mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-13 15:13:07 +00:00
- ~190 findings zerados: knip --fix (grafo corrigido: tests como entries, migrations como consumidores) + delecao guardada dos orfaos (git grep -w antes de deletar) + reparos manuais dos corpos arrow pendurados - pecas nao usadas do kit ui deletadas (PaginationLink/Next/Previous, familias Sidebar/Combobox/Sheet/Drawer/Dialog etc.) - shadcn add recoloca se precisar - acoes mortas removidas (updateCampaignDemandDetails*, *Record orfaos), schemas/tipos mortos (campaignDemandDetailsUpdateSchema, Contact do zod), helpers mortos - tipos de eleicao derivam direto das *_OPTIONS (consts intermediarias eliminadas) - knip.json: rules exports/types/enumMembers=error, duplicates=off (unicos hits: 6 aliases deliberados canUpdateX=canReadX); hints aplicados (payload.config entry redundante, ignores de tsx/sharp/playwright/payload-types desnecessarios) - ledger: linha P2 dos unused exports fechada
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import type { CampaignUser, Media } from '@/payload-types'
|
|
|
|
const CAMPAIGN_AVATAR_MAX_BYTES = 2 * 1024 * 1024
|
|
|
|
const CAMPAIGN_AVATAR_UNSUPPORTED_MIME_MESSAGE = 'Envie uma imagem JPEG, PNG ou WebP.'
|
|
const CAMPAIGN_AVATAR_MAX_SIZE_MESSAGE = 'A imagem deve ter no máximo 2 MB.'
|
|
const CAMPAIGN_AVATAR_EMPTY_FILE_MESSAGE = 'O arquivo enviado está vazio.'
|
|
|
|
export const campaignRoleLabels: Record<CampaignUser['role'], string> = {
|
|
coordinator: 'Coordenador Geral',
|
|
advisor: 'Assessor',
|
|
candidate: 'Candidato',
|
|
leader: 'Liderança',
|
|
}
|
|
|
|
export type CampaignUserShellView = {
|
|
name: string
|
|
role: CampaignUser['role']
|
|
avatarUrl: string | null
|
|
}
|
|
|
|
export const campaignUserShellView = (
|
|
user: Pick<CampaignUser, 'name' | 'role' | 'avatar'>,
|
|
): CampaignUserShellView => ({
|
|
name: user.name,
|
|
role: user.role,
|
|
avatarUrl: mediaDocumentUrl(user.avatar),
|
|
})
|
|
|
|
const CAMPAIGN_AVATAR_MIME_TYPES = new Set(['image/jpeg', 'image/png', 'image/webp'])
|
|
|
|
export const campaignUserInitials = (name: string): string => {
|
|
const parts = name.trim().split(/\s+/).filter(Boolean).slice(0, 2)
|
|
|
|
if (parts.length === 0) return '?'
|
|
|
|
return parts.map((part) => part[0]?.toUpperCase() ?? '').join('')
|
|
}
|
|
|
|
export const mediaDocumentUrl = (media: number | Media | null | undefined): string | null => {
|
|
if (!media || typeof media === 'number') return null
|
|
|
|
return media.url ?? null
|
|
}
|
|
|
|
export const assertCampaignAvatarFile = (file: File): void => {
|
|
if (!CAMPAIGN_AVATAR_MIME_TYPES.has(file.type)) {
|
|
throw new Error(CAMPAIGN_AVATAR_UNSUPPORTED_MIME_MESSAGE)
|
|
}
|
|
if (file.size > CAMPAIGN_AVATAR_MAX_BYTES) {
|
|
throw new Error(CAMPAIGN_AVATAR_MAX_SIZE_MESSAGE)
|
|
}
|
|
if (file.size === 0) {
|
|
throw new Error(CAMPAIGN_AVATAR_EMPTY_FILE_MESSAGE)
|
|
}
|
|
}
|
|
|
|
export const CAMPAIGN_AVATAR_SAFE_ERROR_MESSAGES = [
|
|
CAMPAIGN_AVATAR_UNSUPPORTED_MIME_MESSAGE,
|
|
CAMPAIGN_AVATAR_MAX_SIZE_MESSAGE,
|
|
CAMPAIGN_AVATAR_EMPTY_FILE_MESSAGE,
|
|
] as const
|