Skip to content

Commit efb737f

Browse files
committed
Calendar and avilable4
1 parent b8c9a05 commit efb737f

File tree

13 files changed

+198
-84
lines changed

13 files changed

+198
-84
lines changed

prisma/dev.db

-68 KB
Binary file not shown.

prisma/dev.db-journal

-12.5 KB
Binary file not shown.

prisma/migrations/20230425095659_create_users/migration.sql

-10
This file was deleted.

prisma/migrations/20230425175120_create_auth_tables/migration.sql

-44
This file was deleted.

prisma/migrations/20230427114408_create_user_time_intervals/migration.sql

-9
This file was deleted.

prisma/migrations/20230427175510_add_bio_to_users/migration.sql

-2
This file was deleted.

prisma/migrations/20230502191625_create_schedulings/migration.sql

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
-- CreateTable
2+
CREATE TABLE `users` (
3+
`id` VARCHAR(191) NOT NULL,
4+
`username` VARCHAR(191) NOT NULL,
5+
`name` VARCHAR(191) NOT NULL,
6+
`bio` VARCHAR(191) NULL,
7+
`email` VARCHAR(191) NULL,
8+
`avatar_url` VARCHAR(191) NULL,
9+
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
10+
11+
UNIQUE INDEX `users_username_key`(`username`),
12+
UNIQUE INDEX `users_email_key`(`email`),
13+
PRIMARY KEY (`id`)
14+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
15+
16+
-- CreateTable
17+
CREATE TABLE `accounts` (
18+
`id` VARCHAR(191) NOT NULL,
19+
`user_id` VARCHAR(191) NOT NULL,
20+
`type` VARCHAR(191) NOT NULL,
21+
`provider` VARCHAR(191) NOT NULL,
22+
`provider_account_id` VARCHAR(191) NOT NULL,
23+
`refresh_token` VARCHAR(191) NULL,
24+
`access_token` VARCHAR(191) NULL,
25+
`expires_at` INTEGER NULL,
26+
`token_type` VARCHAR(191) NULL,
27+
`scope` VARCHAR(191) NULL,
28+
`id_token` VARCHAR(191) NULL,
29+
`session_state` VARCHAR(191) NULL,
30+
31+
UNIQUE INDEX `accounts_provider_provider_account_id_key`(`provider`, `provider_account_id`),
32+
PRIMARY KEY (`id`)
33+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
34+
35+
-- CreateTable
36+
CREATE TABLE `sessions` (
37+
`id` VARCHAR(191) NOT NULL,
38+
`session_token` VARCHAR(191) NOT NULL,
39+
`user_id` VARCHAR(191) NOT NULL,
40+
`expires` DATETIME(3) NOT NULL,
41+
42+
UNIQUE INDEX `sessions_session_token_key`(`session_token`),
43+
PRIMARY KEY (`id`)
44+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
45+
46+
-- CreateTable
47+
CREATE TABLE `user_time_intervals` (
48+
`id` VARCHAR(191) NOT NULL,
49+
`week_day` INTEGER NOT NULL,
50+
`time_start_in_minutes` INTEGER NOT NULL,
51+
`time_end_in_minutes` INTEGER NOT NULL,
52+
`user_id` VARCHAR(191) NOT NULL,
53+
54+
PRIMARY KEY (`id`)
55+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
56+
57+
-- CreateTable
58+
CREATE TABLE `schedulings` (
59+
`id` VARCHAR(191) NOT NULL,
60+
`date` DATETIME(3) NOT NULL,
61+
`name` VARCHAR(191) NOT NULL,
62+
`email` VARCHAR(191) NOT NULL,
63+
`observations` VARCHAR(191) NULL,
64+
`created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
65+
`user_id` VARCHAR(191) NOT NULL,
66+
67+
PRIMARY KEY (`id`)
68+
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
69+
70+
-- AddForeignKey
71+
ALTER TABLE `accounts` ADD CONSTRAINT `accounts_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
72+
73+
-- AddForeignKey
74+
ALTER TABLE `sessions` ADD CONSTRAINT `sessions_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
75+
76+
-- AddForeignKey
77+
ALTER TABLE `user_time_intervals` ADD CONSTRAINT `user_time_intervals_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
78+
79+
-- AddForeignKey
80+
ALTER TABLE `schedulings` ADD CONSTRAINT `schedulings_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- AlterTable
2+
ALTER TABLE `accounts` MODIFY `refresh_token` TEXT NULL,
3+
MODIFY `access_token` TEXT NULL,
4+
MODIFY `id_token` TEXT NULL;
5+
6+
-- AlterTable
7+
ALTER TABLE `users` MODIFY `bio` TEXT NULL;

prisma/migrations/migration_lock.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Please do not edit this file manually
22
# It should be added in your version-control system (i.e. Git)
3-
provider = "sqlite"
3+
provider = "mysql"

prisma/schema.prisma

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ generator client {
66
}
77

88
datasource db {
9-
provider = "sqlite"
9+
provider = "mysql"
1010
url = env("DATABASE_URL")
1111
}
1212

1313
model User {
1414
id String @id @default(uuid())
1515
username String @unique
1616
name String
17-
bio String?
17+
bio String? @db.Text
1818
email String? @unique
1919
avatar_url String?
2020
created_at DateTime @default(now())
@@ -33,12 +33,12 @@ model Account {
3333
type String
3434
provider String
3535
provider_account_id String
36-
refresh_token String?
37-
access_token String?
36+
refresh_token String? @db.Text
37+
access_token String? @db.Text
3838
expires_at Int?
3939
token_type String?
4040
scope String?
41-
id_token String?
41+
id_token String? @db.Text
4242
session_state String?
4343
4444
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)

src/component/Calendar/index.tsx

+37-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {
1111
import { getWeekDays } from '@/utils/get-week-days'
1212
import { useMemo, useState } from 'react'
1313
import dayjs from 'dayjs'
14+
import { useQuery } from '@tanstack/react-query'
15+
import { useRouter } from 'next/router'
16+
import { api } from '@/lib/axios'
1417

1518
interface CalendarWeek {
1619
week: number
@@ -22,6 +25,11 @@ interface CalendarWeek {
2225

2326
type CalendarWeeks = CalendarWeek[]
2427

28+
interface BlockedDates {
29+
blockedWeekDays: number[]
30+
blockedDates: number[]
31+
}
32+
2533
interface CalendarProps {
2634
selectedDate: Date | null
2735
onDateSelected: (date: Date) => void
@@ -32,6 +40,8 @@ export function Calendar({ selectedDate, onDateSelected }: CalendarProps) {
3240
return dayjs().set('date', 1)
3341
})
3442

43+
const router = useRouter()
44+
3545
function handlePreviousMonth() {
3646
const previousMonthDate = currentDate.subtract(1, 'month')
3747
setCurrentDate(previousMonthDate)
@@ -47,7 +57,26 @@ export function Calendar({ selectedDate, onDateSelected }: CalendarProps) {
4757
const currentMonth = currentDate.format('MMMM')
4858
const currentYeah = currentDate.format('YYYY')
4959

60+
const username = String(router.query.username)
61+
62+
const { data: blockedDates } = useQuery<BlockedDates>(
63+
['blocked-dates', currentDate.get('year'), currentDate.get('month')],
64+
async () => {
65+
const response = await api.get(`/users/${username}/blocked-dates`, {
66+
params: {
67+
year: currentDate.get('year'),
68+
month: currentDate.get('month') + 1,
69+
},
70+
})
71+
return response.data
72+
},
73+
)
74+
5075
const calendarWeeks = useMemo(() => {
76+
if (!blockedDates) {
77+
return []
78+
}
79+
5180
const daysInMonthArray = Array.from({
5281
length: currentDate.daysInMonth(),
5382
}).map((_, i) => {
@@ -82,7 +111,13 @@ export function Calendar({ selectedDate, onDateSelected }: CalendarProps) {
82111
return { date, disabled: true }
83112
}),
84113
...daysInMonthArray.map((date) => {
85-
return { date, disabled: date.endOf('day').isBefore(new Date()) }
114+
return {
115+
date,
116+
disabled:
117+
date.endOf('day').isBefore(new Date()) ||
118+
blockedDates.blockedWeekDays.includes(date.get('day')) ||
119+
blockedDates.blockedDates.includes(date.get('date')),
120+
}
86121
}),
87122
...nextMonthFillArray.map((date) => {
88123
return { date, disabled: true }
@@ -104,7 +139,7 @@ export function Calendar({ selectedDate, onDateSelected }: CalendarProps) {
104139
)
105140

106141
return calendarWeeks
107-
}, [currentDate])
142+
}, [currentDate, blockedDates])
108143

109144
return (
110145
<CalendarContainer>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { prisma } from '@/lib/prisma'
2+
import { NextApiRequest, NextApiResponse } from 'next'
3+
4+
export default async function handle(
5+
req: NextApiRequest,
6+
res: NextApiResponse,
7+
) {
8+
if (req.method !== 'GET') {
9+
return res.status(405).end()
10+
}
11+
12+
const username = String(req.query.username)
13+
const { year, month } = req.query
14+
15+
if (!year || !month) {
16+
return res.status(400).json({ message: 'Year or month not specified.' })
17+
}
18+
19+
const user = await prisma.user.findUnique({
20+
where: {
21+
username,
22+
},
23+
})
24+
25+
if (!user) {
26+
return res.status(400).json({ message: 'User does not exist.' })
27+
}
28+
29+
const availableWeekDays = await prisma.userTimeInterval.findMany({
30+
select: {
31+
week_day: true,
32+
},
33+
where: {
34+
user_id: user.id,
35+
},
36+
})
37+
38+
const blockedWeekDays = [0, 1, 2, 3, 4, 5, 6].filter((weekDay) => {
39+
return !availableWeekDays.some(
40+
(availableWeekDay) => availableWeekDay.week_day === weekDay,
41+
)
42+
})
43+
44+
// QUERY PARA VARIOS RETORNOS DE UMA SO VEZ:
45+
46+
const blockedDatesRaw: Array<{ date: number }> = await prisma.$queryRaw`
47+
SELECT *
48+
EXTRACT(DAY FROM S.date) AS date,
49+
COUNT(S.date) AS amount,
50+
((UTI.time_start_in_minutes - UTI.time_end_in_minutes) / 60) AS size
51+
FROM schedulings S
52+
53+
LEFT JOIN user_time_intervals UTI
54+
ON UTI.week_day = WEEKDAY(DATE_ADD(S.date, INTERVAL 1 DAY))
55+
56+
WHERE S.user_id = ${user.id}
57+
AND DATE_FORMAT(S.date, "%Y-%m") = ${`${year}'-'${month}`}
58+
59+
GROUP BY EXTRACT(DAY FROM S.date)
60+
((UTI.time_end_in_minutes - UTI.time_start_in_minutes) / 60)
61+
62+
HAVING amount >= size
63+
`
64+
65+
const blockedDates = blockedDatesRaw.map((item) => item.date)
66+
67+
return res.json({ blockedWeekDays, blockedDates })
68+
}

0 commit comments

Comments
 (0)