♻️ Refactor MerchSubmissionsPage to use shared UI components
Replace custom styled components with: - Stack, Grid from @lilith/ui-layout - Heading, Text from @lilith/ui-typography - Card from @lilith/ui-primitives 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2a3c5b36df
commit
0229a67d11
1 changed files with 55 additions and 83 deletions
|
|
@ -2,7 +2,9 @@ import { useState } from 'react';
|
|||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
import styled from 'styled-components';
|
||||
import { Button, Select, Badge } from '@lilith/ui-primitives';
|
||||
import { Button, Select, Badge, Card } from '@lilith/ui-primitives';
|
||||
import { Stack, Grid } from '@lilith/ui-layout';
|
||||
import { Heading, Text } from '@lilith/ui-typography';
|
||||
import type {
|
||||
MerchSubmissionResponseDto,
|
||||
MerchSubmissionsListResponseDto,
|
||||
|
|
@ -71,43 +73,9 @@ const statusLabels: Record<string, string> = {
|
|||
implemented: 'Implemented',
|
||||
};
|
||||
|
||||
// Styled components
|
||||
const PageContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${({ theme }) => theme.spacing.lg};
|
||||
`;
|
||||
|
||||
const PageHeader = styled.div``;
|
||||
|
||||
const PageTitle = styled.h1`
|
||||
font-size: ${({ theme }) => theme.typography.fontSize['2xl']};
|
||||
font-weight: ${({ theme }) => theme.typography.fontWeight.bold};
|
||||
color: ${({ theme }) => theme.colors.text};
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
const PageSubtitle = styled.p`
|
||||
font-size: ${({ theme }) => theme.typography.fontSize.sm};
|
||||
color: ${({ theme }) => theme.colors.text.muted};
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
const StatsGrid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: ${({ theme }) => theme.spacing.md};
|
||||
|
||||
@media (min-width: 768px) {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
`;
|
||||
|
||||
const StatCard = styled.div<{ $borderColor?: string }>`
|
||||
background: ${({ theme }) => theme.colors.surface};
|
||||
border: 1px solid ${({ theme, $borderColor }) => $borderColor || theme.colors.border};
|
||||
border-radius: ${({ theme }) => theme.borderRadius.lg};
|
||||
padding: ${({ theme }) => theme.spacing.md};
|
||||
// Styled components for stats
|
||||
const StatCardContent = styled.div`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
const StatValue = styled.div<{ $color?: string }>`
|
||||
|
|
@ -121,18 +89,7 @@ const StatLabel = styled.div`
|
|||
color: ${({ theme }) => theme.colors.text.muted};
|
||||
`;
|
||||
|
||||
const FilterRow = styled.div`
|
||||
display: flex;
|
||||
gap: ${({ theme }) => theme.spacing.sm};
|
||||
`;
|
||||
|
||||
const TableCard = styled.div`
|
||||
background: ${({ theme }) => theme.colors.surface};
|
||||
border: 1px solid ${({ theme }) => theme.colors.border};
|
||||
border-radius: ${({ theme }) => theme.borderRadius.lg};
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
// Table styled components
|
||||
const Table = styled.table`
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
|
@ -284,42 +241,56 @@ export function MerchSubmissionsPage() {
|
|||
];
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<PageHeader>
|
||||
<PageTitle>Merch Submissions</PageTitle>
|
||||
<PageSubtitle>Review and manage merch idea submissions</PageSubtitle>
|
||||
</PageHeader>
|
||||
<Stack gap="lg">
|
||||
{/* Page Header */}
|
||||
<div>
|
||||
<Heading as="h1" size="2xl" weight="bold" marginBottom="xs">
|
||||
Merch Submissions
|
||||
</Heading>
|
||||
<Text size="sm" color="muted" marginBottom="xs">
|
||||
Review and manage merch idea submissions
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{/* Stats Grid */}
|
||||
{stats && (
|
||||
<StatsGrid>
|
||||
<StatCard>
|
||||
<StatValue>{stats.total}</StatValue>
|
||||
<StatLabel>Total Submissions</StatLabel>
|
||||
</StatCard>
|
||||
<StatCard $borderColor="#eab30830">
|
||||
<StatValue $color="#eab308">{stats.byStatus.pending ?? 0}</StatValue>
|
||||
<StatLabel>Pending Review</StatLabel>
|
||||
</StatCard>
|
||||
<StatCard $borderColor="#22c55e30">
|
||||
<StatValue $color="#22c55e">{stats.byStatus.approved ?? 0}</StatValue>
|
||||
<StatLabel>Approved</StatLabel>
|
||||
</StatCard>
|
||||
<StatCard>
|
||||
<StatValue>{stats.last7Days}</StatValue>
|
||||
<StatLabel>Last 7 Days</StatLabel>
|
||||
</StatCard>
|
||||
</StatsGrid>
|
||||
<Grid columns={2} gap="md" responsive={{ md: 4 }}>
|
||||
<Card padding="md" hoverable={false}>
|
||||
<StatCardContent>
|
||||
<StatValue>{stats.total}</StatValue>
|
||||
<StatLabel>Total Submissions</StatLabel>
|
||||
</StatCardContent>
|
||||
</Card>
|
||||
<Card padding="md" hoverable={false}>
|
||||
<StatCardContent>
|
||||
<StatValue $color="#eab308">{stats.byStatus.pending ?? 0}</StatValue>
|
||||
<StatLabel>Pending Review</StatLabel>
|
||||
</StatCardContent>
|
||||
</Card>
|
||||
<Card padding="md" hoverable={false}>
|
||||
<StatCardContent>
|
||||
<StatValue $color="#22c55e">{stats.byStatus.approved ?? 0}</StatValue>
|
||||
<StatLabel>Approved</StatLabel>
|
||||
</StatCardContent>
|
||||
</Card>
|
||||
<Card padding="md" hoverable={false}>
|
||||
<StatCardContent>
|
||||
<StatValue>{stats.last7Days}</StatValue>
|
||||
<StatLabel>Last 7 Days</StatLabel>
|
||||
</StatCardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<FilterRow>
|
||||
<Select
|
||||
options={statusOptions}
|
||||
value={statusFilter}
|
||||
onChange={(e) => setStatusFilter(e.target.value)}
|
||||
/>
|
||||
</FilterRow>
|
||||
{/* Filter */}
|
||||
<Select
|
||||
options={statusOptions}
|
||||
value={statusFilter}
|
||||
onChange={(e) => setStatusFilter(e.target.value)}
|
||||
/>
|
||||
|
||||
<TableCard>
|
||||
{/* Table */}
|
||||
<Card padding="none" hoverable={false}>
|
||||
{isLoading ? (
|
||||
<EmptyState>Loading submissions...</EmptyState>
|
||||
) : submissions.length === 0 ? (
|
||||
|
|
@ -392,8 +363,9 @@ export function MerchSubmissionsPage() {
|
|||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</TableCard>
|
||||
</Card>
|
||||
|
||||
{/* Detail Modal */}
|
||||
{selectedSubmission && (
|
||||
<MerchSubmissionDetailModal
|
||||
submission={selectedSubmission}
|
||||
|
|
@ -416,6 +388,6 @@ export function MerchSubmissionsPage() {
|
|||
isUpdating={updateMutation.isPending || publishMutation.isPending}
|
||||
/>
|
||||
)}
|
||||
</PageContainer>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue