Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"framer-motion": "^11.15.0",
"next": "15.1.3",
"react": "^19.0.0",
"react-chrono": "^2.9.1",
"react-dom": "^19.0.0",
"react-image-file-resizer": "^0.4.8",
"rehype-raw": "^7.0.0",
Expand Down
169 changes: 169 additions & 0 deletions client/src/app/wiki/groups/[uuid]/page.tsx

Large diffs are not rendered by default.

167 changes: 167 additions & 0 deletions client/src/components/group/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
'use client';

import React from 'react';
import { Chrono } from 'react-chrono';
import { OrganizationEvent } from '@type/Event.type';

interface TimelineProps {
events: OrganizationEvent[];
}

const Timeline = ({ events }: TimelineProps) => {
const timelineItems = events.map(event => ({
title: event.occurredAt,
cardTitle: event.title,
cardSubtitle: event.writer,
cardDetailedText: event.contents,
media: event.imageUrl
? {
source: {
url: event.imageUrl,
},
type: 'IMAGE',
name: event.title,
}
: undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 이미지가 없다면 fallback image를 넣는 것도 고려해보면 좋을 것 같아요

}));

if (events.length === 0) {
return (
<div className="flex h-64 items-center justify-center rounded-lg bg-grayscale-50">
<p className="font-pretendard text-sm text-grayscale-lightText">
등록된 이벤트가 없습니다.
</p>
</div>
);
}

return (
<div className="timeline-container w-full overflow-x-auto overflow-y-hidden">
<Chrono
items={timelineItems}
mode="HORIZONTAL"
cardHeight={200}
scrollable={{ scrollbar: true }}
theme={{
primary: '#25B4B9', // primary-primary
secondary: '#F5F5F5', // grayscale-50
cardBgColor: '#FFFFFF',
titleColor: '#1A1A1A', // grayscale-text
titleColorActive: '#25B4B9',
cardTitleColor: '#1A1A1A',
cardSubtitleColor: '#888888', // grayscale-500
cardDetailsColor: '#555555', // grayscale-600
}}
fontSizes={{
title: '0.875rem',
cardTitle: '1rem',
cardSubtitle: '0.75rem',
cardText: '0.875rem',
}}
classNames={{
card: 'shadow-md border border-grayscale-200 rounded-lg',
cardTitle: 'font-pretendard font-semibold',
cardSubTitle: 'font-pretendard text-grayscale-500',
cardText: 'font-pretendard',
}}
hideControls
disableClickOnCircle
useReadMore={false}
lineWidth={3}
cardWidth={280}
textDensity="HIGH"
disableToolbar={true}
enableLayoutSwitch={true}
/>

<style jsx global>{`
.timeline-container {
padding: 1rem;
min-height: 400px;
max-width: 100%;
overflow-y: hidden;
}

.timeline-container .timeline-main-wrapper {
padding-bottom: 2rem;
max-width: 100%;
overflow-y: hidden;
}

.timeline-container .timeline-horizontal-container {
padding: 1rem 0;
max-width: 100%;
overflow-y: hidden;
}

/* 카드 3개씩 보이도록 너비 조정 */
.timeline-container .rct-chrono-timeline-container {
max-width: 100% !important;
Comment on lines +77 to +99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분 css 파일을 만들어 import해도 좋을 것 같아요!

}

.timeline-container .rct-chrono-timeline-wrapper {
max-width: 900px !important;
}

.timeline-container .timeline-card-content {
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
border: 1px solid #e5e5e5;
border-radius: 0.5rem;
padding: 1rem;
background: white;
}

.timeline-container .timeline-item-title {
color: #888888;
font-family: 'Pretendard', sans-serif;
font-size: 0.75rem;
margin-bottom: 0.5rem;
}

.timeline-container .timeline-circle {
background: #25b4b9;
border: 3px solid #ffffff;
box-shadow: 0 0 0 2px #25b4b9;
}

.timeline-container .timeline-circle.active {
background: #25b4b9;
transform: scale(1.2);
}

.timeline-container h3 {
font-family: 'Pretendard', sans-serif;
font-weight: 600;
color: #1a1a1a;
margin-bottom: 0.5rem;
}

.timeline-container h4 {
font-family: 'Pretendard', sans-serif;
font-size: 0.75rem;
color: #888888;
margin-bottom: 0.5rem;
}

.timeline-container p {
font-family: 'Pretendard', sans-serif;
color: #555555;
line-height: 1.5;
font-size: 0.875rem;
}

.timeline-container img {
width: 100%;
height: auto;
border-radius: 0.5rem;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
object-fit: cover;
max-height: 200px;
}
`}</style>
</div>
);
};

export default Timeline;
31 changes: 31 additions & 0 deletions client/src/type/Event.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export interface OrganizationEvent {
id: number;
uuid: string;
title: string;
contents: string;
writer: string;
occurredAt: string;
organizationDocumentId: number;
imageUrl?: string;
}

export interface EventFormData {
title: string;
contents: string;
writer: string;
occurredAt: string;
organizationDocumentUuid: string;
}

// 조직 이벤트 생성 응답 타입
export interface OrganizationEventCreateResponse {
organizationEventUuid: string;
}

// 조직 이벤트 수정 요청 타입
export interface OrganizationEventUpdateRequest {
title: string;
contents: string;
writer: string;
occurredAt: string;
}
35 changes: 35 additions & 0 deletions client/src/type/Group.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export interface GroupDocument {
id: string;
title: string;
contents: string;
writer: string;
uuid: string;
documentUUID: string;
documentBytes: number;
}

export interface GroupDocumentResponse {
organizationDocumentId: number;
organizationDocumentUuid: string;
title: string;
contents: string;
writer: string;
generateTime: string;
}

// 문서-그룹문서 연결 관계 타입
export interface DocumentGroupDocumentLink {
id: number;
documentId: number;
organizationDocumentId: number;
}

export interface GroupEvent {
id: string;
date: string;
title: string;
description?: string;
imageUrl?: string;
occurredAt: string;
}

69 changes: 69 additions & 0 deletions client/src/type/react-chrono.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
declare module '@type/react-chrono' {
import { ReactNode } from 'react';

export interface TimelineItem {
title?: string;
cardTitle?: string;
cardSubtitle?: string;
cardDetailedText?: string | string[];
media?: {
name?: string;
source: {
url: string;
};
type?: string;
};
url?: string;
}

export interface Theme {
primary?: string;
secondary?: string;
cardBgColor?: string;
cardForeColor?: string;
titleColor?: string;
titleColorActive?: string;
cardTitleColor?: string;
cardSubtitleColor?: string;
cardDetailsColor?: string;
}

export interface FontSizes {
title?: string;
cardTitle?: string;
cardSubtitle?: string;
cardText?: string;
}

export interface ClassNames {
card?: string;
cardTitle?: string;
cardSubTitle?: string;
cardText?: string;
}

export interface ChronoProps {
items?: TimelineItem[];
mode?: 'VERTICAL' | 'VERTICAL_ALTERNATING' | 'HORIZONTAL';
cardHeight?: number;
cardWidth?: number;
scrollable?: boolean | { scrollbar: boolean };
theme?: Theme;
fontSizes?: FontSizes;
classNames?: ClassNames;
hideControls?: boolean;
disableClickOnCircle?: boolean;
disableNavOnKey?: boolean;
useReadMore?: boolean;
lineWidth?: number;
activeItemIndex?: number;
onScrollEnd?: () => void;
onItemSelected?: (data: any) => void;
textDensity?: 'LOW' |'HIGH';
enableLayoutSwitch?: boolean;
disableToolbar: boolean;
children?: ReactNode;
}

export const Chrono: React.FC<ChronoProps>;
}
Loading