Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions app/action/[userId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ function ContributeFlow({ contribution, onSuccess }: { contribution: MyContribut
const [step, setStep] = useState<Step>('idle');
const [amount, setAmount] = useState('');
const [pin, setPin] = useState('');
const [isAnonymous, setIsAnonymous] = useState(false);

const fixedAmount = Number(contribution.amountPerMember);

Expand All @@ -170,16 +171,16 @@ function ContributeFlow({ contribution, onSuccess }: { contribution: MyContribut
}
setStep('loading');
try {
await contributeToGroup(contribution.groupId, contribution.id, payAmount, pin);
await contributeToGroup(contribution.groupId, contribution.id, payAmount, pin, isAnonymous);
onSuccess(payAmount);
setStep('idle'); setPin(''); setAmount('');
setStep('idle'); setPin(''); setAmount(''); setIsAnonymous(false);
} catch (err: any) {
alert(err?.response?.data?.message || 'Contribution failed');
setStep(contribution.type === 'fixed' ? 'enter_pin' : 'enter_amount');
}
};

const cancel = () => { setStep('idle'); setPin(''); setAmount(''); };
const cancel = () => { setStep('idle'); setPin(''); setAmount(''); setIsAnonymous(false); };

if (step === 'idle') return (
<Button size="sm" className="h-8 text-xs bg-[#00B512] hover:bg-[#009a0f] text-white"
Expand All @@ -204,16 +205,22 @@ function ContributeFlow({ contribution, onSuccess }: { contribution: MyContribut
);

if (step === 'enter_pin') return (
<div className="flex flex-col sm:flex-row sm:items-center gap-2 w-full">
<div className="flex items-center gap-2">
<div className="flex items-center gap-1 text-xs text-gray-500"><Lock size={11} /><span>PIN</span></div>
<Input type="password" inputMode="numeric" maxLength={4} placeholder="••••"
value={pin} onChange={(e) => setPin(e.target.value.replace(/\D/g, '').slice(0, 4))}
className="h-8 text-xs w-full sm:w-20 min-w-0 tracking-widest" autoFocus />
</div>
<div className="flex gap-2">
<Button size="sm" variant="outline" className="h-8 text-xs flex-1 sm:flex-none" onClick={cancel}>Cancel</Button>
<Button size="sm" className="h-8 text-xs flex-1 sm:flex-none bg-[#00B512] hover:bg-[#009a0f] text-white" onClick={handlePay}>Pay</Button>
<div className="flex flex-col gap-2 w-full">
<label className="flex items-center gap-1.5 text-[11px] text-gray-500 cursor-pointer select-none">
<input type="checkbox" checked={isAnonymous} onChange={(e) => setIsAnonymous(e.target.checked)} className="h-3 w-3" />
Contribute anonymously
</label>
<div className="flex flex-col sm:flex-row sm:items-center gap-2 w-full">
<div className="flex items-center gap-2">
<div className="flex items-center gap-1 text-xs text-gray-500"><Lock size={11} /><span>PIN</span></div>
<Input type="password" inputMode="numeric" maxLength={4} placeholder="••••"
value={pin} onChange={(e) => setPin(e.target.value.replace(/\D/g, '').slice(0, 4))}
className="h-8 text-xs w-full sm:w-20 min-w-0 tracking-widest" autoFocus />
</div>
<div className="flex gap-2">
<Button size="sm" variant="outline" className="h-8 text-xs flex-1 sm:flex-none" onClick={cancel}>Cancel</Button>
<Button size="sm" className="h-8 text-xs flex-1 sm:flex-none bg-[#00B512] hover:bg-[#009a0f] text-white" onClick={handlePay}>Pay</Button>
</div>
</div>
</div>
);
Expand Down Expand Up @@ -287,7 +294,7 @@ function ContributionCard({ contribution: initial, currentUserId }: { contributi
const progress = goal > 0 ? Math.min((collected / goal) * 100, 100) : 0;
const isActive = c.status === 'active';
const hasPaid = !!c.myPayment;
const canContribute = isActive && !hasPaid;
const canContribute = isActive;
const isDeadlinePast = c.deadline && new Date(c.deadline) < new Date();

useEffect(() => {
Expand Down Expand Up @@ -1845,7 +1852,7 @@ const ActionsByAccountPage = () => {
{/* ── ROW 3: Public Campaigns ── */}
{!isViewingAnotherUser && (
<div>
<div className="flex items-center gap-3 mb-3">
<div className="flex flex-wrap items-center gap-3 mb-3">
<Globe2 size={16} className="text-[#00B512]" />
<span className="text-sm font-bold text-[#00313A] dark:text-white uppercase tracking-widest">My Campaigns</span>
<span className="text-xs text-gray-400 dark:text-gray-500">{visibleCampaigns.length}</span>
Expand All @@ -1854,7 +1861,7 @@ const ActionsByAccountPage = () => {
{activeCampaigns.length} active
</span>
)}
<div className="ml-auto flex items-center gap-1.5">
<div className="w-full sm:w-auto sm:ml-auto flex flex-wrap items-center gap-1.5">
{(['all', 'active', 'closed'] as const).map((f) => (
<button key={f} onClick={() => setCampaignsFilter(f)}
className={`px-2.5 py-1 rounded-full text-[11px] font-semibold capitalize transition-colors ${
Expand All @@ -1867,7 +1874,7 @@ const ActionsByAccountPage = () => {
<ScrollBtns s={campaignsScroll} />
<button
onClick={() => setCreateCampaignOpen(true)}
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold bg-[#00B512] hover:bg-[#009a0f] text-white transition-colors"
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-semibold bg-[#00B512] hover:bg-[#009a0f] text-white transition-colors whitespace-nowrap"
>
<Plus size={12} />
New Campaign
Expand Down
4 changes: 2 additions & 2 deletions app/contacts/components/ContactDetailsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export function ContactDetailsPanel({ contact, isOpen, onClose }: ContactDetails
className="absolute bottom-0 right-0 bg-white dark:bg-darkBg-card rounded-full p-1.5 shadow-sm border border-gray-100 dark:border-darkBorder-light hover:bg-gray-50 dark:hover:bg-darkBg-hover transition-colors"
title={contact.isFavorite ? "Remove from favorites" : "Add to favorites"}
>
<Star className={cn("h-4 w-4", contact.isFavorite ? "text-yellow-500 fill-yellow-500" : "text-gray-400")} />
<Star className={cn("h-4 w-4", contact.isFavorite ? "text-yellow-500 fill-yellow-500" : "text-gray-400 dark:text-gray-500")} />
</button>
</div>

Expand All @@ -195,7 +195,7 @@ export function ContactDetailsPanel({ contact, isOpen, onClose }: ContactDetails
className="h-5 w-5 p-0 rounded-full hover:bg-gray-100 dark:hover:bg-darkBg-hover"
title="Manage tags"
>
<Edit className="h-3 w-3 text-gray-400" />
<Edit className="h-3 w-3 text-gray-400 dark:text-gray-500" />
</Button>
</div>

Expand Down
6 changes: 3 additions & 3 deletions app/contacts/components/ContactsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,17 @@ export function ContactsTable({ contacts, isLoading, onSelect }: ContactsTablePr

if (isLoading) {
return (
<div className="p-8 text-center text-gray-500">
<div className="p-8 text-center text-gray-500 dark:text-gray-400">
Loading contacts...
</div>
);
}

if (contacts.length === 0) {
return (
<div className="p-12 text-center text-gray-500">
<div className="p-12 text-center text-gray-500 dark:text-gray-400">
<div className="mb-4">
<div className="h-12 w-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto text-gray-400">
<div className="h-12 w-12 bg-gray-100 dark:bg-darkBg-interactive rounded-full flex items-center justify-center mx-auto text-gray-400 dark:text-gray-500">
<span className="text-xl">?</span>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/contacts/components/PendingRequestsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ export function PendingRequestsTable({ requests, isLoading }: PendingRequestsTab

if (isLoading) {
return (
<div className="p-8 text-center text-gray-500">
<div className="p-8 text-center text-gray-500 dark:text-gray-400">
Loading sent requests...
</div>
);
}

if (requests.length === 0) {
return (
<div className="p-12 text-center text-gray-500">
<div className="p-12 text-center text-gray-500 dark:text-gray-400">
<div className="mb-4">
<div className="h-12 w-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto text-gray-400">
<div className="h-12 w-12 bg-gray-100 dark:bg-darkBg-interactive rounded-full flex items-center justify-center mx-auto text-gray-400 dark:text-gray-500">
<span className="text-xl">Inbox</span>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/contacts/components/SentRequestsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ export function SentRequestsTable({ requests, isLoading }: SentRequestsTableProp

if (isLoading) {
return (
<div className="p-8 text-center text-gray-500">
<div className="p-8 text-center text-gray-500 dark:text-gray-400">
Loading pending requests...
</div>
);
}

if (requests.length === 0) {
return (
<div className="p-12 text-center text-gray-500">
<div className="p-12 text-center text-gray-500 dark:text-gray-400">
<div className="mb-4">
<div className="h-12 w-12 bg-gray-100 rounded-full flex items-center justify-center mx-auto text-gray-400">
<div className="h-12 w-12 bg-gray-100 dark:bg-darkBg-interactive rounded-full flex items-center justify-center mx-auto text-gray-400 dark:text-gray-500">
<span className="text-xl">Outbox</span>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/contacts/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ function ContactsPageInner() {
</DropdownMenu>
</div>

<div className="flex-1 overflow-y-auto space-y-8 pr-2">
<div className="flex-1 overflow-y-auto space-y-8 pr-2 mobile-bottom-padding">
{(activeTab === 'normal' || activeTab === 'companies' || activeTab === 'persons') && (
<>
{/* Favorites Section */}
Expand Down
2 changes: 1 addition & 1 deletion app/groups/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export default function GroupsPage() {
</div>

{/* Group list */}
<div className="flex-1 overflow-y-auto pr-1">
<div className="flex-1 overflow-y-auto pr-1 mobile-bottom-padding">
<div className="bg-white dark:bg-darkBg-card rounded-xl shadow-sm border border-gray-200 dark:border-darkBorder-light overflow-hidden">
{filteredGroups.length === 0 ? (
<div className="flex flex-col items-center justify-center py-16 px-6 text-center">
Expand Down
26 changes: 13 additions & 13 deletions app/home/requests/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ export default function RequestsPage() {

return (
<Card className="p-4 mb-3 hover:shadow-md transition-all border-gray-100 dark:border-darkBorder-light bg-white dark:bg-darkBg-card">
<div className="flex items-center justify-between gap-4">
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 sm:gap-4">
<div className="flex items-center gap-3 flex-1 min-w-0">
<UserAvatar
<UserAvatar
profileImage={(otherParty as any)?.profile?.profileImage || otherParty?.profile?.avatar}
firstName={otherParty?.firstName}
lastName={otherParty?.lastName}
userId={otherParty?.id}
className="h-10 w-10 flex-shrink-0"
className="h-10 w-10 flex-shrink-0"
/>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
Expand All @@ -136,31 +136,31 @@ export default function RequestsPage() {
</p>
</div>
</div>
<div className="text-right flex flex-col items-end gap-2">
<div className="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-1">

<div className="flex flex-col items-stretch sm:items-end gap-2 sm:flex-shrink-0">
<div className="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-1 whitespace-nowrap sm:self-end">
{type === 'received' ? (
<ArrowDownLeft size={16} className="text-red-500" />
) : (
<ArrowUpRight size={16} className="text-green-500" />
)}
{request.amount.toLocaleString()} {request.currency}
</div>

{type === 'received' && isPending && (
<div className="flex items-center gap-2">
<Button
size="sm"
<Button
size="sm"
variant="outline"
className="h-8"
className="h-8 flex-1 sm:flex-none"
disabled={processingRequestId === request.id}
onClick={() => handleDeclineRequest(request.id)}
>
Decline
</Button>
<Button
size="sm"
className={`${accent.solidDark} text-white h-8`}
<Button
size="sm"
className={`${accent.solidDark} text-white h-8 flex-1 sm:flex-none`}
onClick={() => router.push(`/home/transfer/amount?requestId=${request.id}`)}
>
Pay Now
Expand Down
2 changes: 1 addition & 1 deletion app/welcome/[userId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1509,7 +1509,7 @@ const WelcomeProfilePage: React.FC = () => {
<>
{isHydrated && isLoggedIn && <Header />}
<div className={`min-h-screen ${accent.bgPage}`}>
<div className="max-w-5xl mx-auto px-3 sm:px-4 py-4 sm:py-8 space-y-4 sm:space-y-5">
<div className="max-w-5xl mx-auto px-3 sm:px-4 py-4 sm:py-8 space-y-4 sm:space-y-5 mobile-bottom-padding">

{/* Profile header card */}
<div className={`rounded-2xl p-4 sm:p-6 md:p-8 ${accent.bgCard}`}>
Expand Down
Loading
Loading