diff --git a/public/svg/Arrow.svg b/public/svg/Arrow.svg new file mode 100644 index 0000000..c6c1010 --- /dev/null +++ b/public/svg/Arrow.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/svg/Calendar.svg b/public/svg/Calendar.svg new file mode 100644 index 0000000..8a9b860 --- /dev/null +++ b/public/svg/Calendar.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/svg/Clock.svg b/public/svg/Clock.svg new file mode 100644 index 0000000..63857a2 --- /dev/null +++ b/public/svg/Clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/svg/Home.svg b/public/svg/Home.svg new file mode 100644 index 0000000..7c5a9d7 --- /dev/null +++ b/public/svg/Home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/svg/Plus.svg b/public/svg/Plus.svg new file mode 100644 index 0000000..9f98254 --- /dev/null +++ b/public/svg/Plus.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/svg/Users.svg b/public/svg/Users.svg new file mode 100644 index 0000000..ea9c064 --- /dev/null +++ b/public/svg/Users.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/features/app/Router.tsx b/src/features/app/Router.tsx index 3c5fd37..506356a 100644 --- a/src/features/app/Router.tsx +++ b/src/features/app/Router.tsx @@ -12,6 +12,7 @@ import SettingContainer from '../setting/Container'; import ErrorContainer from '../shared/error/Container'; import NotFound from '../shared/error/notfound/NotFound'; import PreviewContainer from '../preview/Container'; +import ScheduleContainer from '../schedule/Container'; import EventContainer from '../event/Container'; const router = createRoutesFromElements( @@ -28,6 +29,7 @@ const router = createRoutesFromElements( } /> } /> } /> + } /> } /> } /> , diff --git a/src/features/schedule/Container.tsx b/src/features/schedule/Container.tsx new file mode 100644 index 0000000..1216181 --- /dev/null +++ b/src/features/schedule/Container.tsx @@ -0,0 +1,35 @@ +import { useLayoutEffect } from 'react'; +import { useAtom } from 'jotai'; + +import { titleAtom } from '../shared/layout/atom'; + +import MeetingItem from './components/MeetingItem'; +import WeekSelector from './components/WeekSelector'; +import './style/index.scss'; +import useSchedule from './hooks/useSchedule'; + +const ScheduleContainer = () => { + const [, setTitle] = useAtom(titleAtom); + const { dummyMeetings, handleWeekChange } = useSchedule(); + + useLayoutEffect(() => { + setTitle({ title: 'Schedule', back: true }); + }, []); + + return ( +
+ + {(dummyMeetings || []).map((x, key) => ( + + ))} + {/*
+ +
*/} +
+ ); +}; + +export default ScheduleContainer; diff --git a/src/features/schedule/components/Badge.tsx b/src/features/schedule/components/Badge.tsx new file mode 100644 index 0000000..39e5cf5 --- /dev/null +++ b/src/features/schedule/components/Badge.tsx @@ -0,0 +1,7 @@ +import { MeetingTypes } from '../type'; + +const Badge = ({ type }: { type: MeetingTypes }) => { + return ; +}; + +export default Badge; diff --git a/src/features/schedule/components/MeetingItem.tsx b/src/features/schedule/components/MeetingItem.tsx new file mode 100644 index 0000000..a651f12 --- /dev/null +++ b/src/features/schedule/components/MeetingItem.tsx @@ -0,0 +1,44 @@ +import { Meeting } from '../type'; + +import calendar from '/svg/Calendar.svg'; +import clock from '/svg/Clock.svg'; +import home from '/svg/Home.svg'; +import users from '/svg/Users.svg'; +import arrow from '/svg/Arrow.svg'; + +import Badge from './Badge'; + +const MeetingItem = ({ type, title, date, time, place, people }: Meeting) => { + return ( +
+

+ + + {title.slice(0, 26)} + {title.length > 26 && '⋯'} + + +

+

+ + {date} +

+

+ + {time} +

+

+ + {place} +

+ {people && ( +

+ + {people} +

+ )} +
+ ); +}; + +export default MeetingItem; diff --git a/src/features/schedule/components/WeekSelector.tsx b/src/features/schedule/components/WeekSelector.tsx new file mode 100644 index 0000000..59b34b7 --- /dev/null +++ b/src/features/schedule/components/WeekSelector.tsx @@ -0,0 +1,17 @@ +import calendar from '/svg/Calendar.svg'; +import arrow from '/svg/Arrow.svg'; + +const WeekSelector = ({ onClick }: { onClick: () => void }) => { + return ( +
+ +

+ + 00.00  ~  00.00 +

+ +
+ ); +}; + +export default WeekSelector; diff --git a/src/features/schedule/constants.ts b/src/features/schedule/constants.ts new file mode 100644 index 0000000..c6850ce --- /dev/null +++ b/src/features/schedule/constants.ts @@ -0,0 +1,82 @@ +import { Meeting, MeetingTypes } from './type'; + +export const dummy: Array = [ + { + type: MeetingTypes.Team, + title: 'Team Meeting Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Business, + title: 'Business Trip/Outside Work Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Personal, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + }, + { + type: MeetingTypes.Team, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Business, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: 'Hall A', + people: 'Andreas', + }, + { + type: MeetingTypes.Business, + title: 'Business Trip/Outside Work Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Personal, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Team, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Personal, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + people: 'Andreas and 14 others', + }, + { + type: MeetingTypes.Personal, + title: 'Personal Schedule Title', + date: 'Wed, Aug 16th 2023', + time: '14:00 ~ 17:00', + place: '7F Conference Room A', + }, +]; diff --git a/src/features/schedule/hooks/useSchedule.tsx b/src/features/schedule/hooks/useSchedule.tsx new file mode 100644 index 0000000..368aa79 --- /dev/null +++ b/src/features/schedule/hooks/useSchedule.tsx @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +import { dummy } from '../constants'; +import { Meeting } from '../type'; + +const useSchedule = () => { + const [dummyMeetings, setDummyMeetings] = useState>([ + ...dummy, + ]); + const handleWeekChange = () => { + setDummyMeetings([ + dummy[Math.floor(Math.random() * 10)], + dummy[Math.floor(Math.random() * 10)], + dummy[Math.floor(Math.random() * 10)], + dummy[Math.floor(Math.random() * 10)], + ]); + }; + return { dummyMeetings, handleWeekChange }; +}; + +export default useSchedule; diff --git a/src/features/schedule/style/index.scss b/src/features/schedule/style/index.scss new file mode 100644 index 0000000..6873342 --- /dev/null +++ b/src/features/schedule/style/index.scss @@ -0,0 +1,116 @@ +@import '../../shared/style/color'; +@import '../../shared/style/variable'; + +.schedule-container { + width: 100%; + display: grid; + gap: 12px; + background-color: $background; + position: relative; + + h1 { + color: #191919; + font-size: 16px; + font-weight: 500; + display: flex; + align-items: center; + } + + h1 img { + width: 20px; + margin-right: 8px; + } + + h2 { + color: #191919; + font-size: 16px; + font-weight: 700; + padding: 4px 0 6px; + display: flex; + align-items: center; + justify-content: space-between; + } + + h2 img { + width: 16px; + } + + .arrow { + padding: 0 24px; + } + + .arrow-left { + transform: rotate(180deg); + } + + p { + color: #000; + font-size: 14px; + font-weight: 400; + display: flex; + align-items: center; + } + + p img { + margin-right: 8px; + width: 16px; + } + + .meeting-item { + background-color: #ffffff; + padding: 8px 16px; + } + + .badge { + width: 12px; + height: 12px; + border-radius: 6px; + display: inline-block; + margin-right: 8px; + } + + .badge-team { + background-color: #ff0000; + } + + .badge-business { + background-color: #24b277; + } + + .badge-personal { + background-color: #0038ff; + } + + .week-selector { + background-color: #ffffff; + display: flex; + justify-content: center; + align-items: center; + padding: 6px 0; + } + + .button-area { + border-top: 1px solid #e9e9f1; + padding: 16px; + background-color: #ffffff; + position: fixed; + bottom: 0; + width: calc($min-width - 32px); + } + + button { + background-color: $button-background-color; + border: 1px solid $button-background-color; + color: $button-text-color; + font-weight: 500; + font-size: 16px; + padding: 6px 14px; + width: 100%; + height: 48px; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + } +} diff --git a/src/features/schedule/type.ts b/src/features/schedule/type.ts new file mode 100644 index 0000000..b0500c3 --- /dev/null +++ b/src/features/schedule/type.ts @@ -0,0 +1,14 @@ +export enum MeetingTypes { + Team = 'team', + Business = 'business', + Personal = 'personal', +} + +export type Meeting = { + type: MeetingTypes; + title: string; + date: string; + time: string; + place: string; + people?: string; +}; diff --git a/src/features/shared/style/_color.scss b/src/features/shared/style/_color.scss index 868e0c2..3d5ec0d 100644 --- a/src/features/shared/style/_color.scss +++ b/src/features/shared/style/_color.scss @@ -5,4 +5,6 @@ $container-color: #ffffff; $button-background-color: #191919; $button-text-color: #ffffff; -$description-sub: #7878B8; +$description-sub: #7878b8; + +$background: #f7f7f7;