From c0839f035385975d83c2a3ccf951a837ec956378 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Fri, 19 Jan 2024 16:37:00 +0100 Subject: [PATCH 01/15] adds the possibility for a user to specify its employers --- shared/locales/de/website-me.json | 14 ++ shared/locales/en/website-me.json | 14 ++ .../[region]/(website)/me/layout-client.tsx | 16 ++- .../[lang]/[region]/(website)/me/layout.tsx | 2 + .../me/work-info/add-employer-form.tsx | 69 ++++++++++ .../(website)/me/work-info/employers-list.tsx | 120 ++++++++++++++++++ .../[region]/(website)/me/work-info/page.tsx | 29 +++++ 7 files changed, 262 insertions(+), 2 deletions(-) create mode 100644 website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx create mode 100644 website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx create mode 100644 website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx diff --git a/shared/locales/de/website-me.json b/shared/locales/de/website-me.json index f0fbad58b..6f774a0be 100644 --- a/shared/locales/de/website-me.json +++ b/shared/locales/de/website-me.json @@ -14,6 +14,10 @@ "subscriptions": "Abonnemente", "donation-certificates-short": "Bescheinigungen", "donation-certificates-long": "Spendebescheinigungen" + }, + "employer": { + "title": "Mein Arbeitgeber", + "work": "Arbeit" } }, "contributions": { @@ -85,5 +89,15 @@ "title": "Möchtest du dich abmelden?", "button": "Abmelden" } + }, + "work-info": { + "work": "Arbeiten", + "add-employer": "Neuen Arbeitgeber hinzufügen", + "submit-button": "Hinzufügen", + "current-employers": "Aktueller Arbeitgeber", + "empty-state": "Sie haben keinen Arbeitgeber angegeben", + "delete-employer": "Löschen", + "past-employers": "Frühere Arbeitgeber", + "no-longer-work-here": "Ich arbeite nicht mehr hier" } } diff --git a/shared/locales/en/website-me.json b/shared/locales/en/website-me.json index a3065b95e..9c814d037 100644 --- a/shared/locales/en/website-me.json +++ b/shared/locales/en/website-me.json @@ -14,6 +14,10 @@ "subscriptions": "Subscriptions", "donation-certificates-short": "Certificates", "donation-certificates-long": "Donation certificates" + }, + "employer": { + "title": "My Employer", + "work": "Work" } }, "contributions": { @@ -85,5 +89,15 @@ "title": "Sign out of your account?", "button": "Sign Out" } + }, + "work-info": { + "work": "Work", + "add-employer": "Add new employer", + "submit-button": "Add", + "current-employer": "Current Employer", + "empty-state": "You didn't specify any employer", + "delete-employer": "Delete", + "past-employers": "Past Employers", + "no-longer-work-here": "I no longer work here" } } diff --git a/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx b/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx index 889315a04..9ce875ce7 100644 --- a/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx @@ -8,6 +8,7 @@ import { DocumentIcon, ShieldCheckIcon, UserCircleIcon, + BriefcaseIcon } from '@heroicons/react/24/outline'; import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger, Typography } from '@socialincome/ui'; import { LinkProps } from 'next/dist/client/link'; @@ -51,6 +52,8 @@ type LayoutClientProps = { subscriptions: string; donationCertificatesShort: string; donationCertificatesLong: string; + employerTitle: string, + work: string, }; }; @@ -84,7 +87,16 @@ export function LayoutClient({ params, translations, children }: PropsWithChildr > {translations.donationCertificatesShort} - )} + ) + } + {translations.employerTitle} + setIsOpen(false)} + > + {translations.work} + {translations.accountTitle} {translations.security} - + ); let title; diff --git a/website/src/app/[lang]/[region]/(website)/me/layout.tsx b/website/src/app/[lang]/[region]/(website)/me/layout.tsx index 32a35e008..dc2e097cb 100644 --- a/website/src/app/[lang]/[region]/(website)/me/layout.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/layout.tsx @@ -27,6 +27,8 @@ export default async function Layout({ children, params }: PropsWithChildren {children} diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx new file mode 100644 index 000000000..f595bb819 --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -0,0 +1,69 @@ +'use client' + +import { Form, FormField, FormItem, FormControl, Input, FormMessage, Button } from '@socialincome/ui'; +import * as z from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; +import { Timestamp, addDoc, collection } from 'firebase/firestore'; +import { useFirestore } from 'reactfire'; +import { useUserContext } from '../user-context-provider'; +import { Employer } from '@socialincome/shared/src/types/employers'; + +export type AddEmployerFormProps = { + translations: { + addEmployer: string, + submitButton: string, + }, + onNewEmployerSubmitted: () => void, +}; + +export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmployerFormProps) { + const firestore = useFirestore(); + const { user } = useUserContext(); + + const formSchema = z.object({ + employerName: z.string().trim().min(1), + }); + type FormSchema = z.infer; + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: { + employerName: '', + } + }); + + const onSubmit = async (values: FormSchema) => { + if (user) { + const userId = user!.id; + await addDoc>(collection(firestore, "employers"), { ...values, isCurrent: true, userId: userId, created: Timestamp.now() }).then(() => { + form.reset(); + onNewEmployerSubmitted(); + }); + + } + }; + + return ( +
+ + ( + + + + + + + )} + /> + + + + ); +} + diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx new file mode 100644 index 000000000..3be6bfe5e --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -0,0 +1,120 @@ +'use client'; + +import { UserContext } from '@/app/[lang]/[region]/(website)/me/user-context-provider'; +import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; + +import { Table, TableBody, TableCell, TableRow, Typography } from '@socialincome/ui'; +import { useQuery } from '@tanstack/react-query'; +import { collection, getDocs, query, deleteDoc, updateDoc, doc, where, orderBy } from 'firebase/firestore'; +import { useContext } from 'react'; +import { useFirestore } from 'reactfire'; +import { AddEmployerForm, AddEmployerFormProps } from './add-employer-form'; +import { DefaultParams } from '../../..'; + +type EmployersListProps = { + translations: { + employersList: { + emptyState: string, + deleteEmployer: string, + noLongerWorkHere: string, + pastEmployers: string, + }, + addEmployerForm: AddEmployerFormProps['translations'] + } +} & DefaultParams; + +export function EmployersList({ translations }: EmployersListProps) { + const firestore = useFirestore(); + const { user } = useContext(UserContext); + const { isLoading, data, refetch } = useQuery({ + queryKey: ['employersList'], + queryFn: async () => { + if (user && firestore) { + return await getDocs( + query( + collection(firestore, EMPLOYERS_FIRESTORE_PATH), + where('userId', '==', user.id), + orderBy('created', 'desc') + ), + ); + } else return null; + }, + staleTime: 1000 * 60 * 60, // an hour + }); + + const onDeleteEmployer = async (employer_id: String) => { + const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); + await deleteDoc(employerRef).then(() => onEmployersUpdated()); + }; + + const onArchiveEmployer = async (employer_id: String) => { + const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); + await updateDoc(employerRef, { isCurrent: false }).then(() => onEmployersUpdated()) + }; + + const onEmployersUpdated = async () => { + await refetch(); + } + + if (isLoading) { + return Loading ... + } + + const currentEmployers = data!.docs.filter((e) => e.get('isCurrent')); + const pastEmployers = data!.docs.filter((e) => !e.get('isCurrent')); + + return ( + <> + {currentEmployers.length > 0 + ? + + {currentEmployers.map((employer, index) => { + return ( + + +
+ {employer.get('employerName')} +
+ +
+
+
+
) + })} +
+
+ : {translations.employersList.emptyState} + } + + + {pastEmployers.length > 0 && + <> + + {translations.employersList.pastEmployers} + + + + {pastEmployers.map((employer, index) => { + return ( + + +
+ {employer.get('employerName')} +
+ +
+
+
+
) + })} +
+
+ } + + + ) +} diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx new file mode 100644 index 000000000..f0e3a4b03 --- /dev/null +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx @@ -0,0 +1,29 @@ +import { DefaultPageProps, DefaultParams } from '@/app/[lang]/[region]'; +import { Translator } from '@socialincome/shared/src/utils/i18n'; +import { Typography, Form, FormField, FormItem, FormLabel, FormControl, Input, Button } from '@socialincome/ui'; +import { EmployersList } from './employers-list'; + +export default async function Page({ params }: DefaultPageProps) { + const translator = await Translator.getInstance({ language: params.lang, namespaces: ['website-me'] }); + return ( +
+ + {translator.t('work-info.current-employers')} + + +
+ ); +} From 071d06c5b19564a54991319122e69cb47c91b86b Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Fri, 19 Jan 2024 16:35:33 +0100 Subject: [PATCH 02/15] adds an employer collection to the database --- firestore.rules | 7 +- shared/locales/de/website-me.json | 4 +- shared/locales/en/website-me.json | 12 +-- shared/src/types/employers.ts | 10 +++ .../me/work-info/add-employer-form.tsx | 37 +++++----- .../(website)/me/work-info/employers-list.tsx | 73 ++++++++++--------- .../[region]/(website)/me/work-info/page.tsx | 20 ++--- 7 files changed, 94 insertions(+), 69 deletions(-) create mode 100644 shared/src/types/employers.ts diff --git a/firestore.rules b/firestore.rules index 04cc67f42..db585236f 100644 --- a/firestore.rules +++ b/firestore.rules @@ -24,6 +24,11 @@ service cloud.firestore { allow read: if isGlobalAnalyst(request.auth.token.email); } + match /employers/{data=**} { + allow read, write, delete: if request.auth.uid == request.auth.uid; + allow create: if request.auth != null; + } + match /events/{data} { allow read, write: if request.auth != null; } @@ -86,4 +91,4 @@ service cloud.firestore { allow read, write: if false; } } -} \ No newline at end of file +} diff --git a/shared/locales/de/website-me.json b/shared/locales/de/website-me.json index 6f774a0be..4b96a4538 100644 --- a/shared/locales/de/website-me.json +++ b/shared/locales/de/website-me.json @@ -89,12 +89,12 @@ "title": "Möchtest du dich abmelden?", "button": "Abmelden" } - }, + }, "work-info": { "work": "Arbeiten", "add-employer": "Neuen Arbeitgeber hinzufügen", "submit-button": "Hinzufügen", - "current-employers": "Aktueller Arbeitgeber", + "current-employers": "Aktueller Arbeitgeber", "empty-state": "Sie haben keinen Arbeitgeber angegeben", "delete-employer": "Löschen", "past-employers": "Frühere Arbeitgeber", diff --git a/shared/locales/en/website-me.json b/shared/locales/en/website-me.json index 9c814d037..34d615df2 100644 --- a/shared/locales/en/website-me.json +++ b/shared/locales/en/website-me.json @@ -92,12 +92,12 @@ }, "work-info": { "work": "Work", - "add-employer": "Add new employer", - "submit-button": "Add", - "current-employer": "Current Employer", - "empty-state": "You didn't specify any employer", - "delete-employer": "Delete", - "past-employers": "Past Employers", + "add-employer": "Add new employer", + "submit-button": "Add", + "current-employer": "Current Employer", + "empty-state": "You didn't specify any employer", + "delete-employer": "Delete", + "past-employers": "Past Employers", "no-longer-work-here": "I no longer work here" } } diff --git a/shared/src/types/employers.ts b/shared/src/types/employers.ts new file mode 100644 index 000000000..f059c850f --- /dev/null +++ b/shared/src/types/employers.ts @@ -0,0 +1,10 @@ +import { Timestamp } from 'firebase-admin/firestore'; + +export const EMPLOYERS_FIRESTORE_PATH = 'employers'; + +export type Employer = { + userId: string; + isCurrent: boolean; + employerName: string; + created: Timestamp; +}; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index f595bb819..e2428bc05 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -1,20 +1,20 @@ -'use client' +'use client'; -import { Form, FormField, FormItem, FormControl, Input, FormMessage, Button } from '@socialincome/ui'; -import * as z from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; -import { useForm } from 'react-hook-form'; +import { Employer } from '@socialincome/shared/src/types/employers'; +import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; import { Timestamp, addDoc, collection } from 'firebase/firestore'; +import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; +import * as z from 'zod'; import { useUserContext } from '../user-context-provider'; -import { Employer } from '@socialincome/shared/src/types/employers'; export type AddEmployerFormProps = { translations: { - addEmployer: string, - submitButton: string, - }, - onNewEmployerSubmitted: () => void, + addEmployer: string; + submitButton: string; + }; + onNewEmployerSubmitted: () => void; }; export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmployerFormProps) { @@ -30,28 +30,32 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp resolver: zodResolver(formSchema), defaultValues: { employerName: '', - } + }, }); const onSubmit = async (values: FormSchema) => { if (user) { const userId = user!.id; - await addDoc>(collection(firestore, "employers"), { ...values, isCurrent: true, userId: userId, created: Timestamp.now() }).then(() => { + await addDoc>(collection(firestore, 'employers'), { + ...values, + isCurrent: true, + userId: userId, + created: Timestamp.now(), + }).then(() => { form.reset(); onNewEmployerSubmitted(); }); - } }; return (
- + ( - + @@ -59,11 +63,8 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp )} /> - + ); } - diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index 3be6bfe5e..6ee4463d8 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -5,22 +5,22 @@ import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employe import { Table, TableBody, TableCell, TableRow, Typography } from '@socialincome/ui'; import { useQuery } from '@tanstack/react-query'; -import { collection, getDocs, query, deleteDoc, updateDoc, doc, where, orderBy } from 'firebase/firestore'; +import { collection, deleteDoc, doc, getDocs, orderBy, query, updateDoc, where } from 'firebase/firestore'; import { useContext } from 'react'; import { useFirestore } from 'reactfire'; -import { AddEmployerForm, AddEmployerFormProps } from './add-employer-form'; import { DefaultParams } from '../../..'; +import { AddEmployerForm, AddEmployerFormProps } from './add-employer-form'; type EmployersListProps = { translations: { employersList: { - emptyState: string, - deleteEmployer: string, - noLongerWorkHere: string, - pastEmployers: string, - }, - addEmployerForm: AddEmployerFormProps['translations'] - } + emptyState: string; + deleteEmployer: string; + noLongerWorkHere: string; + pastEmployers: string; + }; + addEmployerForm: AddEmployerFormProps['translations']; + }; } & DefaultParams; export function EmployersList({ translations }: EmployersListProps) { @@ -34,7 +34,7 @@ export function EmployersList({ translations }: EmployersListProps) { query( collection(firestore, EMPLOYERS_FIRESTORE_PATH), where('userId', '==', user.id), - orderBy('created', 'desc') + orderBy('created', 'desc'), ), ); } else return null; @@ -42,22 +42,22 @@ export function EmployersList({ translations }: EmployersListProps) { staleTime: 1000 * 60 * 60, // an hour }); - const onDeleteEmployer = async (employer_id: String) => { + const onDeleteEmployer = async (employer_id: string) => { const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); await deleteDoc(employerRef).then(() => onEmployersUpdated()); }; - const onArchiveEmployer = async (employer_id: String) => { + const onArchiveEmployer = async (employer_id: string) => { const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); - await updateDoc(employerRef, { isCurrent: false }).then(() => onEmployersUpdated()) + await updateDoc(employerRef, { isCurrent: false }).then(() => onEmployersUpdated()); }; const onEmployersUpdated = async () => { await refetch(); - } + }; if (isLoading) { - return Loading ... + return Loading ...; } const currentEmployers = data!.docs.filter((e) => e.get('isCurrent')); @@ -65,31 +65,35 @@ export function EmployersList({ translations }: EmployersListProps) { return ( <> - {currentEmployers.length > 0 - ? + {currentEmployers.length > 0 ? ( +
{currentEmployers.map((employer, index) => { return ( -
- {employer.get('employerName')} -
+
+ + {employer.get('employerName')} + +
- ) + + ); })}
- : {translations.employersList.emptyState} - } + ) : ( + {translations.employersList.emptyState} + )} - {pastEmployers.length > 0 && + {pastEmployers.length > 0 && ( <> {translations.employersList.pastEmployers} @@ -100,21 +104,24 @@ export function EmployersList({ translations }: EmployersListProps) { return ( -
- {employer.get('employerName')} -
+
+ + {employer.get('employerName')} + +
- ) + + ); })} - } - + + )} - ) + ); } diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx index f0e3a4b03..39f8834e2 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx @@ -1,6 +1,6 @@ -import { DefaultPageProps, DefaultParams } from '@/app/[lang]/[region]'; +import { DefaultPageProps } from '@/app/[lang]/[region]'; import { Translator } from '@socialincome/shared/src/utils/i18n'; -import { Typography, Form, FormField, FormItem, FormLabel, FormControl, Input, Button } from '@socialincome/ui'; +import { Typography } from '@socialincome/ui'; import { EmployersList } from './employers-list'; export default async function Page({ params }: DefaultPageProps) { @@ -10,20 +10,22 @@ export default async function Page({ params }: DefaultPageProps) { {translator.t('work-info.current-employers')} - + noLongerWorkHere: translator.t('work-info.no-longer-work-here'), + }, + }} + />
); } From c0afd938f154485583b40911425a656cb1e4cd8c Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Mon, 5 Feb 2024 15:49:44 +0100 Subject: [PATCH 03/15] store a reference to a user id in the employers collection --- shared/locales/en/website-me.json | 2 +- .../[lang]/[region]/(website)/me/layout-client.tsx | 11 +++++------ .../(website)/me/work-info/add-employer-form.tsx | 5 +++-- .../(website)/me/work-info/employers-list.tsx | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/shared/locales/en/website-me.json b/shared/locales/en/website-me.json index 34d615df2..4b9bfe085 100644 --- a/shared/locales/en/website-me.json +++ b/shared/locales/en/website-me.json @@ -14,7 +14,7 @@ "subscriptions": "Subscriptions", "donation-certificates-short": "Certificates", "donation-certificates-long": "Donation certificates" - }, + }, "employer": { "title": "My Employer", "work": "Work" diff --git a/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx b/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx index 9ce875ce7..98bb4c65d 100644 --- a/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/layout-client.tsx @@ -4,11 +4,11 @@ import { DefaultParams } from '@/app/[lang]/[region]'; import { UserContext } from '@/app/[lang]/[region]/(website)/me/user-context-provider'; import { ArrowPathIcon, + BriefcaseIcon, CurrencyDollarIcon, DocumentIcon, ShieldCheckIcon, UserCircleIcon, - BriefcaseIcon } from '@heroicons/react/24/outline'; import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger, Typography } from '@socialincome/ui'; import { LinkProps } from 'next/dist/client/link'; @@ -52,8 +52,8 @@ type LayoutClientProps = { subscriptions: string; donationCertificatesShort: string; donationCertificatesLong: string; - employerTitle: string, - work: string, + employerTitle: string; + work: string; }; }; @@ -87,8 +87,7 @@ export function LayoutClient({ params, translations, children }: PropsWithChildr > {translations.donationCertificatesShort} - ) - } + )} {translations.employerTitle} {translations.security} - + ); let title; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index e2428bc05..a08000071 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -2,8 +2,9 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Employer } from '@socialincome/shared/src/types/employers'; +import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; -import { Timestamp, addDoc, collection } from 'firebase/firestore'; +import { Timestamp, addDoc, collection, doc } from 'firebase/firestore'; import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; import * as z from 'zod'; @@ -39,7 +40,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp await addDoc>(collection(firestore, 'employers'), { ...values, isCurrent: true, - userId: userId, + userId: doc(firestore, USER_FIRESTORE_PATH, userId).path, created: Timestamp.now(), }).then(() => { form.reset(); diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index 6ee4463d8..a298a0bcc 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -3,6 +3,7 @@ import { UserContext } from '@/app/[lang]/[region]/(website)/me/user-context-provider'; import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; +import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Table, TableBody, TableCell, TableRow, Typography } from '@socialincome/ui'; import { useQuery } from '@tanstack/react-query'; import { collection, deleteDoc, doc, getDocs, orderBy, query, updateDoc, where } from 'firebase/firestore'; @@ -33,7 +34,7 @@ export function EmployersList({ translations }: EmployersListProps) { return await getDocs( query( collection(firestore, EMPLOYERS_FIRESTORE_PATH), - where('userId', '==', user.id), + where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id)), orderBy('created', 'desc'), ), ); From 4bdabc3b9287b6e7fcd544379622ed85d78f4c23 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Wed, 7 Feb 2024 10:49:51 +0100 Subject: [PATCH 04/15] fix translation issue on work information page --- shared/locales/de/website-me.json | 2 +- website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/locales/de/website-me.json b/shared/locales/de/website-me.json index 4b96a4538..a444005e9 100644 --- a/shared/locales/de/website-me.json +++ b/shared/locales/de/website-me.json @@ -94,7 +94,7 @@ "work": "Arbeiten", "add-employer": "Neuen Arbeitgeber hinzufügen", "submit-button": "Hinzufügen", - "current-employers": "Aktueller Arbeitgeber", + "current-employer": "Aktueller Arbeitgeber", "empty-state": "Sie haben keinen Arbeitgeber angegeben", "delete-employer": "Löschen", "past-employers": "Frühere Arbeitgeber", diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx index 39f8834e2..dddfea283 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/page.tsx @@ -8,7 +8,7 @@ export default async function Page({ params }: DefaultPageProps) { return (
- {translator.t('work-info.current-employers')} + {translator.t('work-info.current-employer')} Date: Wed, 7 Feb 2024 11:05:05 +0100 Subject: [PATCH 05/15] fix employers list not showing anything --- .../[lang]/[region]/(website)/me/work-info/employers-list.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index a298a0bcc..985aee80e 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -34,7 +34,7 @@ export function EmployersList({ translations }: EmployersListProps) { return await getDocs( query( collection(firestore, EMPLOYERS_FIRESTORE_PATH), - where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id)), + where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id).path), orderBy('created', 'desc'), ), ); From 7a5e009f0ddc0d5de9f9b3d464a13ea0b9f95cd5 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Wed, 7 Feb 2024 13:35:04 +0100 Subject: [PATCH 06/15] fix type for employers userId field --- shared/src/types/employers.ts | 4 +++- .../(website)/me/work-info/add-employer-form.tsx | 9 +++++---- .../[region]/(website)/me/work-info/employers-list.tsx | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/shared/src/types/employers.ts b/shared/src/types/employers.ts index f059c850f..5bf89cb0a 100644 --- a/shared/src/types/employers.ts +++ b/shared/src/types/employers.ts @@ -1,9 +1,11 @@ import { Timestamp } from 'firebase-admin/firestore'; +import { DocumentReference } from 'firebase-admin/firestore'; +import { User } from './user'; export const EMPLOYERS_FIRESTORE_PATH = 'employers'; export type Employer = { - userId: string; + userId: DocumentReference; isCurrent: boolean; employerName: string; created: Timestamp; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index a08000071..2d062e2db 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -2,9 +2,9 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Employer } from '@socialincome/shared/src/types/employers'; -import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; +import { USER_FIRESTORE_PATH, User } from '@socialincome/shared/src/types/user'; import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; -import { Timestamp, addDoc, collection, doc } from 'firebase/firestore'; +import { DocumentReference, Timestamp, addDoc, collection, doc } from 'firebase/firestore'; import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; import * as z from 'zod'; @@ -37,10 +37,11 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp const onSubmit = async (values: FormSchema) => { if (user) { const userId = user!.id; - await addDoc>(collection(firestore, 'employers'), { + + await addDoc(collection(firestore, 'employers'), { ...values, isCurrent: true, - userId: doc(firestore, USER_FIRESTORE_PATH, userId).path, + userId: doc(firestore, USER_FIRESTORE_PATH, userId), created: Timestamp.now(), }).then(() => { form.reset(); diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index 985aee80e..a298a0bcc 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -34,7 +34,7 @@ export function EmployersList({ translations }: EmployersListProps) { return await getDocs( query( collection(firestore, EMPLOYERS_FIRESTORE_PATH), - where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id).path), + where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id)), orderBy('created', 'desc'), ), ); From 49c506fae5dae660bb4b51253a974c59eb2f6f0b Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Wed, 7 Feb 2024 13:37:19 +0100 Subject: [PATCH 07/15] update firestore rules --- firestore.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore.rules b/firestore.rules index db585236f..0d1d12bf9 100644 --- a/firestore.rules +++ b/firestore.rules @@ -25,7 +25,7 @@ service cloud.firestore { } match /employers/{data=**} { - allow read, write, delete: if request.auth.uid == request.auth.uid; + allow read, write, delete: if request.auth.uid == get(resource.data.userId).data.auth_user_id; allow create: if request.auth != null; } From 1939d1fd2fa3d2a096edf371870fe9f27dd4d516 Mon Sep 17 00:00:00 2001 From: anthonyray Date: Wed, 7 Feb 2024 12:39:39 +0000 Subject: [PATCH 08/15] Prettified Code! --- shared/src/types/employers.ts | 4 +--- .../[region]/(website)/me/work-info/add-employer-form.tsx | 7 +++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/shared/src/types/employers.ts b/shared/src/types/employers.ts index 5bf89cb0a..a0146da07 100644 --- a/shared/src/types/employers.ts +++ b/shared/src/types/employers.ts @@ -1,6 +1,4 @@ -import { Timestamp } from 'firebase-admin/firestore'; -import { DocumentReference } from 'firebase-admin/firestore'; -import { User } from './user'; +import { DocumentReference, Timestamp } from 'firebase-admin/firestore'; export const EMPLOYERS_FIRESTORE_PATH = 'employers'; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index 2d062e2db..f5560c17e 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -1,10 +1,9 @@ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; -import { Employer } from '@socialincome/shared/src/types/employers'; -import { USER_FIRESTORE_PATH, User } from '@socialincome/shared/src/types/user'; +import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; -import { DocumentReference, Timestamp, addDoc, collection, doc } from 'firebase/firestore'; +import { Timestamp, addDoc, collection, doc } from 'firebase/firestore'; import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; import * as z from 'zod'; @@ -37,7 +36,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp const onSubmit = async (values: FormSchema) => { if (user) { const userId = user!.id; - + await addDoc(collection(firestore, 'employers'), { ...values, isCurrent: true, From 5984c64c755aa536cf0d6ed799d142264ac94e21 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Mon, 11 Mar 2024 17:15:38 +0100 Subject: [PATCH 09/15] removes rule for employer collection --- firestore.rules | 5 ----- 1 file changed, 5 deletions(-) diff --git a/firestore.rules b/firestore.rules index 0d1d12bf9..af5a45303 100644 --- a/firestore.rules +++ b/firestore.rules @@ -24,11 +24,6 @@ service cloud.firestore { allow read: if isGlobalAnalyst(request.auth.token.email); } - match /employers/{data=**} { - allow read, write, delete: if request.auth.uid == get(resource.data.userId).data.auth_user_id; - allow create: if request.auth != null; - } - match /events/{data} { allow read, write: if request.auth != null; } From e00bdd7fb5b4fcca4c39b48c789ea57a7b906255 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Mon, 11 Mar 2024 17:16:05 +0100 Subject: [PATCH 10/15] changes user type to add a employers subcollection --- shared/src/types/user.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/src/types/user.ts b/shared/src/types/user.ts index 9fcd267a8..cdc1a3034 100644 --- a/shared/src/types/user.ts +++ b/shared/src/types/user.ts @@ -3,6 +3,7 @@ import { capitalizeStringIfUppercase } from '../utils/strings'; import { CountryCode } from './country'; import { Currency } from './currency'; import { LanguageCode } from './language'; +import { Employer } from './employers'; export const USER_FIRESTORE_PATH = 'users'; @@ -45,6 +46,7 @@ export type User = { language?: LanguageCode; currency?: Currency; contributor_organisations?: EntityReference[]; + employers?: Employer[]; }; export const splitName = (name: string) => { From d2e392643757471160308221642ee34195bd8201 Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Mon, 11 Mar 2024 17:16:30 +0100 Subject: [PATCH 11/15] updates UI to reflect new database structure --- .../[region]/(website)/me/work-info/add-employer-form.tsx | 5 +++-- .../[region]/(website)/me/work-info/employers-list.tsx | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index f5560c17e..c04ceb4d2 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -8,6 +8,7 @@ import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; import * as z from 'zod'; import { useUserContext } from '../user-context-provider'; +import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; export type AddEmployerFormProps = { translations: { @@ -22,7 +23,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp const { user } = useUserContext(); const formSchema = z.object({ - employerName: z.string().trim().min(1), + employerName: z.string().trim().min(1), // TODO : security }); type FormSchema = z.infer; @@ -37,7 +38,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp if (user) { const userId = user!.id; - await addDoc(collection(firestore, 'employers'), { + await addDoc(collection(firestore, USER_FIRESTORE_PATH, userId, EMPLOYERS_FIRESTORE_PATH), { ...values, isCurrent: true, userId: doc(firestore, USER_FIRESTORE_PATH, userId), diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index a298a0bcc..481ceedec 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -33,8 +33,7 @@ export function EmployersList({ translations }: EmployersListProps) { if (user && firestore) { return await getDocs( query( - collection(firestore, EMPLOYERS_FIRESTORE_PATH), - where('userId', '==', doc(firestore, USER_FIRESTORE_PATH, user.id)), + collection(firestore, USER_FIRESTORE_PATH, user.id, EMPLOYERS_FIRESTORE_PATH), orderBy('created', 'desc'), ), ); @@ -44,12 +43,12 @@ export function EmployersList({ translations }: EmployersListProps) { }); const onDeleteEmployer = async (employer_id: string) => { - const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); + const employerRef = doc(firestore, USER_FIRESTORE_PATH, user!.id, EMPLOYERS_FIRESTORE_PATH, employer_id); await deleteDoc(employerRef).then(() => onEmployersUpdated()); }; const onArchiveEmployer = async (employer_id: string) => { - const employerRef = doc(firestore, EMPLOYERS_FIRESTORE_PATH, employer_id); + const employerRef = doc(firestore, USER_FIRESTORE_PATH, user!.id, EMPLOYERS_FIRESTORE_PATH, employer_id); await updateDoc(employerRef, { isCurrent: false }).then(() => onEmployersUpdated()); }; From 3efef4bf85852faf7891ccc87e86aed78180d023 Mon Sep 17 00:00:00 2001 From: anthonyray Date: Mon, 11 Mar 2024 16:20:45 +0000 Subject: [PATCH 12/15] Prettified Code! --- shared/src/types/user.ts | 2 +- .../[region]/(website)/me/work-info/add-employer-form.tsx | 4 ++-- .../[lang]/[region]/(website)/me/work-info/employers-list.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/shared/src/types/user.ts b/shared/src/types/user.ts index cdc1a3034..f6b73e070 100644 --- a/shared/src/types/user.ts +++ b/shared/src/types/user.ts @@ -2,8 +2,8 @@ import { EntityReference } from 'firecms'; import { capitalizeStringIfUppercase } from '../utils/strings'; import { CountryCode } from './country'; import { Currency } from './currency'; -import { LanguageCode } from './language'; import { Employer } from './employers'; +import { LanguageCode } from './language'; export const USER_FIRESTORE_PATH = 'users'; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index c04ceb4d2..7dc07d271 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -1,6 +1,7 @@ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; +import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; import { Timestamp, addDoc, collection, doc } from 'firebase/firestore'; @@ -8,7 +9,6 @@ import { useForm } from 'react-hook-form'; import { useFirestore } from 'reactfire'; import * as z from 'zod'; import { useUserContext } from '../user-context-provider'; -import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; export type AddEmployerFormProps = { translations: { @@ -23,7 +23,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp const { user } = useUserContext(); const formSchema = z.object({ - employerName: z.string().trim().min(1), // TODO : security + employerName: z.string().trim().min(1), // TODO : security }); type FormSchema = z.infer; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index 481ceedec..da0c4e668 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -6,7 +6,7 @@ import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employe import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Table, TableBody, TableCell, TableRow, Typography } from '@socialincome/ui'; import { useQuery } from '@tanstack/react-query'; -import { collection, deleteDoc, doc, getDocs, orderBy, query, updateDoc, where } from 'firebase/firestore'; +import { collection, deleteDoc, doc, getDocs, orderBy, query, updateDoc } from 'firebase/firestore'; import { useContext } from 'react'; import { useFirestore } from 'reactfire'; import { DefaultParams } from '../../..'; From 03869797da7ff655a5dc8746eb857eb9b822b2ed Mon Sep 17 00:00:00 2001 From: Anthony Reinette Date: Thu, 14 Mar 2024 11:25:50 +0100 Subject: [PATCH 13/15] make use of the refactored Employer type --- shared/src/types/employers.ts | 5 ++--- .../me/work-info/add-employer-form.tsx | 22 +++++++++---------- .../(website)/me/work-info/employers-list.tsx | 22 +++++++++++++------ 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/shared/src/types/employers.ts b/shared/src/types/employers.ts index a0146da07..5501e640e 100644 --- a/shared/src/types/employers.ts +++ b/shared/src/types/employers.ts @@ -3,8 +3,7 @@ import { DocumentReference, Timestamp } from 'firebase-admin/firestore'; export const EMPLOYERS_FIRESTORE_PATH = 'employers'; export type Employer = { - userId: DocumentReference; - isCurrent: boolean; - employerName: string; + is_current: boolean; + employer_name: string; created: Timestamp; }; diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx index 7dc07d271..81cc430e7 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/add-employer-form.tsx @@ -1,7 +1,7 @@ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; -import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; +import { EMPLOYERS_FIRESTORE_PATH, Employer } from '@socialincome/shared/src/types/employers'; import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Button, Form, FormControl, FormField, FormItem, FormMessage, Input } from '@socialincome/ui'; import { Timestamp, addDoc, collection, doc } from 'firebase/firestore'; @@ -23,27 +23,27 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp const { user } = useUserContext(); const formSchema = z.object({ - employerName: z.string().trim().min(1), // TODO : security + employer_name: z.string().trim().min(1), // TODO : security }); type FormSchema = z.infer; const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { - employerName: '', + employer_name: '', }, }); const onSubmit = async (values: FormSchema) => { if (user) { - const userId = user!.id; - - await addDoc(collection(firestore, USER_FIRESTORE_PATH, userId, EMPLOYERS_FIRESTORE_PATH), { - ...values, - isCurrent: true, - userId: doc(firestore, USER_FIRESTORE_PATH, userId), + const user_id = user!.id; + let new_employer: Employer = { + employer_name: values.employer_name, + is_current: true, created: Timestamp.now(), - }).then(() => { + }; + + await addDoc(collection(firestore, USER_FIRESTORE_PATH, user_id, EMPLOYERS_FIRESTORE_PATH), new_employer).then(() => { form.reset(); onNewEmployerSubmitted(); }); @@ -55,7 +55,7 @@ export function AddEmployerForm({ onNewEmployerSubmitted, translations }: AddEmp
( diff --git a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx index da0c4e668..d80ad9d57 100644 --- a/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx +++ b/website/src/app/[lang]/[region]/(website)/me/work-info/employers-list.tsx @@ -1,7 +1,7 @@ 'use client'; import { UserContext } from '@/app/[lang]/[region]/(website)/me/user-context-provider'; -import { EMPLOYERS_FIRESTORE_PATH } from '@socialincome/shared/src/types/employers'; +import { EMPLOYERS_FIRESTORE_PATH, Employer } from '@socialincome/shared/src/types/employers'; import { USER_FIRESTORE_PATH } from '@socialincome/shared/src/types/user'; import { Table, TableBody, TableCell, TableRow, Typography } from '@socialincome/ui'; @@ -24,6 +24,10 @@ type EmployersListProps = { }; } & DefaultParams; +type EmployerWithId = { + id: string +} & Employer; + export function EmployersList({ translations }: EmployersListProps) { const firestore = useFirestore(); const { user } = useContext(UserContext); @@ -47,9 +51,9 @@ export function EmployersList({ translations }: EmployersListProps) { await deleteDoc(employerRef).then(() => onEmployersUpdated()); }; - const onArchiveEmployer = async (employer_id: string) => { + const onArchiveEmployer = async (employer_id: string) => { // Not leveraging type system .... const employerRef = doc(firestore, USER_FIRESTORE_PATH, user!.id, EMPLOYERS_FIRESTORE_PATH, employer_id); - await updateDoc(employerRef, { isCurrent: false }).then(() => onEmployersUpdated()); + await updateDoc(employerRef, { is_current: false }).then(() => onEmployersUpdated()); }; const onEmployersUpdated = async () => { @@ -60,8 +64,12 @@ export function EmployersList({ translations }: EmployersListProps) { return Loading ...; } - const currentEmployers = data!.docs.filter((e) => e.get('isCurrent')); - const pastEmployers = data!.docs.filter((e) => !e.get('isCurrent')); + const employers: EmployerWithId[] = data!.docs.map((e) => { + const employer: Employer = e.data() as Employer; + return { id: e.id, ...employer } + }); + const currentEmployers: EmployerWithId[] = employers.filter((e) => e.is_current); + const pastEmployers: EmployerWithId[] = employers.filter((e) => !e.is_current); return ( <> @@ -74,7 +82,7 @@ export function EmployersList({ translations }: EmployersListProps) {
- {employer.get('employerName')} + {employer.employer_name}