gohorsejobs/frontend/src/contexts/notification-context.tsx
NANDO9322 ddc2f5dd03 feat: atualiza fluxo de cadastro de candidatos com persistência completa de dados e máscara de telefone
Frontend:
- Implementar máscara de entrada de telefone para números BR ((XX) XXXXX-XXXX).
- Atualizar formulário de cadastro para enviar dados completos do perfil do candidato (endereço, formação, habilidades, etc.).
- Corrigir problemas de idioma misto na página de Detalhes da Vaga e adicionar traduções faltantes.

Backend:
- Atualizar modelo de Usuário, Entidade e DTOs para incluir campos de perfil (Data de Nascimento, Endereço, Formação, etc.).
- Atualizar UserRepository para persistir e recuperar os dados estendidos do usuário no PostgreSQL.
- Atualizar RegisterCandidateUseCase para mapear campos de entrada para a entidade Usuário.
2026-01-06 18:19:47 -03:00

193 lines
4.9 KiB
TypeScript

"use client";
import React, { createContext, useContext, useState, useCallback, useEffect } from "react";
import { toast } from "sonner";
import type { Notification } from "@/lib/types";
import { mockNotifications, mockCompanyNotifications } from "@/lib/mock-data";
import { getCurrentUser } from "@/lib/auth";
interface NotificationContextType {
notifications: Notification[];
addNotification: (
notification: Omit<Notification, "id" | "createdAt" | "read">
) => void;
markAsRead: (id: string) => void;
markAllAsRead: () => void;
removeNotification: (id: string) => void;
clearAllNotifications: () => void;
unreadCount: number;
}
const NotificationContext = createContext<NotificationContextType | undefined>(
undefined
);
export function NotificationProvider({
children,
}: {
children: React.ReactNode;
}) {
const [notifications, setNotifications] = useState<Notification[]>([]);
useEffect(() => {
const user = getCurrentUser();
if (user?.role === "company") {
setNotifications(mockCompanyNotifications);
} else {
setNotifications(mockNotifications);
}
}, []);
const addNotification = useCallback(
(notification: Omit<Notification, "id" | "createdAt" | "read">) => {
const newNotification: Notification = {
...notification,
id: Date.now().toString(),
createdAt: new Date().toISOString(),
read: false,
};
setNotifications((prev) => [newNotification, ...prev]);
// Show toast notification
switch (notification.type) {
case "success":
toast.success(notification.title, {
description: notification.message,
});
break;
case "error":
toast.error(notification.title, {
description: notification.message,
});
break;
case "warning":
toast.warning(notification.title, {
description: notification.message,
});
break;
default:
toast.info(notification.title, {
description: notification.message,
});
break;
}
},
[]
);
const markAsRead = useCallback((id: string) => {
setNotifications((prev) =>
prev.map((notification) =>
notification.id === id ? { ...notification, read: true } : notification
)
);
}, []);
const markAllAsRead = useCallback(() => {
setNotifications((prev) =>
prev.map((notification) => ({ ...notification, read: true }))
);
}, []);
const removeNotification = useCallback((id: string) => {
setNotifications((prev) =>
prev.filter((notification) => notification.id !== id)
);
}, []);
const clearAllNotifications = useCallback(() => {
setNotifications([]);
}, []);
const unreadCount = notifications.filter((n) => !n.read).length;
return (
<NotificationContext.Provider
value={{
notifications,
addNotification,
markAsRead,
markAllAsRead,
removeNotification,
clearAllNotifications,
unreadCount,
}}
>
{children}
</NotificationContext.Provider>
);
}
export function useNotifications() {
const context = useContext(NotificationContext);
if (context === undefined) {
throw new Error(
"useNotifications must be used within a NotificationProvider"
);
}
return context;
}
// Hook personalizado para facilitar o uso
export function useNotify() {
const { addNotification } = useNotifications();
return React.useMemo(() => ({
success: (
title: string,
message: string,
options?: { actionUrl?: string; actionLabel?: string; userId?: string }
) =>
addNotification({
title,
message,
type: "success",
userId: options?.userId || "current",
actionUrl: options?.actionUrl,
actionLabel: options?.actionLabel,
}),
error: (
title: string,
message: string,
options?: { actionUrl?: string; actionLabel?: string; userId?: string }
) =>
addNotification({
title,
message,
type: "error",
userId: options?.userId || "current",
actionUrl: options?.actionUrl,
actionLabel: options?.actionLabel,
}),
warning: (
title: string,
message: string,
options?: { actionUrl?: string; actionLabel?: string; userId?: string }
) =>
addNotification({
title,
message,
type: "warning",
userId: options?.userId || "current",
actionUrl: options?.actionUrl,
actionLabel: options?.actionLabel,
}),
info: (
title: string,
message: string,
options?: { actionUrl?: string; actionLabel?: string; userId?: string }
) =>
addNotification({
title,
message,
type: "info",
userId: options?.userId || "current",
actionUrl: options?.actionUrl,
actionLabel: options?.actionLabel,
}),
}), [addNotification]);
}