website refactor

This commit is contained in:
2026-01-18 16:18:18 +01:00
parent 0b301feb61
commit 13567d51af
329 changed files with 4701 additions and 4750 deletions

View File

@@ -12,9 +12,8 @@ import {
Vote
} from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { Box } from '@/ui/Box';
import { Text } from '@/ui/Text';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Icon } from '@/ui/Icon';
const notificationIcons: Record<string, typeof Bell> = {
@@ -92,9 +91,9 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
};
return (
<Box position="relative" ref={panelRef}>
<Stack position="relative" ref={panelRef}>
{/* Bell button */}
<Box
<Stack
as="button"
onClick={() => setIsOpen(!isOpen)}
p={2}
@@ -108,7 +107,7 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
>
<Icon icon={Bell} size={5} />
{unreadCount > 0 && (
<Box
<Stack
position="absolute"
top="-0.5"
right="-0.5"
@@ -125,13 +124,13 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
style={{ fontSize: '10px', fontWeight: 'bold' }}
>
{unreadCount > 99 ? '99+' : unreadCount}
</Box>
</Stack>
)}
</Box>
</Stack>
{/* Notification panel */}
{isOpen && (
<Box
<Stack
position="absolute"
right="0"
top="full"
@@ -146,20 +145,20 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
zIndex={50}
>
{/* Header */}
<Box display="flex" alignItems="center" justifyContent="between" px={4} py={3} borderBottom borderColor="border-charcoal-outline">
<Box display="flex" alignItems="center" gap={2}>
<Stack display="flex" alignItems="center" justifyContent="between" px={4} py={3} borderBottom borderColor="border-charcoal-outline">
<Stack display="flex" alignItems="center" gap={2}>
<Icon icon={Bell} size={4} color="text-primary-blue" />
<Text weight="semibold" color="text-white">Notifications</Text>
{unreadCount > 0 && (
<Box px={2} py={0.5} bg="bg-red-500/20" rounded="full">
<Stack px={2} py={0.5} bg="bg-red-500/20" rounded="full">
<Text size="xs" weight="medium" color="text-red-400">
{unreadCount} new
</Text>
</Box>
</Stack>
)}
</Box>
</Stack>
{unreadCount > 0 && (
<Box
<Stack
as="button"
onClick={markAllAsRead}
display="flex"
@@ -171,22 +170,22 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
>
<Icon icon={CheckCheck} size={3.5} color="text-gray-400" />
<Text size="xs" color="text-gray-400">Mark all read</Text>
</Box>
</Stack>
)}
</Box>
</Stack>
{/* Notifications list */}
<Box maxHeight="400px" overflow="auto">
<Stack maxHeight="400px" overflow="auto">
{notifications.length === 0 ? (
<Box py={12} textAlign="center">
<Box w="12" h="12" mx="auto" mb={3} rounded="full" bg="bg-iron-gray/50" display="flex" alignItems="center" justifyContent="center">
<Stack py={12} textAlign="center">
<Stack w="12" h="12" mx="auto" mb={3} rounded="full" bg="bg-iron-gray/50" display="flex" alignItems="center" justifyContent="center">
<Icon icon={Bell} size={6} color="text-gray-500" />
</Box>
</Stack>
<Text size="sm" color="text-gray-400" block>No notifications yet</Text>
<Text size="xs" color="text-gray-500" block mt={1}>
You&apos;ll be notified about protests, races, and more
</Text>
</Box>
</Stack>
) : (
<Stack gap={0}
// eslint-disable-next-line gridpilot-rules/component-classification
@@ -197,7 +196,7 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
const colorClass = notificationColors[notification.type] || 'text-gray-400 bg-gray-400/10';
return (
<Box
<Stack
key={notification.id}
as="button"
onClick={() => handleNotificationClick(notification)}
@@ -209,26 +208,26 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
hoverBg="bg-iron-gray/30"
bg={!notification.read ? 'bg-primary-blue/5' : undefined}
>
<Box display="flex" gap={3}>
<Box p={2} rounded="lg" flexShrink={0}
<Stack display="flex" gap={3}>
<Stack p={2} rounded="lg" flexShrink={0}
// eslint-disable-next-line gridpilot-rules/component-classification
className={colorClass}
>
<Icon icon={NotificationIcon} size={4} />
</Box>
<Box flexGrow={1} minWidth="0">
<Box display="flex" alignItems="start" justifyContent="between" gap={2}>
</Stack>
<Stack flexGrow={1} minWidth="0">
<Stack display="flex" alignItems="start" justifyContent="between" gap={2}>
<Text size="sm" weight="medium" truncate color={!notification.read ? 'text-white' : 'text-gray-300'} block>
{notification.title}
</Text>
{!notification.read && (
<Box w="2" h="2" bg="bg-primary-blue" rounded="full" flexShrink={0} mt={1.5} />
<Stack w="2" h="2" bg="bg-primary-blue" rounded="full" flexShrink={0} mt={1.5} />
)}
</Box>
</Stack>
<Text size="xs" color="text-gray-500" lineClamp={2} mt={0.5} block>
{notification.message}
</Text>
<Box display="flex" alignItems="center" gap={2} mt={1.5}>
<Stack display="flex" alignItems="center" gap={2} mt={1.5}>
<Text color="text-gray-600"
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '10px' }}
@@ -236,7 +235,7 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
{formatTime(notification.createdAt)}
</Text>
{notification.actionUrl && (
<Box display="flex" alignItems="center" gap={0.5}>
<Stack display="flex" alignItems="center" gap={0.5}>
<Icon icon={ExternalLink} size={2.5} color="text-primary-blue" />
<Text color="text-primary-blue"
// eslint-disable-next-line gridpilot-rules/component-classification
@@ -244,31 +243,31 @@ export function NotificationCenter({ onNavigate }: NotificationCenterProps) {
>
View
</Text>
</Box>
</Stack>
)}
</Box>
</Box>
</Box>
</Box>
</Stack>
</Stack>
</Stack>
</Stack>
);
})}
</Stack>
)}
</Box>
</Stack>
{/* Footer */}
{notifications.length > 0 && (
<Box px={4} py={2} borderTop borderColor="border-charcoal-outline" bg="bg-iron-gray/20">
<Stack px={4} py={2} borderTop borderColor="border-charcoal-outline" bg="bg-iron-gray/20">
<Text color="text-gray-500" textAlign="center" block
// eslint-disable-next-line gridpilot-rules/component-classification
style={{ fontSize: '10px' }}
>
Showing {notifications.length} notification{notifications.length !== 1 ? 's' : ''}
</Text>
</Box>
</Stack>
)}
</Box>
</Stack>
)}
</Box>
</Stack>
);
}

View File

@@ -6,7 +6,6 @@ import { v4 as uuid } from 'uuid';
import { ModalNotification } from './ModalNotification';
import { ToastNotification } from './ToastNotification';
import { Box } from '@/ui/Box';
import { Stack } from '@/ui/Stack';
import type { Notification, NotificationAction, NotificationVariant } from './notificationTypes';
@@ -136,7 +135,7 @@ export function NotificationProvider({ children }: NotificationProviderProps) {
{children}
{/* Toast notifications container */}
<Box position="fixed" top="20" right="4" zIndex={50}>
<Stack position="fixed" top="20" right="4" zIndex={50}>
<Stack gap={3}>
{toastNotifications.map((notification) => (
<ToastNotification
@@ -147,7 +146,7 @@ export function NotificationProvider({ children }: NotificationProviderProps) {
/>
))}
</Stack>
</Box>
</Stack>
{/* Modal notification */}
{modalNotification && (