fix: corrige tipo JSON para String no SQLite e acentuação nos textos

- Altera typePreferences e categoryPreferences de Json para String no Prisma
- Atualiza API de preferências para fazer parse/stringify de JSON
- Corrige todos os textos sem acentuação nos componentes de notificação

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-07 21:09:02 -03:00
parent f2c0298285
commit 7ecb4c1110
7 changed files with 104 additions and 89 deletions

View file

@ -36,26 +36,26 @@ interface NotificationPreferencesFormProps {
isPortal?: boolean
}
// Agrupamento de tipos de notificacao
// Agrupamento de tipos de notificação
const TYPE_GROUPS = {
lifecycle: {
label: "Ciclo de vida do chamado",
description: "Notificacoes sobre abertura, resolucao e mudancas de status",
description: "Notificações sobre abertura, resolução e mudanças de status",
types: ["ticket_created", "ticket_assigned", "ticket_resolved", "ticket_reopened", "ticket_status_changed", "ticket_priority_changed"],
},
communication: {
label: "Comunicacao",
description: "Comentarios e respostas nos chamados",
label: "Comunicação",
description: "Comentários e respostas nos chamados",
types: ["comment_public", "comment_response", "comment_mention"],
},
sla: {
label: "SLA e alertas",
description: "Alertas de prazo e metricas",
description: "Alertas de prazo e métricas",
types: ["sla_at_risk", "sla_breached", "sla_daily_digest"],
},
security: {
label: "Seguranca",
description: "Notificacoes de autenticacao e acesso",
label: "Segurança",
description: "Notificações de autenticação e acesso",
types: ["security_password_reset", "security_email_verify", "security_email_change", "security_new_login", "security_invite"],
},
}
@ -74,20 +74,20 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
try {
const response = await fetch("/api/notifications/preferences")
if (!response.ok) {
throw new Error("Erro ao carregar preferencias")
throw new Error("Erro ao carregar preferências")
}
const data = await response.json()
setPreferences(data)
// Inicializa preferencias locais
// Inicializa preferências locais
const typePrefs: Record<string, boolean> = {}
data.types.forEach((t: NotificationType) => {
typePrefs[t.type] = t.enabled
})
setLocalTypePrefs(typePrefs)
} catch (error) {
console.error("Erro ao carregar preferencias:", error)
toast.error("Nao foi possivel carregar suas preferencias")
console.error("Erro ao carregar preferências:", error)
toast.error("Não foi possível carregar suas preferências")
} finally {
setLoading(false)
}
@ -112,13 +112,13 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
})
if (!response.ok) {
throw new Error("Erro ao salvar preferencias")
throw new Error("Erro ao salvar preferências")
}
toast.success("Preferencias salvas com sucesso")
toast.success("Preferências salvas com sucesso")
} catch (error) {
console.error("Erro ao salvar preferencias:", error)
toast.error("Nao foi possivel salvar suas preferencias")
console.error("Erro ao salvar preferências:", error)
toast.error("Não foi possível salvar suas preferências")
} finally {
setSaving(false)
}
@ -153,7 +153,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
<Card>
<CardContent className="py-8">
<p className="text-center text-muted-foreground">
Nao foi possivel carregar suas preferencias de notificacao.
Não foi possível carregar suas preferências de notificação.
</p>
<div className="flex justify-center mt-4">
<Button onClick={loadPreferences}>Tentar novamente</Button>
@ -163,7 +163,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
)
}
// Filtra tipos visiveis para o usuario
// Filtra tipos visíveis para o usuário
const visibleTypes = preferences.types
// Agrupa tipos por categoria
@ -177,15 +177,15 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
return (
<div className="space-y-6">
{/* Configuracao global de e-mail */}
{/* Configuração global de e-mail */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Mail className="h-5 w-5" />
Notificacoes por e-mail
Notificações por e-mail
</CardTitle>
<CardDescription>
Controle se deseja receber notificacoes por e-mail.
Controle se deseja receber notificações por e-mail.
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
@ -194,8 +194,8 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
<Label className="text-base">Receber e-mails</Label>
<p className="text-sm text-muted-foreground">
{preferences.emailEnabled
? "Voce recebera notificacoes por e-mail conforme suas preferencias"
: "Todas as notificacoes por e-mail estao desativadas"}
? "Você receberá notificações por e-mail conforme suas preferências"
: "Todas as notificações por e-mail estão desativadas"}
</p>
</div>
<Switch
@ -208,14 +208,14 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
<>
<Separator />
{/* Horario de silencio - apenas staff */}
{/* Horário de silêncio - apenas staff */}
<div className="space-y-4">
<div className="flex items-center gap-2">
<Clock className="h-4 w-4 text-muted-foreground" />
<Label className="text-base">Horario de silencio</Label>
<Label className="text-base">Horário de silêncio</Label>
</div>
<p className="text-sm text-muted-foreground">
Durante este periodo, notificacoes nao urgentes serao adiadas.
Durante este período, notificações não urgentes serão adiadas.
</p>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
@ -229,7 +229,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
/>
</div>
<div className="flex items-center gap-2">
<Label htmlFor="quietEnd" className="text-sm">as</Label>
<Label htmlFor="quietEnd" className="text-sm">às</Label>
<Input
id="quietEnd"
type="time"
@ -252,11 +252,11 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
<Separator />
{/* Frequencia de resumo - apenas staff */}
{/* Frequência de resumo - apenas staff */}
<div className="space-y-4">
<Label className="text-base">Frequencia de resumo</Label>
<Label className="text-base">Frequência de resumo</Label>
<p className="text-sm text-muted-foreground">
Como voce prefere receber as notificacoes nao urgentes.
Como você prefere receber as notificações o urgentes.
</p>
<Select
value={preferences.digestFrequency}
@ -267,7 +267,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
</SelectTrigger>
<SelectContent>
<SelectItem value="immediate">Imediato</SelectItem>
<SelectItem value="daily">Resumo diario</SelectItem>
<SelectItem value="daily">Resumo diário</SelectItem>
<SelectItem value="weekly">Resumo semanal</SelectItem>
</SelectContent>
</Select>
@ -277,19 +277,19 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
</CardContent>
</Card>
{/* Tipos de notificacao */}
{/* Tipos de notificação */}
{preferences.emailEnabled && (
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Bell className="h-5 w-5" />
Tipos de notificacao
Tipos de notificação
</CardTitle>
<CardDescription>
Escolha quais tipos de notificacao deseja receber.
Escolha quais tipos de notificação deseja receber.
{!preferences.isStaff && (
<span className="block mt-1 text-amber-600">
Algumas notificacoes sao obrigatorias e nao podem ser desativadas.
Algumas notificações são obrigatórias e o podem ser desativadas.
</span>
)}
</CardDescription>
@ -323,7 +323,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
</Label>
{notifType.required && (
<Badge variant="secondary" className="ml-2 text-xs">
Obrigatorio
Obrigatório
</Badge>
)}
</div>
@ -343,7 +343,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
</Card>
)}
{/* Botao de salvar */}
{/* Botão de salvar */}
<div className="flex justify-end">
<Button onClick={savePreferences} disabled={saving}>
{saving ? (
@ -352,7 +352,7 @@ export function NotificationPreferencesForm({ isPortal = false }: NotificationPr
Salvando...
</>
) : (
"Salvar preferencias"
"Salvar preferências"
)}
</Button>
</div>