Commit 472aa36e authored by Wellton Quirino's avatar Wellton Quirino

add middleware routes control, add adjustment in modules course

parent d389de98
...@@ -30,42 +30,45 @@ import { zodResolver } from '@hookform/resolvers/zod' ...@@ -30,42 +30,45 @@ import { zodResolver } from '@hookform/resolvers/zod'
import { Box, Chip, MenuItem, TextField } from '@mui/material' import { Box, Chip, MenuItem, TextField } from '@mui/material'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { format } from 'date-fns' import { format } from 'date-fns'
import { CalendarIcon, PlusIcon, Trash2 } from 'lucide-react' import { CalendarIcon, Trash2 } from 'lucide-react'
import { useState } from 'react' import { useState } from 'react'
import { Controller, useForm } from 'react-hook-form' import { Controller, useForm } from 'react-hook-form'
import { toast } from 'sonner' import { toast } from 'sonner'
import { z } from 'zod' import { z } from 'zod'
// type CoursesProps = { // const MAX_FILE_SIZE = 5000000
// name: string // const ACCEPTED_IMAGE_TYPES = [
// description: string // 'image/jpeg',
// desktopBanner: string // 'image/jpg',
// mobileBanner: string // 'image/png',
// duration: number // 'image/webp',
// startDate: Date // ]
// endDate: Date
// professors: string[]
// workload: number
// areaId: string
// audienceId: string
// categoryId: string
// moduleIds: string[]
// }
const FormSchema = z.object({ const FormSchema = z.object({
name: z.string().trim().min(3, { message: 'Título obrigatório' }), name: z.string().trim().min(3, { message: 'Título obrigatório' }),
description: z.string().trim().min(3, { message: 'Descrição obrigatória' }), description: z.string().trim().min(3, { message: 'Descrição obrigatória' }),
desktopBanner: z.string(), desktopBanner: z.any(),
mobileBanner: z.string(), // .refine((file) => file?.size <= MAX_FILE_SIZE, `Max image size is 5MB.`)
duration: z.number(), // .refine(
// (file) => ACCEPTED_IMAGE_TYPES.includes(file?.type),
// 'Only .jpg, .jpeg, .png and .webp formats are supported.',
// ),
mobileBanner: z.any(),
// .refine((file) => file?.size <= MAX_FILE_SIZE, `Max image size is 5MB.`)
// .refine(
// (file) => ACCEPTED_IMAGE_TYPES.includes(file?.type),
// 'Only .jpg, .jpeg, .png and .webp formats are supported.',
// ),
startDate: z.date().optional(), startDate: z.date().optional(),
endDate: z.date().optional(), endDate: z.date().optional(),
professors: z.array(z.string()), professors: z.array(z.string()),
workload: z.number(), workload: z.string(),
areaId: z.string(), areaId: z.string().trim().min(1, { message: 'Selecione a área' }),
audienceId: z.string(), audienceId: z.string(),
categoryId: z.string(), categoryId: z.string(),
moduleIds: z.array(z.string()), moduleIds: z.array(
z.string().trim().min(1, { message: 'Selecione um módulo' }),
),
}) })
export default function Curso() { export default function Curso() {
...@@ -78,7 +81,7 @@ export default function Curso() { ...@@ -78,7 +81,7 @@ export default function Curso() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
// const { form.register, watch, handleSubmit, control } = useForm<CoursesProps>() // const { form.register, watch, handleSubmit, control } = useForm<CoursesProps>()
const { register, handleSubmit, reset } = useForm<ModulesProps>() const { register, handleSubmit } = useForm<ModulesProps>()
const form = useForm<z.infer<typeof FormSchema>>({ const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema), resolver: zodResolver(FormSchema),
defaultValues: { defaultValues: {
...@@ -147,8 +150,6 @@ export default function Curso() { ...@@ -147,8 +150,6 @@ export default function Curso() {
const responseModuleId = response.data.id const responseModuleId = response.data.id
form.setValue('moduleIds', [...selectedIds, responseModuleId]) form.setValue('moduleIds', [...selectedIds, responseModuleId])
reset()
} }
const selectedIds = form.watch('moduleIds') || [] const selectedIds = form.watch('moduleIds') || []
...@@ -204,20 +205,25 @@ export default function Curso() { ...@@ -204,20 +205,25 @@ export default function Curso() {
variant="standard" variant="standard"
type="text" type="text"
{...form.register('name')} {...form.register('name')}
sx={StyledInputs({ color: '#26AAA7' })} sx={StyledInputs(
/> form.formState.errors.name
{form.formState.errors.name && ( ? { color: '#dc2626' }
<p>{form.formState.errors.name.message}</p> : { color: '#26AAA7' },
)} )}
/>
<TextField <TextField
type="text" type="text"
variant="standard" variant="standard"
label="Área" label="Área"
select select
sx={StyledInputs({ color: '#26AAA7' })}
defaultValue={''} defaultValue={''}
{...form.register('areaId')} {...form.register('areaId')}
sx={StyledInputs(
form.formState.errors.areaId
? { color: '#dc2626' }
: { color: '#26AAA7' },
)}
> >
<MenuItem value="" className="hidden"> <MenuItem value="" className="hidden">
Selecione a área Selecione a área
...@@ -235,8 +241,12 @@ export default function Curso() { ...@@ -235,8 +241,12 @@ export default function Curso() {
type="text" type="text"
multiline multiline
rows={4} rows={4}
sx={StyledInputs({ color: '#26AAA7' })}
{...form.register('description')} {...form.register('description')}
sx={StyledInputs(
form.formState.errors.description
? { color: '#dc2626' }
: { color: '#26AAA7' },
)}
/> />
<Controller <Controller
...@@ -283,6 +293,7 @@ export default function Curso() { ...@@ -283,6 +293,7 @@ export default function Curso() {
values={valueDesktopBanner} values={valueDesktopBanner}
label="Adicionar banner" label="Adicionar banner"
{...form.register('desktopBanner')} {...form.register('desktopBanner')}
defaultValue={'testedesktopBanner'}
/> />
</div> </div>
<div className="flex flex-col flex-1 mt-6"> <div className="flex flex-col flex-1 mt-6">
...@@ -296,10 +307,25 @@ export default function Curso() { ...@@ -296,10 +307,25 @@ export default function Curso() {
values={valueMobileBanner} values={valueMobileBanner}
label="Adicionar banner" label="Adicionar banner"
{...form.register('mobileBanner')} {...form.register('mobileBanner')}
defaultValue={'testemobileBanner'}
/> />
</div> </div>
</div> </div>
<Separator className="!mt-10 !mb-4" />
<h6 className="text-xl text-purple-100 mb-4">Horas</h6>
<TextField
label="Total de horas do curso"
variant="standard"
type="number"
{...form.register('workload')}
sx={StyledInputs(
form.formState.errors.workload
? { color: '#dc2626' }
: { color: '#26AAA7' },
)}
/>
<Separator className="!mt-10 !mb-4" /> <Separator className="!mt-10 !mb-4" />
<h6 className="text-xl text-purple-100 mb-4">Datas</h6> <h6 className="text-xl text-purple-100 mb-4">Datas</h6>
<div className="flex flex-col space-y-6"> <div className="flex flex-col space-y-6">
...@@ -402,11 +428,15 @@ export default function Curso() { ...@@ -402,11 +428,15 @@ export default function Curso() {
variant="standard" variant="standard"
label="Selecione os módulos do curso" label="Selecione os módulos do curso"
select select
sx={StyledInputs({ color: '#26AAA7' })}
defaultValue={''} defaultValue={''}
value="" value=""
onChange={handleSelect} onChange={handleSelect}
// {...form.register('moduleIds')} // {...form.register('moduleIds')}
sx={StyledInputs(
form.formState.errors.moduleIds
? { color: '#dc2626' }
: { color: '#26AAA7' },
)}
> >
<MenuItem value="" className="hidden"> <MenuItem value="" className="hidden">
Selecione os módulos Selecione os módulos
...@@ -457,7 +487,7 @@ export default function Curso() { ...@@ -457,7 +487,7 @@ export default function Curso() {
className="uppercase w-52 flex items-center gap-2 !mt-8" className="uppercase w-52 flex items-center gap-2 !mt-8"
onClick={handleSubmit(addNewModuler)} onClick={handleSubmit(addNewModuler)}
> >
<PlusIcon size={20} /> <span>Criar novo Módulo</span> <span>Criar novo Módulo</span>
</Button> </Button>
</div> </div>
......
'use client'
import { InputMui } from '@/components/mui/inputs' import { InputMui } from '@/components/mui/inputs'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { MenuItem } from '@mui/material' import { MenuItem } from '@mui/material'
......
'use client'
import { Search } from 'lucide-react' import { Search } from 'lucide-react'
import { useForm } from 'react-hook-form' import { useForm } from 'react-hook-form'
import { InputMui } from './mui/inputs' import { InputMui } from './mui/inputs'
......
...@@ -3,7 +3,6 @@ import axios from 'axios' ...@@ -3,7 +3,6 @@ import axios from 'axios'
import { destroyCookie, parseCookies } from 'nookies' import { destroyCookie, parseCookies } from 'nookies'
const { 'sevenpro-token': token } = parseCookies() const { 'sevenpro-token': token } = parseCookies()
console.log('🚀 ~ token:', token)
export const api = axios.create({ export const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_URL_API, baseURL: process.env.NEXT_PUBLIC_URL_API,
......
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
export async function middleware(request: NextRequest) {
const token = request.cookies.get('sevenpro-token')?.value
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/admin/:path*'],
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment