- Add bottle_splits and split_participants tables with RLS - Implement soft-lock: pending requests count as reserved - Create /splits/create wizard (3 steps: bottle, pricing, shipping) - Create /splits/[slug] public page with price calculator - Create /splits/manage host dashboard with participant workflow - Add SplitProgressBar component for visual volume display - Status workflow: PENDING -> APPROVED -> PAID -> SHIPPED - Forum export (BBCode format) - Saved defaults in localStorage for glass/shipping costs
102 lines
4.0 KiB
TypeScript
102 lines
4.0 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
|
|
interface SplitProgressBarProps {
|
|
totalVolume: number;
|
|
hostShare: number;
|
|
taken: number;
|
|
reserved: number;
|
|
showLabels?: boolean;
|
|
height?: 'sm' | 'md' | 'lg';
|
|
}
|
|
|
|
export default function SplitProgressBar({
|
|
totalVolume,
|
|
hostShare,
|
|
taken,
|
|
reserved,
|
|
showLabels = true,
|
|
height = 'md',
|
|
}: SplitProgressBarProps) {
|
|
const available = totalVolume - hostShare - taken - reserved;
|
|
|
|
const hostPercent = (hostShare / totalVolume) * 100;
|
|
const takenPercent = (taken / totalVolume) * 100;
|
|
const reservedPercent = (reserved / totalVolume) * 100;
|
|
const availablePercent = (available / totalVolume) * 100;
|
|
|
|
const heightClass = height === 'sm' ? 'h-3' : height === 'lg' ? 'h-8' : 'h-5';
|
|
|
|
return (
|
|
<div className="space-y-2">
|
|
<div className={`w-full ${heightClass} rounded-full overflow-hidden flex bg-zinc-800`}>
|
|
{/* Host Share - Grey */}
|
|
{hostPercent > 0 && (
|
|
<div
|
|
className="bg-zinc-600 flex items-center justify-center text-[8px] font-bold text-white/70"
|
|
style={{ width: `${hostPercent}%` }}
|
|
>
|
|
{height !== 'sm' && hostPercent > 10 && 'Host'}
|
|
</div>
|
|
)}
|
|
|
|
{/* Taken - Orange/Red */}
|
|
{takenPercent > 0 && (
|
|
<div
|
|
className="bg-orange-600 flex items-center justify-center text-[8px] font-bold text-white"
|
|
style={{ width: `${takenPercent}%` }}
|
|
>
|
|
{height !== 'sm' && takenPercent > 8 && `${taken}cl`}
|
|
</div>
|
|
)}
|
|
|
|
{/* Reserved/Pending - Yellow */}
|
|
{reservedPercent > 0 && (
|
|
<div
|
|
className="bg-yellow-500 flex items-center justify-center text-[8px] font-bold text-black/70"
|
|
style={{ width: `${reservedPercent}%` }}
|
|
>
|
|
{height !== 'sm' && reservedPercent > 8 && `${reserved}cl`}
|
|
</div>
|
|
)}
|
|
|
|
{/* Available - Green */}
|
|
{availablePercent > 0 && (
|
|
<div
|
|
className="bg-green-500 flex items-center justify-center text-[8px] font-bold text-white"
|
|
style={{ width: `${availablePercent}%` }}
|
|
>
|
|
{height !== 'sm' && availablePercent > 8 && `${available}cl`}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{showLabels && (
|
|
<div className="flex flex-wrap gap-3 text-[10px] font-bold">
|
|
<div className="flex items-center gap-1.5">
|
|
<div className="w-2.5 h-2.5 rounded-sm bg-zinc-600" />
|
|
<span className="text-zinc-500">Host ({hostShare}cl)</span>
|
|
</div>
|
|
{taken > 0 && (
|
|
<div className="flex items-center gap-1.5">
|
|
<div className="w-2.5 h-2.5 rounded-sm bg-orange-600" />
|
|
<span className="text-zinc-500">Vergeben ({taken}cl)</span>
|
|
</div>
|
|
)}
|
|
{reserved > 0 && (
|
|
<div className="flex items-center gap-1.5">
|
|
<div className="w-2.5 h-2.5 rounded-sm bg-yellow-500" />
|
|
<span className="text-zinc-500">Reserviert ({reserved}cl)</span>
|
|
</div>
|
|
)}
|
|
<div className="flex items-center gap-1.5">
|
|
<div className="w-2.5 h-2.5 rounded-sm bg-green-500" />
|
|
<span className="text-zinc-500">Verfügbar ({available}cl)</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|