website refactor
This commit is contained in:
101
apps/website/components/profile/SponsorshipRequestsPanel.tsx
Normal file
101
apps/website/components/profile/SponsorshipRequestsPanel.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { Card } from '@/ui/Card';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { Box } from '@/ui/Box';
|
||||
import { Stack } from '@/ui/Stack';
|
||||
import { Text } from '@/ui/Text';
|
||||
import { Surface } from '@/ui/Surface';
|
||||
import { DateDisplay } from '@/lib/display-objects/DateDisplay';
|
||||
import { ProfileSection } from './ProfileSection';
|
||||
|
||||
interface Request {
|
||||
id: string;
|
||||
sponsorName: string;
|
||||
message?: string | null;
|
||||
createdAtIso: string;
|
||||
}
|
||||
|
||||
interface Section {
|
||||
entityId: string;
|
||||
entityName: string;
|
||||
entityType: string;
|
||||
requests: Request[];
|
||||
}
|
||||
|
||||
interface SponsorshipRequestsPanelProps {
|
||||
sections: Section[];
|
||||
onAccept: (requestId: string) => Promise<void>;
|
||||
onReject: (requestId: string, reason?: string) => Promise<void>;
|
||||
processingId?: string | null;
|
||||
}
|
||||
|
||||
export function SponsorshipRequestsPanel({
|
||||
sections,
|
||||
onAccept,
|
||||
onReject,
|
||||
processingId,
|
||||
}: SponsorshipRequestsPanelProps) {
|
||||
return (
|
||||
<Stack gap={8}>
|
||||
{sections.map((section) => (
|
||||
<ProfileSection
|
||||
key={`${section.entityType}-${section.entityId}`}
|
||||
title={section.entityName}
|
||||
description={`Manage pending sponsorship requests for ${section.entityName}.`}
|
||||
>
|
||||
<Card>
|
||||
{section.requests.length === 0 ? (
|
||||
<Text size="sm" color="text-gray-400">No pending requests.</Text>
|
||||
) : (
|
||||
<Stack gap={3}>
|
||||
{section.requests.map((request) => (
|
||||
<Surface
|
||||
key={request.id}
|
||||
variant="muted"
|
||||
rounded="lg"
|
||||
border
|
||||
padding={4}
|
||||
backgroundColor="#0C0D0F"
|
||||
borderColor="#23272B"
|
||||
>
|
||||
<Stack direction="row" align="center" justify="between" wrap gap={4}>
|
||||
<Box flexGrow={1} minWidth="0">
|
||||
<Text weight="medium" color="text-white" block>{request.sponsorName}</Text>
|
||||
{request.message && (
|
||||
<Text size="xs" color="text-gray-400" block mt={1}>{request.message}</Text>
|
||||
)}
|
||||
<Text size="xs" color="text-gray-500" block mt={2}>
|
||||
{DateDisplay.formatShort(request.createdAtIso)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Stack direction="row" gap={2}>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => onAccept(request.id)}
|
||||
size="sm"
|
||||
disabled={!!processingId}
|
||||
>
|
||||
{processingId === request.id ? 'Accepting...' : 'Accept'}
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => onReject(request.id)}
|
||||
size="sm"
|
||||
disabled={!!processingId}
|
||||
>
|
||||
{processingId === request.id ? 'Rejecting...' : 'Reject'}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Surface>
|
||||
))}
|
||||
</Stack>
|
||||
)}
|
||||
</Card>
|
||||
</ProfileSection>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user