Files
akademiawodociagowca/frontend/src/components/Icon.tsx
T
debian dda54f00a1
Deploy PROD / deploy (push) Successful in 33s
Moderacja wyrazow: slownik i wstrzymywanie wiadomosci do akceptacji
Wiadomosc czatu i pytanie uczestnika przechodza przez slownik przed
publikacja. Trafienie wstrzymuje je (status NEW, moderation_hit), widzi
je tylko panel prowadzenia z przyciskami Opublikuj / Odrzuc, a autor
dostaje informacje, ze wiadomosc czeka. Wiadomosci prowadzacych nie sa
filtrowane.

Normalizacja rozpoznaje ogonki, wielkie litery, cyfry zamiast liter,
powtorzenia i rozstrzelenia. Slownik startowy w V31: wulgaryzmy, obelgi,
tresci zwiazane z pedofilia. WordFilterTest czyta slownik z migracji
i sprawdza obie strony, takze slownictwo wodociagowe.

Ekran "Moderacja wyrazow" w menu: lista z wyszukiwaniem i kategoriami,
dodawanie, edycja, wylaczanie, usuwanie z potwierdzeniem, sprawdzanie
tekstu. Dostep ADMIN i MODERATOR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:48:39 +02:00

158 lines
2.8 KiB
TypeScript

import {
AlertTriangle,
ArrowLeft,
Award,
BookOpen,
CalendarPlus,
Check,
CreditCard,
CheckCircle2,
ChevronDown,
ChevronLeft,
ChevronRight,
ChevronUp,
CircleAlert,
CircleHelp,
Clock,
Copy,
Download,
Droplet,
Eye,
EyeOff,
FileText,
GraduationCap,
Hand,
History,
Image,
Mic,
MicOff,
Key,
Link2,
Loader2,
ListChecks,
Lock,
LogIn,
LogOut,
Mail,
MailCheck,
Menu,
MessageSquare,
MessageSquareOff,
Pencil,
Plus,
Play,
Presentation,
RefreshCw,
Save,
Search,
Send,
Settings,
ShieldAlert,
Trash2,
Upload,
UserPlus,
UserRoundX,
Users,
Volume2,
VolumeX,
Video,
VideoOff,
X,
XCircle,
} from 'lucide-react'
import type { LucideIcon } from 'lucide-react'
/**
* Ikony wedlug systemu HydroNexis: Lucide, 2px stroke, zaokraglone konce.
*
* Zestaw jest jawna mapa, a nie dynamicznym importem po nazwie. Dzieki temu
* bundler dolacza tylko faktycznie uzywane ikony, a literowka w nazwie
* wychodzi na etapie kompilacji, nie u uzytkownika.
*/
const ICONS = {
'alert-triangle': AlertTriangle,
'arrow-left': ArrowLeft,
award: Award,
'book-open': BookOpen,
'calendar-plus': CalendarPlus,
check: Check,
'credit-card': CreditCard,
'check-circle': CheckCircle2,
'chevron-down': ChevronDown,
'chevron-left': ChevronLeft,
'chevron-right': ChevronRight,
'chevron-up': ChevronUp,
'circle-alert': CircleAlert,
'help-circle': CircleHelp,
clock: Clock,
copy: Copy,
download: Download,
droplet: Droplet,
eye: Eye,
'eye-off': EyeOff,
'file-text': FileText,
'graduation-cap': GraduationCap,
hand: Hand,
history: History,
image: Image,
mic: Mic,
'mic-off': MicOff,
key: Key,
link: Link2,
loader: Loader2,
'list-checks': ListChecks,
lock: Lock,
'log-in': LogIn,
'log-out': LogOut,
mail: Mail,
'mail-check': MailCheck,
menu: Menu,
'message-square': MessageSquare,
'message-square-off': MessageSquareOff,
pencil: Pencil,
plus: Plus,
play: Play,
presentation: Presentation,
refresh: RefreshCw,
save: Save,
search: Search,
send: Send,
settings: Settings,
'shield-alert': ShieldAlert,
trash: Trash2,
upload: Upload,
'user-plus': UserPlus,
'user-off': UserRoundX,
users: Users,
volume: Volume2,
'volume-off': VolumeX,
video: Video,
'video-off': VideoOff,
x: X,
'x-circle': XCircle,
} satisfies Record<string, LucideIcon>
export type IconName = keyof typeof ICONS
export function Icon({
name,
size = 18,
className = '',
strokeWidth = 2,
}: {
name: IconName
size?: number
className?: string
strokeWidth?: number
}) {
const Component = ICONS[name]
return (
<Component
size={size}
strokeWidth={strokeWidth}
className={`shrink-0 ${className}`}
aria-hidden="true"
/>
)
}