Commit 89d68af0 authored by Wellton Quirino's avatar Wellton Quirino

Holiday Adjustments

parent 1a435420
import { api } from '@/lib/axios'
export type AudiencesNameProps = {
name: string
}
export type AudiencesProps = {
id: string
id?: string
name: string
}
export async function createAudiences({
name,
}: AudiencesNameProps) {
const audiences = await api.post<AudiencesNameProps>('/audiences', {
export async function createAudiences({ name }: AudiencesProps) {
const audiences = await api.post<AudiencesProps>('/audiences', {
name,
})
return audiences
......@@ -27,12 +22,14 @@ export async function getAudienceId(id: string) {
return audiences
}
export async function editAudienceId(id: string) {
const audiences = await api.put<AudiencesProps>(`/audiences/${id}`)
export async function editAudienceId(data: AudiencesProps) {
const audiences = await api.put<AudiencesProps>(`/audiences/${data.id}`, {
name: data.name,
})
return audiences
}
export async function deleteAudience(id: string) {
const audiences = await api.delete(`/audiences/${id}`)
return audiences
}
\ No newline at end of file
}
import { api } from '@/lib/axios'
export type CategoriesProps = {
id: string
id?: string
name: string
}
export async function createCategories({ name }: CategoriesProps) {
const categories = await api.post<CategoriesProps>('/categories', {
name,
})
return categories
}
export async function getCategories() {
const categories = await api.get<CategoriesProps[]>('/categories')
return categories
}
export async function getCategoryId(id: string) {
const categories = await api.get<CategoriesProps>(`/categories/${id}`)
return categories
}
export async function editCategoryId(data: CategoriesProps) {
const categories = await api.put<CategoriesProps>(`/categories/${data.id}`, {
name: data.name,
})
return categories
}
export async function deleteCategory(id: string) {
const categories = await api.delete(`/categories/${id}`)
return categories
}
'use client'
import {
AudiencesProps,
deleteAudience,
editAudienceId,
getAudienceId,
} from '@/api/audiences'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import ModalDialog from '@/components/modal-dialog'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { AlertDialog, AlertDialogTrigger } from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { TextField } from '@mui/material'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Trash } from 'lucide-react'
import { useParams, useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
export default function AudienceId() {
const params = useParams<{ id: string }>()
const {
register,
handleSubmit,
formState: { errors },
} = useForm<AudiencesProps>()
const router = useRouter()
const queryClient = useQueryClient()
const { data: audience, isLoading } = useQuery({
queryKey: ['audiences', params.id],
queryFn: () => getAudienceId(params.id),
enabled: !!params.id,
})
const mutationEditAudience = useMutation({
mutationFn: editAudienceId,
onSuccess: () => {
toast.success('Audiência auterada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
router.push('/admin')
},
})
const mutationDeleteAudience = useMutation({
mutationFn: deleteAudience,
onSuccess: () => {
toast.success('Audiência criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
router.push('/admin')
},
})
function handleDeleteAudience() {
mutationDeleteAudience.mutate(params.id)
}
async function onSubmit(data: AudiencesProps) {
console.log('🚀 ~ onSubmit ~ data:', data)
const body = {
id: params.id,
name: data.name,
}
mutationEditAudience.mutateAsync(body)
}
if (isLoading) {
return (
<div className="flex w-full h-[500px] items-center justify-center">
<LoadingSpinIcon />
<span>Loading...</span>
</div>
)
}
return (
<section className="container py-10">
<BreadcrumbComponent page="Audiência" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Editar Audiência</h1>
<Button
variant="secondary"
type="submit"
className="uppercase rounded-sm"
disabled={isLoading}
>
{mutationEditAudience.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
<AlertDialog>
<>
<AlertDialogTrigger
className="uppercase flex items-center gap-2 text-orange-100 border-none hover:bg-orange-100/10 hover:text-orange-100 h-10 px-5 rounded-sm"
type="button"
>
<span>Apagar audiência</span>
<Trash />
</AlertDialogTrigger>
<ModalDialog
title="Tem certeza que deseja deletar a audiência?"
description={`Ao clicar em continue você irá deletar a audiência ${audience?.data.name}`}
handleClick={handleDeleteAudience}
/>
</>
</AlertDialog>
</div>
<div className="w-full mt-16">
<TextField
label="Nome da audiência"
type="text"
defaultValue={audience?.data.name}
{...register('name')}
variant="standard"
className="flex"
sx={StyledInputs(
errors.name ? { color: '#dc2626' } : { color: '#26AAA7' },
)}
/>
</div>
</form>
</section>
)
}
'use client'
import { AudiencesProps, createAudiences } from '@/api/audiences'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { Button } from '@/components/ui/button'
import { zodResolver } from '@hookform/resolvers/zod'
import { TextField } from '@mui/material'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { z } from 'zod'
const FormSchema = z.object({
name: z.string().trim().min(3, { message: 'Nome obrigatório' }),
})
export default function Audience() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<AudiencesProps>({
resolver: zodResolver(FormSchema),
})
const router = useRouter()
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: createAudiences,
onSuccess: () => {
toast.success('Audiência criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
router.push('/admin')
},
})
async function onSubmit(data: AudiencesProps) {
mutation.mutateAsync(data)
}
return (
<section className="container py-10">
<BreadcrumbComponent page="Audiência" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Criar Audiência</h1>
<Button variant="secondary" className="uppercase rounded-sm">
{mutation.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
</div>
<div className="w-full mt-16">
<TextField
label="Nome da audiência"
variant="standard"
type="text"
className="flex"
{...register('name')}
sx={StyledInputs(
errors.name ? { color: '#dc2626' } : { color: '#26AAA7' },
)}
/>
</div>
</form>
</section>
)
}
'use client'
import {
CategoriesProps,
deleteCategory,
editCategoryId,
getCategoryId,
} from '@/api/categories'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import ModalDialog from '@/components/modal-dialog'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { AlertDialog, AlertDialogTrigger } from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { TextField } from '@mui/material'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Trash } from 'lucide-react'
import { useParams, useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
export default function AudienceId() {
const params = useParams<{ id: string }>()
const {
register,
handleSubmit,
formState: { errors },
} = useForm<CategoriesProps>()
const router = useRouter()
const queryClient = useQueryClient()
const { data: categorie, isLoading } = useQuery({
queryKey: ['categories', params.id],
queryFn: () => getCategoryId(params.id),
enabled: !!params.id,
})
const mutationEditAudience = useMutation({
mutationFn: editCategoryId,
onSuccess: () => {
toast.success('Categoria auterada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['categories'] })
router.push('/admin')
},
})
const mutationDeleteAudience = useMutation({
mutationFn: deleteCategory,
onSuccess: () => {
toast.success('Categoria criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['categories'] })
router.push('/admin')
},
})
function handleDeleteAudience() {
mutationDeleteAudience.mutate(params.id)
}
async function onSubmit(data: CategoriesProps) {
const body = {
id: params.id,
name: data.name,
}
mutationEditAudience.mutateAsync(body)
}
if (isLoading) {
return (
<div className="flex w-full h-[500px] items-center justify-center">
<LoadingSpinIcon />
<span>Loading...</span>
</div>
)
}
return (
<section className="container py-10">
<BreadcrumbComponent page="Categoria" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Editar Categoria</h1>
<Button
variant="secondary"
type="submit"
className="uppercase rounded-sm"
disabled={isLoading}
>
{mutationEditAudience.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
<AlertDialog>
<>
<AlertDialogTrigger
className="uppercase flex items-center gap-2 text-orange-100 border-none hover:bg-orange-100/10 hover:text-orange-100 h-10 px-5 rounded-sm"
type="button"
>
<span>Apagar categoria</span>
<Trash />
</AlertDialogTrigger>
<ModalDialog
title="Tem certeza que deseja deletar a categoria?"
description={`Ao clicar em continue você irá deletar a categoria ${categorie?.data.name}`}
handleClick={handleDeleteAudience}
/>
</>
</AlertDialog>
</div>
<div className="w-full mt-16">
<TextField
label="Nome da categoria"
type="text"
defaultValue={categorie?.data.name}
{...register('name')}
variant="standard"
className="flex"
sx={StyledInputs(
errors.name ? { color: '#dc2626' } : { color: '#26AAA7' },
)}
/>
</div>
</form>
</section>
)
}
'use client'
import { CategoriesProps, createCategories } from '@/api/categories'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { Button } from '@/components/ui/button'
import { zodResolver } from '@hookform/resolvers/zod'
import { TextField } from '@mui/material'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
import { z } from 'zod'
const FormSchema = z.object({
name: z.string().trim().min(3, { message: 'Nome obrigatório' }),
})
export default function Category() {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<CategoriesProps>({
resolver: zodResolver(FormSchema),
})
const router = useRouter()
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: createCategories,
onSuccess: () => {
toast.success('Categoria criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['categories'] })
router.push('/admin')
},
})
async function onSubmit(data: CategoriesProps) {
mutation.mutateAsync(data)
}
return (
<section className="container py-10">
<BreadcrumbComponent page="Categoria" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Criar Categoria</h1>
<Button variant="secondary" className="uppercase rounded-sm">
{mutation.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
</div>
<div className="w-full mt-16">
<TextField
label="Nome da categoria"
variant="standard"
type="text"
className="flex"
{...register('name')}
sx={StyledInputs(
errors.name ? { color: '#dc2626' } : { color: '#26AAA7' },
)}
/>
</div>
</form>
</section>
)
}
'use client'
import { getAreas } from '@/api/areas'
import { createAudiences, deleteAudience, editAudienceId, getAudiences } from '@/api/audiences'
import { getAudiences } from '@/api/audiences'
import { getCategories } from '@/api/categories'
import { getCourses } from '@/api/courses'
import { Card } from '@/components/card'
import ModalInputs from '@/components/modal-inputs'
import { InputMui } from '@/components/mui/inputs'
import { AlertDialog, AlertDialogTrigger } from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import { AuthContext } from '@/contexts/auth-context'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useQuery } from '@tanstack/react-query'
import { Pencil, Search } from 'lucide-react'
import Link from 'next/link'
import { useContext, useState } from 'react'
import { useContext } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
export default function Admin() {
const [open, setOpen] = useState<boolean>(false);
const [nameAudience, setNameAudience] = useState('')
const { register } = useForm()
const { user } = useContext(AuthContext)
const queryClient = useQueryClient()
const {
data: areas,
......@@ -30,6 +26,11 @@ export default function Admin() {
isError,
} = useQuery({ queryKey: ['areas'], queryFn: getAreas })
const { data: categories } = useQuery({
queryKey: ['categories'],
queryFn: getCategories,
})
const { data: audiences } = useQuery({
queryKey: ['audiences'],
queryFn: getAudiences,
......@@ -40,48 +41,6 @@ export default function Admin() {
queryFn: getCourses,
})
const mutationCreateAudience = useMutation({
mutationFn: createAudiences,
onSuccess: () => {
toast.success('Audiência criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
},
})
const mutationEditAudience = useMutation({
mutationFn: editAudienceId,
onSuccess: () => {
toast.success('Audiência criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
},
})
const mutationDeleteAudience = useMutation({
mutationFn: deleteAudience,
onSuccess: () => {
toast.success('Audiência criada com sucesso!')
queryClient.invalidateQueries({ queryKey: ['audiences'] })
},
})
function handleCreateAudience() {
const body = {
name: nameAudience
}
mutationCreateAudience.mutate(body)
setOpen(false)
}
function handleEditAudience(id: string) {
mutationEditAudience.mutate(id)
setOpen(false)
}
function handleDeleteAudience(id: string) {
mutationDeleteAudience.mutate(id)
setOpen(false)
}
if (isLoading) {
return <span>Loading...</span>
}
......@@ -118,74 +77,48 @@ export default function Admin() {
</nav>
<h2 className="text-purple-50 text-2xl mt-10">Audiência</h2>
<AlertDialog open={open} onOpenChange={setOpen}>
<>
<AlertDialogTrigger
className="flex justify-between w-full"
type="button"
>
<Button className="uppercase mt-6">
+ Adicionar novo
</Button>
</AlertDialogTrigger>
<ModalInputs
title="Criar"
description="Criar nova audiência"
handleClick={handleCreateAudience}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setNameAudience(e.target.value)
}
/>
</>
</AlertDialog>
<AlertDialog open={open} onOpenChange={setOpen}>
<nav className="my-6 w-full">
<ul className="space-y-4">
{audiences?.data.map((audience) => (
<li
key={audience.id}
className="border-b border-green-400 py-2 hover:bg-green-400/10"
>
<AlertDialogTrigger
className="flex justify-between w-full"
type="button"
>
{audience.name}
<Pencil className="text-green-400" />
</AlertDialogTrigger>
<ModalInputs
title="Editar"
description="Editar nome da audiência"
handleClick={() => handleEditAudience(audience.id)}
value={nameAudience}
handleClickDelete={() => handleDeleteAudience(audience.id)}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setNameAudience(e.target.value)
}
/>
</li>
))}
</ul>
</nav>
</AlertDialog>
{/* <h2 className="text-purple-50 text-2xl mt-10">Banners</h2>
<Button className="uppercase mt-6" asChild>
<Link href="admin/audience">+ Adicionar novo</Link>
</Button>
<nav className="my-6">
<ul className="space-y-4">
{banners.map((banner) => (
<li
key={banner.title}
className="flex justify-between border-b border-green-400 py-2"
>
<Link href="#">{banner.title}</Link>
<Pencil className="text-green-400" />
{audiences?.data.map((audience) => (
<li key={audience.id} className="border-b border-green-400">
<Link
href={`/admin/audience/${audience.id}`}
className="flex justify-between py-2 hover:bg-green-400/10"
>
<span>{audience.name}</span>
<Pencil className="text-green-400" />
</Link>
</li>
))}
</ul>
</nav> */}
</nav>
<h2 className="text-purple-50 text-2xl mt-10">Categoria</h2>
<Button className="uppercase mt-6" asChild>
<Link href="admin/category">+ Adicionar novo</Link>
</Button>
<nav className="my-6">
<ul className="space-y-4">
{categories?.data.map((category) => (
<li key={category.id} className="border-b border-green-400">
<Link
href={`/admin/category/${category.id}`}
className="flex justify-between py-2 hover:bg-green-400/10"
>
<span>{category.name}</span>
<Pencil className="text-green-400" />
</Link>
</li>
))}
</ul>
</nav>
</aside>
<div className="flex-1 ml-4 pl-6 border-l border-gray-50">
......@@ -217,7 +150,7 @@ export default function Admin() {
>
<div className="border border-gray-100 pb-4 rounded-lg overflow-hidden">
<Card.Image
image={course.desktopBanner || ''}
image={course.mobileBanner || ''}
width={240}
height={320}
>
......
......@@ -3,10 +3,10 @@
import { InputMui } from '@/components/mui/inputs'
import { Button } from '@/components/ui/button'
import { AuthContext } from '@/contexts/auth-context'
import { AxiosError } from 'axios'
import Image from 'next/image'
import Link from 'next/link'
// import { useRouter } from 'next/router'
import { AxiosError } from 'axios'
import { useRouter } from 'next/navigation'
import { useContext } from 'react'
import { useForm } from 'react-hook-form'
import { toast } from 'sonner'
......@@ -20,12 +20,12 @@ type FormLogin = {
export default function Login() {
const { handleSubmit, register } = useForm<FormLogin>()
const { signIn } = useContext(AuthContext)
// const router = useRouter()
const router = useRouter()
const onSubmit = async (data: FormLogin) => {
try {
await signIn(data)
// router.push('/admin')
router.push('/admin')
} catch (error) {
if (error instanceof AxiosError) {
const { message } = error.response?.data
......
......@@ -2,7 +2,7 @@
import Link, { LinkProps } from 'next/link'
import { useSearchParams } from 'next/navigation'
import { usePathname, useSearchParams } from 'next/navigation'
import { Button } from './ui/button'
interface NavLinkProps extends LinkProps {
......@@ -23,16 +23,25 @@ interface NavLinkProps extends LinkProps {
export function NavLinkSearchParams(props: NavLinkProps) {
const searchParams = useSearchParams()
const category = searchParams.get('area')
const pathname = usePathname()
const path = pathname
const area = searchParams.get('area')
return (
<Button
data-current={category === props.href}
data-current={area === props.href}
className={`data-[current=true]:font-semibold rounded-2xl ${props.className}`}
variant={category === props.href ? 'third' : props.variant}
variant={area === props.href ? 'third' : props.variant}
asChild
>
<Link href={{ query: { area: props.href as string } }}>
<Link
href={{
pathname: `${path === '/' ? '/estudantes' : path}`,
query: { area: props.href as string },
}}
>
{props.children}
</Link>
</Button>
......
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