Skip to content

Commit

Permalink
refactor(website): update donation payment flow (#630)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkue authored Nov 14, 2023
1 parent 2bac9af commit 8f64f06
Show file tree
Hide file tree
Showing 19 changed files with 468 additions and 244 deletions.
35 changes: 35 additions & 0 deletions shared/locales/de/website-donate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"amount-currency": "{{ amount, currency }}",
"title": "Was ist dein durchschnittliches monatliches Einkommen?",
"how-to-pay": "Wie möchtest du bezahlen?",
"amount": "Betrag",
"button-text": "Einen Unterschied machen",
"donation-impact": {
"monthly-contribution": "Dein monatlicher Beitrag:",
"direct-payout": "Dein Beitrag wird direkt auf das Mobiltelefon der Social Income Empfänger:innen ausgezahlt.",
"your-impact": "Dein Einfluss:",
"0": "{{ amount, currency }} legt den Grundstein für eine bedeutende Sache. Es ermöglicht uns, einer Person in Not ein Social Income zu bieten.",
"1": "{{ amount, currency }} deckt mehr als ein Drittel eines Social Incomes für eine bedürftige Person.",
"2": "{{ amount, currency }} finanziert mehr als die Hälfte eines Social Incomes für eine Person.",
"3": "Großartig! Dein monatlicher Beitrag von {{ amount, currency }} ermöglicht es mindestens einer bedürftigen Person ein vollständiges Social Income bereitzustellen.",
"4": "{{ amount, currency }} ermöglicht ein Social Income für mehr als zwei bedürftige Personen.",
"5": "Wunderbar! Dein Beitrag von {{ amount, currency }} finanziert ein Social Income für mehr als drei bedürftige Personen.",
"6": "Dein Beitrag von {{ amount, currency }} sichert ein Social Income für mehr als vier bedürftige Personen.",
"7": "Dein Beitrag von {{ amount, currency }} sichert ein Social Income für mehr als fünf bedürftige Personen.",
"8": "Dein monatlicher Beitrag von {{ amount, currency }} ist außergewöhnlich, ebenso wie dein Einfluss."
},
"donation-interval": {
"1": {
"title": "Monatlich",
"text": "{{ amount, currency }} jeden Monat zahlen"
},
"3": {
"title": "Quartalsweise",
"text": "{{ amount, currency }} alle 3 Monate zahlen"
},
"12": {
"title": "Jährlich",
"text": "{{ amount, currency }} jedes Jahr zahlen"
}
}
}
17 changes: 9 additions & 8 deletions shared/locales/de/website-me.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@
}
},
"contributions": {
"amount": "Amount",
"date": "Date",
"source": "Source",
"amount": "Betrag",
"date": "Datum",
"source": "Quelle",
"total": "Total",
"one-time-payment": "Neue einmalige Spende",
"amount-currency": "{{ amount, currency }}",
"sources": {
"benevity": "Benevity",
"cash": "Cash",
"cash": "Bar",
"stripe": "Stripe",
"wire-transfer": "Wire Transfer"
"wire-transfer": "Banküberweisung"
}
},
"subscriptions": {
"amount": "Amount",
"date": "Date",
"source": "Source",
"amount": "Betrag",
"date": "Datum",
"source": "Quelle",
"total": "Total",
"amount-currency": "{{ amount, currency }}",
"interval": "Interval",
Expand Down
35 changes: 35 additions & 0 deletions shared/locales/en/website-donate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"amount-currency": "{{ amount, currency }}",
"title": "What's your average monthly income?",
"how-to-pay": "How would you like to pay?",
"amount": "Amount",
"button-text": "Make a Difference",
"donation-impact": {
"monthly-contribution": "Your monthly contribution:",
"direct-payout": "The people in need receive your contribution directly on their mobile phones.",
"your-impact": "Your impact:",
"0": "{{ amount, currency }} lays the groundwork for a significant cause. It enables us to provide a Social Income to an individual facing hardship.",
"1": "{{ amount, currency }} pays for more than a third of a Social Income for one person in need.",
"2": "{{ amount, currency }} funds more than half of someone’s Social Income.",
"3": "Great! Your monthly contribution of {{ amount, currency }} will allow at least one person in need to receive a full Social Income.",
"4": "{{ amount, currency }} provides a Social Income for more than two people in need.",
"5": "Wonderful! Your contribution of {{ amount, currency }} funds a Social Income for more than three people in need.",
"6": "Your contribution of {{ amount, currency }} sustains a Social Income for more than four people in need.",
"7": "Your contribution of {{ amount, currency }} sustains a Social Income for more than five people in need.",
"8": "Your monthly contribution of {{ amount, currency }} is extraordinary, as well as your impact."
},
"donation-interval": {
"1": {
"title": "Monthly",
"text": "Pay {{ amount, currency }} every month"
},
"3": {
"title": "Quarterly",
"text": "Pay {{ amount, currency }} every 3 months"
},
"12": {
"title": "Yearly",
"text": "Pay {{ amount, currency }} every year"
}
}
}
1 change: 1 addition & 0 deletions shared/locales/en/website-me.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"date": "Date",
"source": "Source",
"total": "Total",
"one-time-payment": "New one-time donation",
"amount-currency": "{{ amount, currency }}",
"sources": {
"benevity": "Benevity",
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
const Comp = asChild ? Slot : 'button';
return (
<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props}>
{Icon && <Icon className={cn('h-4 w-4', { 'mr-2': size !== 'icon' })} />}
{Icon && <Icon className={cn('h-4 w-4', { 'mr-2': size !== 'icon', 'h-6 w-6': size === 'lg' })} />}
{children}
</Comp>
);
Expand Down
21 changes: 7 additions & 14 deletions ui/src/components/typography/typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const FONT_COLOR_MAP: { [key in FontColor]: string } = {
'destructive-foreground': 'text-destructive-foreground',
muted: 'text-muted',
'muted-foreground': 'text-muted-foreground',
card: 'text-card',
'card-foreground': 'text-card-foreground',
popover: 'text-popover',
'popover-foreground': 'text-popover-foreground',
};
Expand All @@ -67,26 +69,17 @@ export type TypographyProps<C extends ElementType> = {
} & ComponentPropsWithoutRef<C>;

export function Typography<C extends ElementType = 'p'>(
{
as,
size = 'md',
weight = 'normal',
color = 'foreground',
lineHeight = 'normal',
className,
children,
...props
}: TypographyProps<C>,
{ as, size, weight, color, lineHeight, className, children, ...props }: TypographyProps<C>,
) {
const Component = as || 'p';
return (
<Component
className={twMerge(
classNames(
FONT_SIZE_MAP[size],
FONT_WEIGHT_MAP[weight],
FONT_COLOR_MAP[color],
LINE_HEIGHT_MAP[lineHeight],
size && FONT_SIZE_MAP[size],
weight && FONT_WEIGHT_MAP[weight],
color && FONT_COLOR_MAP[color],
lineHeight && LINE_HEIGHT_MAP[lineHeight],
className,
),
)}
Expand Down
3 changes: 3 additions & 0 deletions ui/src/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
--background: hsl(216, 54%, 55%);
--foreground: hsl(60 9.1% 97.8%);

--card: hsl(216, 54%, 95%);
--card-foreground: hsl(0, 0%, 10%);

--primary: hsl(48, 100%, 49%);
--primary-foreground: hsl(0, 0%, 20%);
}
Expand Down
2 changes: 2 additions & 0 deletions ui/src/interfaces/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export type FontColor = Extract<
| 'muted-foreground'
| 'accent'
| 'accent-foreground'
| 'card'
| 'card-foreground'
| 'popover'
| 'popover-foreground'
>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function Section1Form({ translations, lang, region }: Section1Inp
});

const onSubmit = (values: FormSchema) => {
router.push(`/donate/individual?amount=${(Number(values.amount) / 100).toFixed(2)}`);
router.push(`/${lang}/${region}/donate/individual?amount=${Number(values.amount).toFixed(0)}`);
};

return (
Expand All @@ -51,7 +51,7 @@ export default function Section1Form({ translations, lang, region }: Section1Inp
control={form.control}
name="amount"
render={({ field }) => (
<FormItem className="sm:basis-2/3">
<FormItem className="flex-1">
<FormControl>
<Input className="h-16 text-lg" placeholder={translations.amount} {...field} />
</FormControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ const groups: Group[] = [
export default async function Team({ params }: DefaultPageProps) {
const translator = await Translator.getInstance({ language: params.lang, namespaces: ['countries', 'website-team'] });
return (
<BaseContainer className="py-8">
<BaseContainer id="team" className="py-8">
<Typography as="h3" size="xl" color="muted-foreground" className="mb-4">
{translator.t('header')}
</Typography>
Expand Down
17 changes: 13 additions & 4 deletions website/src/app/[lang]/[region]/(website)/me/payments/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { DefaultPageProps } from '@/app/[lang]/[region]';
import { ContributionsTable } from '@/app/[lang]/[region]/(website)/me/payments/contributions-table';
import { PlusCircleIcon } from '@heroicons/react/24/outline';
import { Translator } from '@socialincome/shared/src/utils/i18n';
import { Button } from '@socialincome/ui';
import Link from 'next/link';

export default async function Page({ params }: DefaultPageProps) {
const translator = await Translator.getInstance({ language: params.lang, namespaces: ['website-me'] });
export default async function Page({ params: { lang, region } }: DefaultPageProps) {
const translator = await Translator.getInstance({ language: lang, namespaces: ['website-me'] });

return (
<div className="grid grid-cols-1 gap-4">
<div className="flex flex-col">
<ContributionsTable
lang={lang}
region={region}
translations={{
date: translator.t('contributions.date'),
amount: translator.t('contributions.amount'),
source: translator.t('contributions.source'),
}}
{...params}
/>
<Link href={`/${lang}/${region}/donate/one-time`}>
<Button Icon={PlusCircleIcon} variant="ghost" size="lg" className="w-full">
{translator.t('contributions.one-time-payment')}
</Button>
</Link>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem>
<FormLabel>First name</FormLabel>
<FormControl>
<Input type="text" placeholder="First name" {...field} />
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -124,7 +124,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem>
<FormLabel>Last name</FormLabel>
<FormControl>
<Input type="text" placeholder="Last name" {...field} />
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -137,7 +137,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="Email" {...field} />
<Input type="email" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand Down Expand Up @@ -173,7 +173,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem className="flex w-3/4 flex-col">
<FormLabel>Street</FormLabel>
<FormControl>
<Input type="text" placeholder="street" {...field} />
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -186,7 +186,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem className="flex w-1/4 flex-col">
<FormLabel>Number</FormLabel>
<FormControl>
<Input type="text" placeholder="streetNumber" {...field} />
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -201,7 +201,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem className="flex w-1/4 flex-col">
<FormLabel>Zip</FormLabel>
<FormControl>
<Input type="number" placeholder="zip" {...field} />
<Input type="number" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -214,7 +214,7 @@ export default function Page({ params }: DefaultPageProps) {
<FormItem className="flex w-3/4 flex-col">
<FormLabel>City</FormLabel>
<FormControl>
<Input type="text" placeholder="city" {...field} />
<Input type="text" {...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -226,7 +226,7 @@ export default function Page({ params }: DefaultPageProps) {
name="language"
render={({ field }) => (
<FormItem>
<FormLabel>Language</FormLabel>
<FormLabel>Communication Language</FormLabel>
<Select onValueChange={field.onChange}>
<FormControl>
<SelectTrigger>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { User, USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user';
import { useQuery } from '@tanstack/react-query';
import assert from 'assert';
import { collection, getDocs, query, QueryDocumentSnapshot, where } from 'firebase/firestore';
import { redirect } from 'next/navigation';
import { createContext, PropsWithChildren, useContext, useEffect } from 'react';
Expand All @@ -18,27 +17,31 @@ export const useUserContext = () => useContext(UserContext);

export function UserContextProvider({ children }: PropsWithChildren) {
const firestore = useFirestore();
const { data: authUser } = useUser();

const { data: authUser, status: authUserStatus } = useUser();
const { data: user, refetch } = useQuery({
queryKey: ['UserContextProvider', authUser?.uid, firestore],
queryFn: async () => {
if (authUser?.uid && firestore) {
let snapshot = await getDocs(
query(collection(firestore, USER_FIRESTORE_PATH), where('authUserId', '==', authUser?.uid)),
);
assert(snapshot.size === 1);
return snapshot.docs[0] as QueryDocumentSnapshot<User>;
} else return null;
if (snapshot.size === 1) {
return snapshot.docs[0] as QueryDocumentSnapshot<User>;
}
return null;
}
return null;
},
staleTime: 1000 * 60 * 60, // 1 hour
});

useEffect(() => {
if (user === null) {
if (user === null && authUserStatus === 'success') {
// If the user is null, it couldn't be found in the database, so redirect to the login page.
// If the user is undefined, the query is still loading, so no redirect.
redirect('../login');
}
}, [user]);
}, [user, authUserStatus]);

if (user) {
return <UserContext.Provider value={{ user, refetch }}>{children}</UserContext.Provider>;
Expand Down
Loading

0 comments on commit 8f64f06

Please sign in to comment.