diff --git a/shared/locales/de/website-about-us.json b/shared/locales/de/website-about-us.json index ce5a102ed..286e9a1a2 100644 --- a/shared/locales/de/website-about-us.json +++ b/shared/locales/de/website-about-us.json @@ -2,5 +2,40 @@ "section-1": { "title-1": "Etwas bewegen, nicht nur darüber sprechen. ", "title-2": "Dies war der Anfang von Social Income." + }, + "team": { + "header": "Unser Team", + "title-1": "Wir verhelfen Social Income ", + "title-2": "zur Realität.", + "roles": { + "finance": "Finanzen", + "operations": "Betrieb", + "marketing": "Marketing", + "communications": "Kommunikation", + "co-president": "Co-Präsident:in", + "founder": "Gründer", + "board-member": "Vorstandsmitglied", + "software-development": "Softwareentwicklung", + "app-development": "App-Entwicklung", + "impact-measurement": "Impact Measurement" + }, + "groups": { + "staff": { + "name": "Mitarbeiter:innen", + "description": "Unsere Mitarbeiter:innen vor Ort in Sierra Leone." + }, + "volunteers": { + "name": "Freiwillige", + "description": "Die Menschen, die alles möglich machen." + }, + "board": { + "name": "Vorstand", + "description": "Die Aufsichtspersonen der Organisation." + }, + "special-thanks": { + "name": "Besonderer Dank", + "description": "Diese Personen haben sich großzügig ehrenamtlich eingesetzt und zu Social Income beigetragen." + } + } } } diff --git a/shared/locales/de/website-home.json b/shared/locales/de/website-home.json index cad6796c1..84b9b2de4 100644 --- a/shared/locales/de/website-home.json +++ b/shared/locales/de/website-home.json @@ -16,6 +16,7 @@ "video-button": "Schau dir das Video an", "vimeo-video-id": "488184818" }, + "section-3": {}, "section-4": { "title-1": "Soziale Gerechtigkeit fängt ", "title-2": " bei uns an.", diff --git a/shared/locales/de/website-team.json b/shared/locales/de/website-team.json deleted file mode 100644 index da55d8b30..000000000 --- a/shared/locales/de/website-team.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "header": "Unser Team", - "title-1": "Wir verhelfen Social Income ", - "title-2": "zur Realität.", - "roles": { - "finance": "Finanzen", - "operations": "Betrieb", - "marketing": "Marketing", - "communications": "Kommunikation", - "co-president": "Co-Präsident:in", - "founder": "Gründer", - "board-member": "Vorstandsmitglied", - "software-development": "Softwareentwicklung", - "app-development": "App-Entwicklung", - "impact-measurement": "Impact Measurement" - }, - "groups": { - "staff": { - "name": "Mitarbeiter:innen", - "description": "Unsere Mitarbeiter:innen vor Ort in Sierra Leone." - }, - "volunteers": { - "name": "Freiwillige", - "description": "Die Menschen, die alles möglich machen." - }, - "board": { - "name": "Vorstand", - "description": "Die Aufsichtspersonen der Organisation." - }, - "special-thanks": { - "name": "Besonderer Dank", - "description": "Diese Personen haben sich großzügig ehrenamtlich eingesetzt und zu Social Income beigetragen." - } - } -} diff --git a/shared/locales/en/website-about-us.json b/shared/locales/en/website-about-us.json index 15074691e..b0e2b4060 100644 --- a/shared/locales/en/website-about-us.json +++ b/shared/locales/en/website-about-us.json @@ -1,6 +1,129 @@ { - "section-1": { - "title-1": "We wanted to act. We found a way to do it. ", - "title-2": "Social Income was born." - } + "landing-page": { + "title": [ + { + "text": "We wanted to act. We found a way to do it. " + }, + { + "text": "Social Income was born.", + "color": "secondary" + } + ] + }, + "our-mission": { + "header": "Our Mission", + "title": [ + { + "text": "Fighting global poverty with the " + }, + { + "text": "help of everyday people.", + "color": "secondary" + } + ], + "subtitle": "Many people in wealthier countries are committed to addressing inequality, but don’t know how or where to start.", + "paragraphs": [ + "Thanks to the widespread use of mobile phone-based money transfer services in developing countries, it is easier than ever to send money directly to people in need, at almost no cost.", + "Social Income wants to harness this potential by combining two approaches to wealth redistribution. The first is the concept of Universal Basic Income, which is a promising path towards a more equal and inclusive society.", + "The second is the use of direct and anticipatory cash transfers to people living in poverty. Research has shown that those who receive direct aid greatly benefit from the money and that they reinvest it locally, responsibly, and successfully.", + "We make an impact by sending regular long-term cash transfers directly to recipients: from person to person, because many of the world's poorest countries lack solid social infrastructure.", + "And we do so in a radically transparent way that allows us to avoid the high administrative costs normally associated with such projects." + ] + }, + "100-percent-model": { + "header": "100% Model", + "title": [ + { + "text": "Zero overhead costs. " + }, + { + "text": "Our pledge to you.", + "color": "secondary" + } + ], + "paragraphs": [ + "We believe that 100% of our contributors’ donations should go to our recipients. To maintain this promise, all our operating costs and financial expenses are covered by philanthropic grants and institutional donations.", + "Thanks to this support, we can guarantee that 100% of the money from our individual contributors reaches our recipients.", + "Additionally, we receive various in-kind support from organizations, such as Google Non-profit or Lineto (Unica77 font). Thank you!" + ] + }, + "flow-of-funds": { + "header": "Flow of Funds", + "title": [ + { + "text": "Social Income payments are sent directly to " + }, + { + "text": "recipients’ mobile phones.", + "color": "secondary" + } + ], + "paragraphs": [ + "We receive contributions from all over the world. They are safely stored in our bank account, in the most stable currency in the world: Swiss Francs. Every month we transfer just enough money to local banks in the countries where we are active. We then distribute Social Incomes with the help of mobile money directly to the phones of beneficiaries." + ], + "vimeo-video-id": "840215695" + }, + "team": { + "header": "Our Team", + "title": [ + { + "text": "We're making Social Income " + }, + { + "text": "a reality.", + "color": "secondary" + } + ], + "roles": { + "finance": "Finances", + "operations": "Operations", + "marketing": "Marketing", + "communications": "Communications", + "co-president": "Co-President", + "founder": "Founder", + "board-member": "Board Member", + "software-development": "Software Development", + "app-development": "App Development", + "impact-measurement": "Impact Measurement", + "strategy": "Strategy" + }, + "groups": { + "staff": { + "name": "Staff", + "description": "Our local staff in Sierra Leone." + }, + "volunteers": { + "name": "Volunteers", + "description": "The people who make it all happen." + }, + "board": { + "name": "Board of Association", + "description": "The overseers of the organization." + }, + "special-thanks": { + "name": "Special Thanks", + "description": "These individuals have volunteered and made generous contributions towards Social Income." + } + } + }, + "contact": { + "header": "Contact", + "title": [ + { + "text": "We're a Swiss " + }, + { + "text": "non-profit organization.", + "color": "secondary" + } + ], + "paragraph": "Social Income was founded as a non-profit association in Zurich, Switzerland. An independent board oversees the organization.", + "legal-status": "Legal Status", + "legal-status-paragraphs": [ + "Non-profit organization founded under Swiss law in 2019 with tax exempt status.", + "UID: CHE-289.611.695", + "DUNS: 48-045-6376" + ], + "find-us": "Find us on" + } } diff --git a/shared/locales/en/website-home.json b/shared/locales/en/website-home.json index ea498d7d1..fb934c965 100644 --- a/shared/locales/en/website-home.json +++ b/shared/locales/en/website-home.json @@ -17,6 +17,18 @@ "video-button": "Watch the video", "vimeo-video-id": "433937157" }, + "section-3": { + "title": [{ "text": "Who should, if not us " }, { "text": "here in Switzerland?", "color": "secondary" }], + "jackpot-title": "Life in Switzerland is like winning the jackpot.", + "jackpot-text": "People in Switzerland have systematically more opportunities and higher chances of leading a life worth living than anywhere else in the world.", + "jackpot-button": "Share the love", + "helping-others-title": "Helping others makes us happier.", + "helping-others-text": "Let’s start by helping those who don’t have the privilege of leading a life without financial difficulties. If not now, when?", + "helping-others-button": "Take Action", + "together-title": "Together we can make a major difference.", + "together-text": "If every fourth person in Switzerland contributed 1% of their income, every citizen of Sierra Leone could receive universal basic income and make poverty a thing of the past.", + "together-button": "Lead the Way" + }, "section-4": { "title-1": "How can we address inequality? ", "title-2": " Ourselves.", diff --git a/shared/locales/en/website-team.json b/shared/locales/en/website-team.json deleted file mode 100644 index a6649d9e8..000000000 --- a/shared/locales/en/website-team.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "header": "Our Team", - "title-1": "We're making Social Income ", - "title-2": "a reality.", - "roles": { - "finance": "Finances", - "operations": "Operations", - "marketing": "Marketing", - "communications": "Communications", - "co-president": "Co-President", - "founder": "Founder", - "board-member": "Board Member", - "software-development": "Software Development", - "app-development": "App Development", - "impact-measurement": "Impact Measurement", - "strategy": "Strategy" - }, - "groups": { - "staff": { - "name": "Staff", - "description": "Our local staff in Sierra Leone." - }, - "volunteers": { - "name": "Volunteers", - "description": "The people who make it all happen." - }, - "board": { - "name": "Board of Association", - "description": "The overseers of the organization." - }, - "special-thanks": { - "name": "Special Thanks", - "description": "These individuals have volunteered and made generous contributions towards Social Income." - } - } -} diff --git a/shared/src/firebase/client/init.ts b/shared/src/firebase/client/init.ts index 9f97fd025..91f45f180 100644 --- a/shared/src/firebase/client/init.ts +++ b/shared/src/firebase/client/init.ts @@ -17,18 +17,16 @@ interface InitializeFirebaseClientProps { functionsEmulatorPort?: number; } -export const initializeFirebaseClient = ( - { - firebaseConfig, - authEmulatorUrl, - firestoreEmulatorHost, - firestoreEmulatorPort, - storageEmulatorHost, - storageEmulatorPort, - functionsEmulatorHost, - functionsEmulatorPort, - }: InitializeFirebaseClientProps, -) => { +export const initializeFirebaseClient = ({ + firebaseConfig, + authEmulatorUrl, + firestoreEmulatorHost, + firestoreEmulatorPort, + storageEmulatorHost, + storageEmulatorPort, + functionsEmulatorHost, + functionsEmulatorPort, +}: InitializeFirebaseClientProps) => { const app = getOrInitializeFirebaseClientApp(firebaseConfig); const auth = getAuth(app); const functions = getFunctions(app, DEFAULT_REGION); diff --git a/shared/src/utils/i18n.ts b/shared/src/utils/i18n.ts index 36a0eb7eb..45aae09b7 100644 --- a/shared/src/utils/i18n.ts +++ b/shared/src/utils/i18n.ts @@ -15,7 +15,7 @@ interface TranslatorProps { namespaces: string[] | string; } -export type TranslateFunction = (key: string, translateProps?: TranslateProps) => string; +export type TranslateFunction = (key: string, translateProps?: TranslateProps) => T; export class Translator { language: LanguageCode; @@ -40,6 +40,7 @@ export class Translator { lng: language, ns: namespaces, fallbackLng: FALLBACK_LANGUAGE, + returnObjects: true, interpolation: { escapeValue: false, }, @@ -47,11 +48,11 @@ export class Translator { return translator; } - public t: TranslateFunction = (key: string, translateProps?: TranslateProps) => { + public t: TranslateFunction = (key: string, translateProps?: TranslateProps): T => { return this.instance.t(key, { ns: translateProps?.namespace || this.namespaces, lng: translateProps?.language || this.language, ...translateProps?.context, - }); + }) as T; }; } diff --git a/shared/src/utils/messaging/email.ts b/shared/src/utils/messaging/email.ts index 3024783d8..631127674 100644 --- a/shared/src/utils/messaging/email.ts +++ b/shared/src/utils/messaging/email.ts @@ -16,9 +16,15 @@ interface SendEmailProps { password: string; } -export const sendEmail = async ( - { from = 'no-reply@socialincome.org', to, subject, content, attachments = [], user, password }: SendEmailProps, -) => { +export const sendEmail = async ({ + from = 'no-reply@socialincome.org', + to, + subject, + content, + attachments = [], + user, + password, +}: SendEmailProps) => { let transporter: Transporter; if (!user) { const testAccount = await nodemailer.createTestAccount(); diff --git a/shared/src/utils/messaging/whatsapp.ts b/shared/src/utils/messaging/whatsapp.ts index 6dd0c75c0..bde18e4ed 100644 --- a/shared/src/utils/messaging/whatsapp.ts +++ b/shared/src/utils/messaging/whatsapp.ts @@ -12,9 +12,12 @@ export interface SendWhatsappProps { templateProps: RenderTemplateProps; } -export const sendWhatsapp = async ( - { to, from, twilioConfig, templateProps }: SendWhatsappProps, -): Promise => { +export const sendWhatsapp = async ({ + to, + from, + twilioConfig, + templateProps, +}: SendWhatsappProps): Promise => { const client = new Twilio(twilioConfig.sid, twilioConfig.token); const body = await renderTemplate(templateProps); return client.messages.create({ body: body, from: `whatsapp:${from}`, to: `whatsapp:${to}` }); diff --git a/shared/src/utils/templates.ts b/shared/src/utils/templates.ts index f144fcb1e..0813fc103 100644 --- a/shared/src/utils/templates.ts +++ b/shared/src/utils/templates.ts @@ -28,9 +28,12 @@ const partials = [ ]; partials.forEach((partial) => Handlebars.registerPartial(partial.name, readHbs(partial.path))); -export const renderTemplate = async ( - { language, translationNamespace = [], hbsTemplatePath, context }: RenderTemplateProps, -) => { +export const renderTemplate = async ({ + language, + translationNamespace = [], + hbsTemplatePath, + context, +}: RenderTemplateProps) => { const i18n = i18next.createInstance(); await i18n .use( diff --git a/ui/CONTRIBUTING.md b/ui/CONTRIBUTING.md index f7a8867a8..b25c7d2f1 100644 --- a/ui/CONTRIBUTING.md +++ b/ui/CONTRIBUTING.md @@ -54,9 +54,11 @@ UI elements: **Example**: ```tsx - export const SoExampleComponent = ( - { children, exampleProperty, ...props }: SoExampleComponentProps, - ) => { + export const SoExampleComponent = ({ + children, + exampleProperty, + ...props + }: SoExampleComponentProps) => { return (

{children} diff --git a/ui/src/components/carousel.tsx b/ui/src/components/carousel.tsx index c1b9658b1..0aa33b9fd 100644 --- a/ui/src/components/carousel.tsx +++ b/ui/src/components/carousel.tsx @@ -14,9 +14,14 @@ type CarouselProps = { showControls?: boolean; } & React.HTMLAttributes; -export const Carousel = ( - { children, className, options = {}, showDots = false, showControls = false, ...props }: CarouselProps, -) => { +export const Carousel = ({ + children, + className, + options = {}, + showDots = false, + showControls = false, + ...props +}: CarouselProps) => { const [emblaRef, emblaApi] = useEmblaCarousel( options, options?.autoPlay?.enabled ? [Autoplay(options.autoPlay)] : [], diff --git a/ui/src/components/form.tsx b/ui/src/components/form.tsx index 8b6af8aa8..6eb5ee55f 100644 --- a/ui/src/components/form.tsx +++ b/ui/src/components/form.tsx @@ -21,9 +21,9 @@ const FormFieldContext = React.createContext({} as FormFi const FormField = < TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, ->( - { ...props }: ControllerProps, -) => { +>({ + ...props +}: ControllerProps) => { return ( diff --git a/ui/src/components/typography/typography.tsx b/ui/src/components/typography/typography.tsx index c45a84175..1d8ad9cb1 100644 --- a/ui/src/components/typography/typography.tsx +++ b/ui/src/components/typography/typography.tsx @@ -68,9 +68,16 @@ export type TypographyProps = { lineHeight?: LineHeight; } & ComponentPropsWithoutRef; -export function Typography( - { as, size, weight, color, lineHeight, className, children, ...props }: TypographyProps, -) { +export function Typography({ + as, + size, + weight, + color, + lineHeight, + className, + children, + ...props +}: TypographyProps) { const Component = as || 'p'; return ( - + - {props.params.region === 'ch' && } - - - - + {region === 'ch' && } + + + + ); } diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-1-form.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-1-form.tsx index 1249686b0..fcb6a06ce 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-1-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-1-form.tsx @@ -60,7 +60,7 @@ export default function Section1Form({ translations, lang, region }: Section1Inp /> - diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-1.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-1.tsx index 62c6ae2a0..4b6af2647 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-1.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-1.tsx @@ -1,11 +1,11 @@ -import { DefaultPageProps } from '@/app/[lang]/[region]'; +import { DefaultParams } from '@/app/[lang]/[region]'; import { Translator } from '@socialincome/shared/src/utils/i18n'; import { BaseContainer, Typography } from '@socialincome/ui'; import Section1Form from './section-1-form'; -export default async function Section1({ params }: DefaultPageProps) { +export async function Section1({ lang, region }: DefaultParams) { const translator = await Translator.getInstance({ - language: params.lang, + language: lang, namespaces: ['website-home', 'common'], }); @@ -15,9 +15,9 @@ export default async function Section1({ params }: DefaultPageProps) { className="min-h-screen-navbar grid grid-cols-1 content-center items-center gap-y-8 lg:grid-cols-2" >

- + {translator.t('section-1.title-1')} - + {translator.t('section-1.title-2')} {translator.t('section-1.title-3')} @@ -25,8 +25,8 @@ export default async function Section1({ params }: DefaultPageProps) {
{translations.title2} - + {translations.subtitle1}
diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-3.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-3.tsx index f2a1c89b4..1d8e8c6de 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-3.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-3.tsx @@ -1,10 +1,73 @@ -import { BaseContainer, Typography } from '@socialincome/ui'; +import { DefaultParams } from '@/app/[lang]/[region]'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Button, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; +import Image from 'next/image'; +import Link from 'next/link'; +import helpingOthers from './(assets)/helping-others.gif'; +import jackpotGif from './(assets)/jackpot.gif'; +import togetherGif from './(assets)/together.gif'; + +export async function Section3({ lang, region }: DefaultParams) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-home', 'common'], + }); -export default function Section3() { return ( - -
- Who should, if not us here in Switzerland? + +

+ {translator.t<{ text: string; color?: FontColor }[]>('section-3.title').map((title, index) => ( + + {title.text} + + ))} +

+
+ Jackpot +
+ + {translator.t('section-3.jackpot-title')} + + + {translator.t('section-3.jackpot-text')} + +
+ + + +
+
+
+
+ Helping Others +
+ + {translator.t('section-3.helping-others-title')} + + {translator.t('section-3.helping-others-text')} +
+ + + +
+
+
+
+ Together +
+ + {translator.t('section-3.together-title')} + + + {translator.t('section-3.together-text')} + +
+ + + +
+
); diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-4.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-4.tsx index 3333d270b..d3944df84 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-4.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-4.tsx @@ -1,15 +1,15 @@ -import { DefaultPageProps } from '@/app/[lang]/[region]'; +import { WebsiteLanguage } from '@/i18n'; import { Translator } from '@socialincome/shared/src/utils/i18n'; import { BaseContainer, Typography } from '@socialincome/ui'; -export default async function Section4({ params }: DefaultPageProps) { +export async function Section4({ lang }: { lang: WebsiteLanguage }) { const translator = await Translator.getInstance({ - language: params.lang, + language: lang, namespaces: ['website-home'], }); return ( - +

{translator.t('section-4.title-1')} @@ -19,14 +19,14 @@ export default async function Section4({ params }: DefaultPageProps) {

- + {translator.t('section-4.subtitle')} -
- {translator.t('section-4.paragraph-1')} - {translator.t('section-4.paragraph-2')} - {translator.t('section-4.paragraph-3')} - {translator.t('section-4.paragraph-4')} +
+ {translator.t('section-4.paragraph-1')} + {translator.t('section-4.paragraph-2')} + {translator.t('section-4.paragraph-3')} + {translator.t('section-4.paragraph-4')}
diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-5-card.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-5-card.tsx index 7effbb39e..b7a1b1dfa 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-5-card.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-5-card.tsx @@ -28,8 +28,8 @@ type SectionCardProps = { export function SectionCard({ titles, items = [], paragraphs = [], articles = [], faqs = [] }: SectionCardProps) { return ( - - + + {titles.main} diff --git a/website/src/app/[lang]/[region]/(website)/(home)/section-5.tsx b/website/src/app/[lang]/[region]/(website)/(home)/section-5.tsx index 1e503bc9e..02826ab52 100644 --- a/website/src/app/[lang]/[region]/(website)/(home)/section-5.tsx +++ b/website/src/app/[lang]/[region]/(website)/(home)/section-5.tsx @@ -1,23 +1,20 @@ -import { DefaultPageProps } from '@/app/[lang]/[region]'; import { SectionCard } from '@/app/[lang]/[region]/(website)/(home)/section-5-card'; +import { WebsiteLanguage } from '@/i18n'; import { Translator } from '@socialincome/shared/src/utils/i18n'; import { BaseContainer, Typography } from '@socialincome/ui'; -export default async function Section5({ params }: DefaultPageProps) { +export async function Section5({ lang }: { lang: WebsiteLanguage }) { const translator = await Translator.getInstance({ - language: params.lang, + language: lang, namespaces: ['website-home', 'website-common'], }); return ( - + {translator?.t('section-5.title')} -
+
-

- + +

+ {translator.t('section-6.title-1')} - + {translator.t('section-6.title-2')}

-
+
+

- + {translator.t('section-7.title-1')} - + {translator.t('section-7.title-2')}

diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/100-percent-model.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/100-percent-model.tsx new file mode 100644 index 000000000..e0f62c33c --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/100-percent-model.tsx @@ -0,0 +1,37 @@ +import { WebsiteLanguage } from '@/i18n'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; + +export async function HundredPercentModel({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-about-us'], + }); + + return ( + + + {translator.t('100-percent-model.header')} + +

+ {translator.t<{ text: string; color?: FontColor }[]>('100-percent-model.title').map((title, index) => ( + + {title.text} + + ))} +

+
+
+ {translator.t('100-percent-model.paragraphs').map((text, index) => ( + + ))} +
+
+
+ ); +} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/contact.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/contact.tsx new file mode 100644 index 000000000..53aff0d84 --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/contact.tsx @@ -0,0 +1,76 @@ +import { WebsiteLanguage } from '@/i18n'; +import { EnvelopeIcon } from '@heroicons/react/24/solid'; +import { SiFacebook, SiGithub, SiInstagram, SiLinkedin, SiTwitter } from '@icons-pack/react-simple-icons'; +import { IconType } from '@icons-pack/react-simple-icons/types'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Button, Card, CardContent, CardHeader, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; +import Link from 'next/link'; + +function SocialMediaButton({ Icon, title, href }: { Icon: IconType; href: string; title: string }) { + return ( + + + + ); +} + +export async function Contact({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-about-us'], + }); + + return ( + + + {translator.t('contact.header')} + +

+ {translator.t<{ text: string; color?: FontColor }[]>('contact.title').map((title, index) => ( + + {title.text} + + ))} +

+
+
+ {translator.t('contact.paragraph')} +
+ + {translator.t('contact.legal-status')} + + {translator.t('contact.legal-status-paragraphs').map((text, index) => ( + + {text} + + ))} +
+
+ + + + {translator.t('contact.find-us')} + + + +
+ + + + + + +
+
+
+
+
+ ); +} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/flow-of-funds.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/flow-of-funds.tsx new file mode 100644 index 000000000..00f352e0f --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/flow-of-funds.tsx @@ -0,0 +1,39 @@ +import { VimeoVideo } from '@/components/vimeo-video'; +import { WebsiteLanguage } from '@/i18n'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; + +export async function FlowOfFunds({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-about-us'], + }); + + return ( + + + {translator.t('flow-of-funds.header')} + +

+ {translator.t<{ text: string; color?: FontColor }[]>('flow-of-funds.title').map((title, index) => ( + + {title.text} + + ))} +

+
+ {translator.t('flow-of-funds.paragraphs').map((text, index) => ( + + ))} +
+
+ +
+
+ ); +} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/landing-page.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/landing-page.tsx new file mode 100644 index 000000000..b6ec1313f --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/landing-page.tsx @@ -0,0 +1,31 @@ +import { WebsiteLanguage } from '@/i18n'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; +import Image from 'next/image'; +import changeGif from '../(assets)/change.gif'; + +export default async function LandingPage({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-about-us'], + }); + + return ( + +

+ {translator.t<{ text: string; color?: FontColor }[]>('landing-page.title').map((title, index) => ( + + {title.text} + + ))} +

+ Change animation +
+ ); +} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/our-mission.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/our-mission.tsx new file mode 100644 index 000000000..316da7574 --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/our-mission.tsx @@ -0,0 +1,42 @@ +import { WebsiteLanguage } from '@/i18n'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { BaseContainer, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; + +export async function OurMission({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ + language: lang, + namespaces: ['website-about-us'], + }); + + return ( + + + {translator.t('our-mission.header')} + +

+ {translator.t<{ text: string; color?: FontColor }[]>('our-mission.title').map((title, index) => ( + + {title.text} + + ))} +

+
+ + {translator.t('our-mission.subtitle')} + +
+ {translator.t('our-mission.paragraphs').map((text, index) => ( + + {text} + + ))} +
+
+
+ ); +} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/section-1.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/section-1.tsx deleted file mode 100644 index a3b913e99..000000000 --- a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/section-1.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { DefaultPageProps } from '@/app/[lang]/[region]'; -import { Translator } from '@socialincome/shared/src/utils/i18n'; -import { BaseContainer, Typography } from '@socialincome/ui'; -import Image from 'next/image'; -import changeGif from '../(assets)/change.gif'; - -export default async function Section1({ params }: DefaultPageProps) { - const translator = await Translator.getInstance({ - language: params.lang, - namespaces: ['website-about-us'], - }); - - return ( - - Change animation -
- - {translator?.t('section-1.title-1')} - - - {translator?.t('section-1.title-2')} - -
-
- ); -} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/team.tsx b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/team.tsx index bde558166..da01833aa 100644 --- a/website/src/app/[lang]/[region]/(website)/about-us/(sections)/team.tsx +++ b/website/src/app/[lang]/[region]/(website)/about-us/(sections)/team.tsx @@ -1,4 +1,3 @@ -import { DefaultPageProps } from '@/app/[lang]/[region]'; import ajlaImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/ajla.jpg'; import alexandreImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/alexandre.jpeg'; import andersImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/anders.jpeg'; @@ -29,8 +28,10 @@ import simonImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/simon. import simoneImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/simone.jpeg'; import thomasImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/thomas.jpeg'; import verenaImage from '@/app/[lang]/[region]/(website)/about-us/(assets)/verena.jpeg'; +import { WebsiteLanguage } from '@/i18n'; import { Translator } from '@socialincome/shared/src/utils/i18n'; import { BaseContainer, FontSize, Typography } from '@socialincome/ui'; +import { FontColor } from '@socialincome/ui/src/interfaces/color'; import classNames from 'classnames'; import { StaticImport } from 'next/dist/shared/lib/get-img-props'; import Image from 'next/image'; @@ -104,27 +105,28 @@ const groups: Group[] = [ ], }, ]; -export default async function Team({ params }: DefaultPageProps) { - const translator = await Translator.getInstance({ language: params.lang, namespaces: ['countries', 'website-team'] }); +export default async function Team({ lang }: { lang: WebsiteLanguage }) { + const translator = await Translator.getInstance({ language: lang, namespaces: ['countries', 'website-about-us'] }); return ( - + - {translator.t('header')} - - - {translator.t('title-1')} - - {translator.t('title-2')} - + {translator.t('team.header')} +

+ {translator.t<{ text: string; color?: FontColor }[]>('team.title').map((title, index) => ( + + {title.text} + + ))} +

{groups.map((group, index1) => (
- {translator.t(`groups.${group.name}.name`)} + {translator.t(`team.groups.${group.name}.name`)} - {translator.t(`groups.${group.name}.description`)} + {translator.t(`team.groups.${group.name}.description`)}
    - {translator.t(`roles.${person.role}`)} + {translator.t(`team.roles.${person.role}`)} ))} diff --git a/website/src/app/[lang]/[region]/(website)/about-us/page.tsx b/website/src/app/[lang]/[region]/(website)/about-us/page.tsx index 2d9c41f6a..91858aec8 100644 --- a/website/src/app/[lang]/[region]/(website)/about-us/page.tsx +++ b/website/src/app/[lang]/[region]/(website)/about-us/page.tsx @@ -1,12 +1,20 @@ import { DefaultPageProps } from '@/app/[lang]/[region]'; +import { HundredPercentModel } from '@/app/[lang]/[region]/(website)/about-us/(sections)/100-percent-model'; +import { Contact } from '@/app/[lang]/[region]/(website)/about-us/(sections)/contact'; +import { FlowOfFunds } from '@/app/[lang]/[region]/(website)/about-us/(sections)/flow-of-funds'; +import { OurMission } from '@/app/[lang]/[region]/(website)/about-us/(sections)/our-mission'; import Team from '@/app/[lang]/[region]/(website)/about-us/(sections)/team'; -import Section1 from './(sections)/section-1'; +import LandingPage from './(sections)/landing-page'; -export default async function Page(props: DefaultPageProps) { +export default async function Page({ params: { lang } }: DefaultPageProps) { return ( <> - - + + + + + + ); } diff --git a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/contributors.tsx b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/contributors.tsx index 0abeac3ce..1275f1e8d 100644 --- a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/contributors.tsx +++ b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/contributors.tsx @@ -19,7 +19,7 @@ export async function Contributors({ params }: DefaultPageProps) {
    diff --git a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/how-it-works.tsx b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/how-it-works.tsx index 850802292..d5507f4c8 100644 --- a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/how-it-works.tsx +++ b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/how-it-works.tsx @@ -16,7 +16,7 @@ export async function HowItWorks({ params }: DefaultPageProps) {
    diff --git a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/our-work.tsx b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/our-work.tsx index c89cb21e0..4c672ccb2 100644 --- a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/our-work.tsx +++ b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/our-work.tsx @@ -12,7 +12,7 @@ export async function OurWork({ params }: DefaultPageProps) { }); return ( - +
    diff --git a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/whats-next.tsx b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/whats-next.tsx index 039344218..55e80270a 100644 --- a/website/src/app/[lang]/[region]/(website)/our-work/(sections)/whats-next.tsx +++ b/website/src/app/[lang]/[region]/(website)/our-work/(sections)/whats-next.tsx @@ -41,7 +41,7 @@ export async function WhatsNext({ params }: DefaultPageProps) {
    diff --git a/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/charts/transparency-charts.tsx b/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/charts/transparency-charts.tsx index 8f39b8cb5..5a1368ad2 100644 --- a/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/charts/transparency-charts.tsx +++ b/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/charts/transparency-charts.tsx @@ -14,9 +14,12 @@ type ContributionStatsProps = { currency: string; }; -export default function TransparencyCharts( - { contributionStats, paymentStats, lang, currency }: ContributionStatsProps, -) { +export default function TransparencyCharts({ + contributionStats, + paymentStats, + lang, + currency, +}: ContributionStatsProps) { const translator = useTranslator(lang, 'website-transparency'); return ( diff --git a/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/info-card.tsx b/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/info-card.tsx index bc245c70a..7e2bfd9ea 100644 --- a/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/info-card.tsx +++ b/website/src/app/[lang]/[region]/(website)/transparency/finances/[currency]/info-card.tsx @@ -14,9 +14,15 @@ type TransparencyCardProps = { secondContent?: ReactElement; }; -export function InfoCard( - { sectionTitle, title, text, firstIcon, firstContent, secondIcon, secondContent }: TransparencyCardProps, -) { +export function InfoCard({ + sectionTitle, + title, + text, + firstIcon, + firstContent, + secondIcon, + secondContent, +}: TransparencyCardProps) { return (
    diff --git a/website/src/components/footer/footer.tsx b/website/src/components/footer/footer.tsx index d951997fd..25e1ea8ed 100644 --- a/website/src/components/footer/footer.tsx +++ b/website/src/components/footer/footer.tsx @@ -73,7 +73,7 @@ export default async function Footer({ lang, region }: DefaultParams) { @@ -124,8 +124,8 @@ export default async function Footer({ lang, region }: DefaultParams) { About us - - + +
    diff --git a/website/src/components/i18n-dialog.tsx b/website/src/components/i18n-dialog.tsx index 8538d5785..93eb3aa46 100644 --- a/website/src/components/i18n-dialog.tsx +++ b/website/src/components/i18n-dialog.tsx @@ -41,9 +41,13 @@ type I18nDialogProps = { }; }; -export function I18nDialog( - { languages, regions, currencies, translations, children }: PropsWithChildren, -) { +export function I18nDialog({ + languages, + regions, + currencies, + translations, + children, +}: PropsWithChildren) { const [open, setOpen] = useState(false); const { language, setLanguage, region, setRegion, currency, setCurrency } = useI18n(); diff --git a/website/src/components/navbar/navbar-client.tsx b/website/src/components/navbar/navbar-client.tsx index 8a725a20c..2ab57a415 100644 --- a/website/src/components/navbar/navbar-client.tsx +++ b/website/src/components/navbar/navbar-client.tsx @@ -62,9 +62,16 @@ type NavbarProps = { }[]; } & DefaultParams; -export function NavbarClient( - { lang, region, translations, languages, regions, currencies, navigation = [], showNavigation = true }: NavbarProps, -) { +export function NavbarClient({ + lang, + region, + translations, + languages, + regions, + currencies, + navigation = [], + showNavigation = true, +}: NavbarProps) { const [isOpen, setIsOpen] = useState(false); const i18nDialog = ( diff --git a/website/src/components/ui/book.tsx b/website/src/components/ui/book.tsx index 5efc32eb0..c5a38ebca 100644 --- a/website/src/components/ui/book.tsx +++ b/website/src/components/ui/book.tsx @@ -15,9 +15,18 @@ type BookProps = { currentlyReading?: boolean; }; -export default async function Book( - { cover, author, authorLink, title, description, quote, publisher, publisherLink, year, currentlyReading }: BookProps, -) { +export default async function Book({ + cover, + author, + authorLink, + title, + description, + quote, + publisher, + publisherLink, + year, + currentlyReading, +}: BookProps) { return (