79 lines
2.6 KiB
TypeScript
79 lines
2.6 KiB
TypeScript
'use client';
|
|
|
|
import {
|
|
SharedBox,
|
|
SharedStack,
|
|
SharedText,
|
|
SharedIcon,
|
|
SharedProgressLine
|
|
} from '@/components/shared/UIComponents';
|
|
import { ShieldAlert } from 'lucide-react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useState } from 'react';
|
|
import { ClientWrapperProps } from '@/lib/contracts/components/ComponentContracts';
|
|
import type { Result } from '@/lib/contracts/Result';
|
|
import type { SponsorshipRequestsViewData } from '@/lib/view-data/SponsorshipRequestsViewData';
|
|
import { SponsorshipRequestsTemplate } from '@/templates/SponsorshipRequestsTemplate';
|
|
|
|
interface SponsorshipRequestsClientProps extends ClientWrapperProps<SponsorshipRequestsViewData> {
|
|
onAccept: (requestId: string) => Promise<Result<void, string>>;
|
|
onReject: (requestId: string, reason?: string) => Promise<Result<void, string>>;
|
|
}
|
|
|
|
export function SponsorshipRequestsClient({ viewData, onAccept, onReject }: SponsorshipRequestsClientProps) {
|
|
const router = useRouter();
|
|
const [isProcessing, setIsProcessing] = useState<string | null>(null);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const handleAccept = async (requestId: string) => {
|
|
setIsProcessing(requestId);
|
|
setError(null);
|
|
const result = await onAccept(requestId);
|
|
if (result.isErr()) {
|
|
setError(result.getError());
|
|
setIsProcessing(null);
|
|
} else {
|
|
router.refresh();
|
|
setIsProcessing(null);
|
|
}
|
|
};
|
|
|
|
const handleReject = async (requestId: string, reason?: string) => {
|
|
setIsProcessing(requestId);
|
|
setError(null);
|
|
const result = await onReject(requestId, reason);
|
|
if (result.isErr()) {
|
|
setError(result.getError());
|
|
setIsProcessing(null);
|
|
} else {
|
|
router.refresh();
|
|
setIsProcessing(null);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<SharedProgressLine isLoading={!!isProcessing} />
|
|
{error && (
|
|
<SharedBox position="fixed" top={4} right={4} zIndex={50} maxWidth="md">
|
|
<SharedBox bg="bg-error-red/10" p={4} rounded="md" border borderColor="border-error-red/20">
|
|
<SharedStack direction="row" align="center" gap={3}>
|
|
<SharedIcon icon={ShieldAlert} size={5} color="text-error-red" />
|
|
<SharedBox>
|
|
<SharedText weight="bold" color="text-error-red">Action Failed</SharedText>
|
|
<SharedText size="sm" color="text-error-red/80">{error}</SharedText>
|
|
</SharedBox>
|
|
</SharedStack>
|
|
</SharedBox>
|
|
</SharedBox>
|
|
)}
|
|
<SponsorshipRequestsTemplate
|
|
viewData={viewData}
|
|
onAccept={handleAccept}
|
|
onReject={handleReject}
|
|
processingId={isProcessing}
|
|
/>
|
|
</>
|
|
);
|
|
}
|