Skip to content

Commit b8c9a05

Browse files
committed
Calendar and available3
1 parent eb2ff2d commit b8c9a05

File tree

15 files changed

+417
-24
lines changed

15 files changed

+417
-24
lines changed

package-lock.json

+75
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
"@hookform/resolvers": "^3.1.0",
1313
"@ignite-ui/react": "^2.2.4",
1414
"@prisma/client": "^4.13.0",
15+
"@tanstack/react-query": "^4.29.5",
1516
"@types/node": "18.16.0",
1617
"@types/react": "18.0.38",
1718
"@types/react-dom": "18.0.11",
1819
"axios": "^1.3.6",
20+
"dayjs": "^1.11.7",
1921
"eslint": "8.39.0",
2022
"eslint-config-next": "13.3.1",
2123
"next": "13.3.1",

prisma/dev.db

8 KB
Binary file not shown.

prisma/dev.db-journal

12.5 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- CreateTable
2+
CREATE TABLE "schedulings" (
3+
"id" TEXT NOT NULL PRIMARY KEY,
4+
"date" DATETIME NOT NULL,
5+
"name" TEXT NOT NULL,
6+
"email" TEXT NOT NULL,
7+
"observations" TEXT,
8+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
9+
"user_id" TEXT NOT NULL,
10+
CONSTRAINT "schedulings_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
11+
);

prisma/schema.prisma

+15
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ model User {
2222
accounts Account[]
2323
sessions Session[]
2424
timeIntervals UserTimeInterval[]
25+
scheduling Scheduling[]
2526
2627
@@map("users")
2728
}
@@ -67,3 +68,17 @@ model UserTimeInterval {
6768
6869
@@map("user_time_intervals")
6970
}
71+
72+
model Scheduling {
73+
id String @id @default(uuid())
74+
date DateTime
75+
name String
76+
email String
77+
observations String?
78+
created_at DateTime @default(now())
79+
80+
user User @relation(fields: [user_id], references: [id])
81+
user_id String
82+
83+
@@map("schedulings")
84+
}

src/component/Calendar/index.tsx

