mobile responsive owners box
This commit is contained in:
@@ -390,7 +390,9 @@ const CommissionDistributionPanel = ({
|
|||||||
<p className="text-xs text-zinc-400 mt-1">Add team members with commission rules to see the distribution.</p>
|
<p className="text-xs text-zinc-400 mt-1">Add team members with commission rules to see the distribution.</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="overflow-x-auto rounded-xl border border-zinc-200 dark:border-white/5">
|
<>
|
||||||
|
{/* ── Desktop table (sm+) ── */}
|
||||||
|
<div className="hidden sm:block overflow-x-auto rounded-xl border border-zinc-200 dark:border-white/5">
|
||||||
<table className="w-full text-left min-w-[600px]">
|
<table className="w-full text-left min-w-[600px]">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-zinc-200 dark:border-white/5 bg-zinc-50 dark:bg-white/[0.02]">
|
<tr className="border-b border-zinc-200 dark:border-white/5 bg-zinc-50 dark:bg-white/[0.02]">
|
||||||
@@ -465,6 +467,65 @@ const CommissionDistributionPanel = ({
|
|||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ── Mobile cards (< sm) ── */}
|
||||||
|
<div className="sm:hidden space-y-2.5">
|
||||||
|
{filteredRows.length === 0 ? (
|
||||||
|
<div className="rounded-xl border border-zinc-200 dark:border-white/5 py-10 text-center">
|
||||||
|
<Users size={22} className="mx-auto mb-2 text-zinc-400" />
|
||||||
|
<p className="text-sm text-zinc-500">No commission entries match the current filters.</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={clearFilters}
|
||||||
|
className="mt-3 inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-[11px] font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400 hover:bg-emerald-50 dark:hover:bg-emerald-500/10 border border-emerald-200 dark:border-emerald-500/20 transition-colors"
|
||||||
|
>
|
||||||
|
<FilterX size={12} /> Clear Filters
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{filteredRows.map((row) => (
|
||||||
|
<div key={row.key} className="rounded-xl border border-zinc-200 dark:border-white/5 bg-white dark:bg-white/[0.02] p-3.5">
|
||||||
|
{/* Name + Amount */}
|
||||||
|
<div className="flex items-center justify-between gap-2">
|
||||||
|
<div className="flex items-center gap-2.5 min-w-0">
|
||||||
|
<div className="w-7 h-7 rounded-full bg-emerald-500/15 flex items-center justify-center text-[10px] font-black text-emerald-600 dark:text-emerald-400 flex-shrink-0">
|
||||||
|
{row.name?.[0] || '?'}
|
||||||
|
</div>
|
||||||
|
<span className="text-sm font-semibold text-zinc-900 dark:text-white truncate">{row.name}</span>
|
||||||
|
</div>
|
||||||
|
<span className="font-mono text-sm font-bold text-green-600 dark:text-[#39ff14] shrink-0">{fmt(row.amount)}</span>
|
||||||
|
</div>
|
||||||
|
{/* Role */}
|
||||||
|
<div className="mt-2.5">
|
||||||
|
<span className={`text-[11px] font-bold rounded-md px-1.5 py-0.5 border ${ROLE_COLORS[row.role] || 'text-zinc-400 bg-zinc-500/10 border-zinc-500/20'}`}>
|
||||||
|
{row.role}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* Project / Type */}
|
||||||
|
<div className="grid grid-cols-2 gap-2 mt-3 pt-3 border-t border-zinc-100 dark:border-white/5">
|
||||||
|
<div className="flex flex-col gap-0.5 min-w-0">
|
||||||
|
<span className="text-[9px] font-mono font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest">Project ID</span>
|
||||||
|
<span className="text-[11px] font-mono text-zinc-500 dark:text-zinc-400 truncate">{row.projectId}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-0.5 min-w-0">
|
||||||
|
<span className="text-[9px] font-mono font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest">Commission Type</span>
|
||||||
|
<span className="text-[11px] text-zinc-600 dark:text-zinc-400 truncate">{row.commissionType}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{/* Total */}
|
||||||
|
<div className="rounded-xl border border-zinc-300 dark:border-white/10 bg-zinc-50 dark:bg-white/[0.03] px-3.5 py-3 flex items-center justify-between">
|
||||||
|
<span className="text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">
|
||||||
|
{hasActiveFilters ? 'Filtered Total' : 'Total'}
|
||||||
|
</span>
|
||||||
|
<span className="font-mono text-sm font-extrabold text-green-600 dark:text-[#39ff14]">{fmt(total)}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -393,8 +393,9 @@ const TeamManagementPanel = ({
|
|||||||
transition={{ duration: 0.25 }}
|
transition={{ duration: 0.25 }}
|
||||||
className="overflow-hidden"
|
className="overflow-hidden"
|
||||||
>
|
>
|
||||||
<div className="overflow-x-auto rounded-xl border border-zinc-200 dark:border-white/5">
|
{/* ── Desktop table (sm+) ── */}
|
||||||
<table className="w-full text-left">
|
<div className="hidden sm:block overflow-x-auto rounded-xl border border-zinc-200 dark:border-white/5">
|
||||||
|
<table className="w-full text-left min-w-[560px]">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-zinc-200 dark:border-white/5 bg-zinc-50 dark:bg-white/[0.02]">
|
<tr className="border-b border-zinc-200 dark:border-white/5 bg-zinc-50 dark:bg-white/[0.02]">
|
||||||
<th className="px-4 py-2.5 text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">Member</th>
|
<th className="px-4 py-2.5 text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">Member</th>
|
||||||
@@ -419,17 +420,17 @@ const TeamManagementPanel = ({
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<span className={`text-[11px] font-bold rounded-md px-1.5 py-0.5 border ${ROLE_COLORS[mc.jobRole] || 'text-zinc-400 bg-zinc-500/10 border-zinc-500/20'}`}>
|
<span className={`text-[11px] font-bold rounded-md px-1.5 py-0.5 border whitespace-nowrap ${ROLE_COLORS[mc.jobRole] || 'text-zinc-400 bg-zinc-500/10 border-zinc-500/20'}`}>
|
||||||
{mc.jobRole}
|
{mc.jobRole}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 text-xs text-zinc-600 dark:text-zinc-400">{COMMISSION_TYPES[mc.resolved.type] || mc.resolved.type}</td>
|
<td className="px-4 py-3 text-xs text-zinc-600 dark:text-zinc-400 whitespace-nowrap">{COMMISSION_TYPES[mc.resolved.type] || mc.resolved.type}</td>
|
||||||
<td className="px-4 py-3 text-right font-mono text-xs text-zinc-900 dark:text-white">
|
<td className="px-4 py-3 text-right font-mono text-xs text-zinc-900 dark:text-white whitespace-nowrap">
|
||||||
{mc.resolved.type === 'flat' || mc.resolved.type === 'custom'
|
{mc.resolved.type === 'flat' || mc.resolved.type === 'custom'
|
||||||
? formatCurrency(mc.resolved.rate)
|
? formatCurrency(mc.resolved.rate)
|
||||||
: `${mc.resolved.rate}%`}
|
: `${mc.resolved.rate}%`}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 text-right font-mono text-xs font-bold text-green-600 dark:text-[#39ff14]">
|
<td className="px-4 py-3 text-right font-mono text-xs font-bold text-green-600 dark:text-[#39ff14] whitespace-nowrap">
|
||||||
{formatCurrency(mc.value)}
|
{formatCurrency(mc.value)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 text-center">
|
<td className="px-4 py-3 text-center">
|
||||||
@@ -445,7 +446,7 @@ const TeamManagementPanel = ({
|
|||||||
<tfoot className="border-t-2 border-zinc-300 dark:border-white/10">
|
<tfoot className="border-t-2 border-zinc-300 dark:border-white/10">
|
||||||
<tr className="bg-zinc-50 dark:bg-white/[0.03]">
|
<tr className="bg-zinc-50 dark:bg-white/[0.03]">
|
||||||
<td colSpan={4} className="px-4 py-3 text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">Total Distribution</td>
|
<td colSpan={4} className="px-4 py-3 text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">Total Distribution</td>
|
||||||
<td className="px-4 py-3 text-right font-mono text-xs font-bold text-green-600 dark:text-[#39ff14]">
|
<td className="px-4 py-3 text-right font-mono text-xs font-bold text-green-600 dark:text-[#39ff14] whitespace-nowrap">
|
||||||
{formatCurrency(memberCommissions.filter(m => m.status === 'active').reduce((s, mc) => s + mc.value, 0))}
|
{formatCurrency(memberCommissions.filter(m => m.status === 'active').reduce((s, mc) => s + mc.value, 0))}
|
||||||
</td>
|
</td>
|
||||||
<td />
|
<td />
|
||||||
@@ -453,6 +454,62 @@ const TeamManagementPanel = ({
|
|||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* ── Mobile cards (< sm) ── */}
|
||||||
|
<div className="sm:hidden space-y-2.5">
|
||||||
|
{memberCommissions.filter(m => m.status === 'active').map((mc) => {
|
||||||
|
const srcCfg = COMMISSION_SOURCE_CFG[mc.resolved.source] || COMMISSION_SOURCE_CFG.org;
|
||||||
|
return (
|
||||||
|
<div key={mc.id} className="rounded-xl border border-zinc-200 dark:border-white/5 bg-white dark:bg-white/[0.02] p-3.5">
|
||||||
|
{/* Member + source */}
|
||||||
|
<div className="flex items-center justify-between gap-2">
|
||||||
|
<div className="flex items-center gap-2 min-w-0">
|
||||||
|
<div className="w-7 h-7 rounded-full bg-violet-500/15 flex items-center justify-center text-[11px] font-black text-violet-400 flex-shrink-0">
|
||||||
|
{mc.name?.[0]}
|
||||||
|
</div>
|
||||||
|
<span className="text-sm font-semibold text-zinc-900 dark:text-white truncate">{mc.name}</span>
|
||||||
|
</div>
|
||||||
|
<span className={`inline-flex items-center gap-1 text-[10px] font-bold rounded-full px-2 py-0.5 border shrink-0 ${srcCfg.bg}`}>
|
||||||
|
<span className={`w-1.5 h-1.5 rounded-full ${srcCfg.dot}`} />
|
||||||
|
<span className={srcCfg.color}>{srcCfg.label}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* Role */}
|
||||||
|
<div className="mt-2.5">
|
||||||
|
<span className={`text-[11px] font-bold rounded-md px-1.5 py-0.5 border ${ROLE_COLORS[mc.jobRole] || 'text-zinc-400 bg-zinc-500/10 border-zinc-500/20'}`}>
|
||||||
|
{mc.jobRole}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{/* Type / Rate / Value */}
|
||||||
|
<div className="grid grid-cols-3 gap-2 mt-3 pt-3 border-t border-zinc-100 dark:border-white/5">
|
||||||
|
<div className="flex flex-col gap-0.5">
|
||||||
|
<span className="text-[9px] font-mono font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest">Type</span>
|
||||||
|
<span className="text-[11px] text-zinc-700 dark:text-zinc-300">{COMMISSION_TYPES[mc.resolved.type] || mc.resolved.type}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-0.5">
|
||||||
|
<span className="text-[9px] font-mono font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest">Rate</span>
|
||||||
|
<span className="font-mono text-[11px] text-zinc-900 dark:text-white">
|
||||||
|
{mc.resolved.type === 'flat' || mc.resolved.type === 'custom'
|
||||||
|
? formatCurrency(mc.resolved.rate)
|
||||||
|
: `${mc.resolved.rate}%`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col gap-0.5">
|
||||||
|
<span className="text-[9px] font-mono font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest">Value</span>
|
||||||
|
<span className="font-mono text-[11px] font-bold text-green-600 dark:text-[#39ff14]">{formatCurrency(mc.value)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{/* Total */}
|
||||||
|
<div className="rounded-xl border border-zinc-300 dark:border-white/10 bg-zinc-50 dark:bg-white/[0.03] px-3.5 py-3 flex items-center justify-between">
|
||||||
|
<span className="text-[10px] font-mono font-bold text-zinc-500 uppercase tracking-widest">Total Distribution</span>
|
||||||
|
<span className="font-mono text-sm font-bold text-green-600 dark:text-[#39ff14]">
|
||||||
|
{formatCurrency(memberCommissions.filter(m => m.status === 'active').reduce((s, mc) => s + mc.value, 0))}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|||||||
Reference in New Issue
Block a user