+121-5
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,120 @@ import {
33
CalendarActions,
44
CalendarBody,
55
CalendarContainer,
6+
CalendarDay,
67
CalendarHeader,
78
CalendarTitle,
89
} from './styles'
10+
911
import { getWeekDays } from '@/utils/get-week-days'
12+
import { useMemo, useState } from 'react'
13+
import dayjs from 'dayjs'
14+
15+
interface CalendarWeek {
16+
week: number
17+
days: Array<{
18+
date: dayjs.Dayjs
19+
disabled: boolean
20+
}>
21+
}
22+
23+
type CalendarWeeks = CalendarWeek[]
24+
25+
interface CalendarProps {
26+
selectedDate: Date | null
27+
onDateSelected: (date: Date) => void
28+
}
29+
30+
export function Calendar({ selectedDate, onDateSelected }: CalendarProps) {
31+
const [currentDate, setCurrentDate] = useState(() => {
32+
return dayjs().set('date', 1)
33+
})
34+
35+
function handlePreviousMonth() {
36+
const previousMonthDate = currentDate.subtract(1, 'month')
37+
setCurrentDate(previousMonthDate)
38+
}
39+
40+
function handleNextMonth() {
41+
const nextMonthDate = currentDate.add(1, 'month')
42+
setCurrentDate(nextMonthDate)
43+
}
1044

11-
export function Calendar() {
1245
const shortWeekDays = getWeekDays({ short: true })
1346

47+
const currentMonth = currentDate.format('MMMM')
48+
const currentYeah = currentDate.format('YYYY')
49+
50+
const calendarWeeks = useMemo(() => {
51+
const daysInMonthArray = Array.from({
52+
length: currentDate.daysInMonth(),
53+
}).map((_, i) => {
54+
return currentDate.set('date', i + 1)
55+
})
56+
57+
const firstWeekDay = currentDate.get('day')
58+
59+
const previousMonthFillArray = Array.from({
60+
length: firstWeekDay,
61+
})
62+
.map((_, i) => {
63+
return currentDate.subtract(i + 1, 'day')
64+
})
65+
.reverse()
66+
67+
const lastDayInCurrentMonth = currentDate.set(
68+
'date',
69+
currentDate.daysInMonth(),
70+
)
71+
72+
const lastWeekDay = lastDayInCurrentMonth.get('day')
73+
74+
const nextMonthFillArray = Array.from({
75+
length: 7 - (lastWeekDay + 1),
76+
}).map((_, i) => {
77+
return lastDayInCurrentMonth.add(i + 1, 'day')
78+
})
79+
80+
const calendarDays = [
81+
...previousMonthFillArray.map((date) => {
82+
return { date, disabled: true }
83+
}),
84+
...daysInMonthArray.map((date) => {
85+
return { date, disabled: date.endOf('day').isBefore(new Date()) }
86+
}),
87+
...nextMonthFillArray.map((date) => {
88+
return { date, disabled: true }
89+
}),
90+
]
91+
92+
const calendarWeeks = calendarDays.reduce<CalendarWeeks>(
93+
(weeks, _, i, original) => {
94+
const isNewWeek = i % 7 === 0
95+
if (isNewWeek) {
96+
weeks.push({
97+
week: i / 7 + 1,
98+
days: original.slice(i, i + 7),
99+
})
100+
}
101+
return weeks
102+
},
103+
[],
104+
)
105+
106+
return calendarWeeks
107+
}, [currentDate])
108+
14109
return (
15110
<CalendarContainer>
16111
<CalendarHeader>
17-
<CalendarTitle>Maio 2023</CalendarTitle>
112+
<CalendarTitle>
113+
{currentMonth} <span>{currentYeah}</span>
114+
</CalendarTitle>
18115
<CalendarActions>
19-
<button>
116+
<button onClick={handlePreviousMonth} title="Previous month">
20117
<CaretLeft />
21118
</button>
22-
<button>
119+
<button onClick={handleNextMonth} title="Next month">
23120
<CaretRight />
24121
</button>
25122
</CalendarActions>
@@ -32,7 +129,26 @@ export function Calendar() {
32129
))}
33130
</tr>
34131
</thead>
35-
<tbody></tbody>
132+
<tbody>
133+
{calendarWeeks.map(({ week, days }) => {
134+
return (
135+
<tr key={week}>
136+
{days.map(({ date, disabled }) => {
137+
return (
138+
<td key={date.toString()}>
139+
<CalendarDay
140+
onClick={() => onDateSelected(date.toDate())}
141+
disabled={disabled}
142+
>
143+
{date.get('date')}
144+
</CalendarDay>
145+
</td>
146+
)
147+
})}
148+
</tr>
149+
)
150+
})}
151+
</tbody>
36152
</CalendarBody>
37153
</CalendarContainer>
38154
)

src/component/Calendar/styles.ts

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export const CalendarHeader = styled('div', {
1515

1616
export const CalendarTitle = styled(Text, {
1717
fontWeight: '$medium',
18+
textTransform: 'capitalize',
19+
1820
span: {
1921
color: '$gray200',
2022
},

src/lib/dayjs.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import dayjs from 'dayjs'
2+
3+
import 'dayjs/locale/pt-br'
4+
5+
dayjs.locale('pt-br')

src/lib/react-query.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { QueryClient } from '@tanstack/react-query'
2+
3+
export const queryClient = new QueryClient()

src/pages/_app.page.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
import { queryClient } from '@/lib/react-query'
2+
import '../lib/dayjs'
3+
14
import { globalStyles } from '@/styles/global'
5+
import { QueryClientProvider } from '@tanstack/react-query'
26
import { SessionProvider } from 'next-auth/react'
37
import type { AppProps } from 'next/app'
48

@@ -9,8 +13,10 @@ export default function App({
913
pageProps: { session, ...pageProps },
1014
}: AppProps) {
1115
return (
12-
<SessionProvider session={session}>
13-
<Component {...pageProps} />
14-
</SessionProvider>
16+
<QueryClientProvider client={queryClient}>
17+
<SessionProvider session={session}>
18+
<Component {...pageProps} />
19+
</SessionProvider>
20+
</QueryClientProvider>
1521
)
1622
}

0 commit comments

Comments
 (0)