From c5a0d122d9994c34cf991475a578fa50c9fadc48 Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:51:12 +0300 Subject: [PATCH 1/7] chore(assignments): update translation keys --- .../import_export/export/useExport.tsx | 30 ++++++++- src/services/dexie/assignment.ts | 66 ++++++++++++++----- 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/src/features/congregation/settings/import_export/export/useExport.tsx b/src/features/congregation/settings/import_export/export/useExport.tsx index 1c9f264edf..4a31bc576f 100644 --- a/src/features/congregation/settings/import_export/export/useExport.tsx +++ b/src/features/congregation/settings/import_export/export/useExport.tsx @@ -15,6 +15,8 @@ import { schedulesState } from '@states/schedules'; import { sourcesState } from '@states/sources'; import { speakersCongregationsActiveState } from '@states/speakers_congregations'; import { visitingSpeakersActiveState } from '@states/visiting_speakers'; +import { assignmentState } from '@states/assignment'; +import { weekTypeState } from '@states/weekType'; const useExport = () => { const persons = useRecoilValue(personsState); @@ -27,6 +29,8 @@ const useExport = () => { const schedules = useRecoilValue(schedulesState); const sources = useRecoilValue(sourcesState); const visitingSpeakers = useRecoilValue(visitingSpeakersActiveState); + const assignments = useRecoilValue(assignmentState); + const weekTypes = useRecoilValue(weekTypeState); const speakersCongregations = useRecoilValue( speakersCongregationsActiveState ); @@ -48,6 +52,28 @@ const useExport = () => { return app_settings; }; + const handleGetAssignments = () => { + const assignmentsList = assignments.map((record) => { + return { + code: record.code, + assignment_type_name: record.assignment_type_name.E, + }; + }); + + return assignmentsList; + }; + + const handleGetWeekTypes = () => { + const weekTypesList = weekTypes.map((record) => { + return { + id: record.id, + week_type_name: record.week_type_name.EN, + }; + }); + + return weekTypesList; + }; + const handleDownload = async () => { if (isProcessing) return; @@ -59,6 +85,7 @@ const useExport = () => { exported: new Date().toISOString(), version: import.meta.env.PACKAGE_VERSION, data: { + assignments: handleGetAssignments(), app_settings: handleGetSettings(), branch_cong_analysis: branchCongAnalysis, branch_field_service_reports: branchFieldReports, @@ -70,10 +97,11 @@ const useExport = () => { sources, speakers_congregations: speakersCongregations, visiting_speakers: visitingSpeakers, + week_type: handleGetWeekTypes(), }, }; - const prettyJsonData = JSON.stringify(backupData, null, 2); + const prettyJsonData = JSON.stringify(backupData); const blob = new Blob([prettyJsonData], { type: 'application/json' }); diff --git a/src/services/dexie/assignment.ts b/src/services/dexie/assignment.ts index 8c1fcea96c..20af5b9ee8 100644 --- a/src/services/dexie/assignment.ts +++ b/src/services/dexie/assignment.ts @@ -89,14 +89,31 @@ export const dbAssignmentUpdate = async () => { key: 'tr_memorialInviteVideo', language: lang.locale, }); - chairmanMMObj[langCode] = getTranslation({ - key: 'tr_chairmanMidweekMeeting', - language: lang.locale, - }); - prayerMMObj[langCode] = getTranslation({ - key: 'tr_prayerMidweekMeeting', - language: lang.locale, - }); + + chairmanMMObj[langCode] = + getTranslation({ + key: 'tr_chairman', + language: lang.locale, + }) + + ' (' + + getTranslation({ + key: 'tr_midweekMeeting', + language: lang.locale, + }) + + ')'; + + prayerMMObj[langCode] = + getTranslation({ + key: 'tr_prayer', + language: lang.locale, + }) + + ' ' + + getTranslation({ + key: 'tr_midweekMeeting', + language: lang.locale, + }) + + ')'; + tgwTalkObj[langCode] = getTranslation({ key: 'tr_tgwTalk', language: lang.locale, @@ -125,14 +142,31 @@ export const dbAssignmentUpdate = async () => { key: 'tr_returnVisitVariations', language: lang.locale, }); - chairmanWMObj[langCode] = getTranslation({ - key: 'tr_chairmanWeekendMeeting', - language: lang.locale, - }); - prayerWMObj[langCode] = getTranslation({ - key: 'tr_prayerWeekendMeeting', - language: lang.locale, - }); + + chairmanWMObj[langCode] = + getTranslation({ + key: 'tr_chairman', + language: lang.locale, + }) + + ' (' + + getTranslation({ + key: 'tr_weekendMeeting', + language: lang.locale, + }) + + ')'; + + prayerWMObj[langCode] = + getTranslation({ + key: 'tr_prayer', + language: lang.locale, + }) + + ' (' + + getTranslation({ + key: 'tr_weekendMeeting', + language: lang.locale, + }) + + ')'; + speakerObj[langCode] = getTranslation({ key: 'tr_speaker', language: lang.locale, From a96cf52ea5505da6c0b63a177294400bb17e3cfe Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:59:15 +0300 Subject: [PATCH 2/7] fix(dashboard): welcome banner not closing for pocket user --- src/features/app_start/pocket/signup/useSignup.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/features/app_start/pocket/signup/useSignup.tsx b/src/features/app_start/pocket/signup/useSignup.tsx index e55deb9fec..96e2f5140c 100644 --- a/src/features/app_start/pocket/signup/useSignup.tsx +++ b/src/features/app_start/pocket/signup/useSignup.tsx @@ -102,6 +102,7 @@ const useSignup = () => { 'cong_settings.cong_circuit': app_settings.cong_settings.cong_circuit, 'cong_settings.midweek_meeting': midweekMeeting, 'cong_settings.weekend_meeting': weekendMeeting, + 'cong_settings.cong_new': false, }); await handleLoadApp(); From 98e5fce06d81597d19807764745a6f6379658ea4 Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 20:44:31 +0300 Subject: [PATCH 3/7] chore(features): restructure to avoid circular dependency --- src/features/demo/start/index.tsx | 4 +- src/features/index.ts | 69 ------------------- src/features/persons/enrollments/index.tsx | 4 +- src/features/persons/privileges/index.tsx | 4 +- src/layouts/navbar/index.tsx | 10 ++- src/layouts/root_layout/index.tsx | 28 ++++---- src/pages/dashboard/congregation/index.tsx | 3 +- .../dashboard/meeting_materials/index.tsx | 3 +- src/pages/dashboard/meetings/index.tsx | 3 +- src/pages/dashboard/ministry/index.tsx | 4 +- src/pages/dashboard/persons/index.tsx | 3 +- src/pages/dashboard/reports/index.tsx | 3 +- .../public_talks_list/index.tsx | 6 +- src/pages/meetings/midweek/index.tsx | 8 +-- src/pages/meetings/weekend/index.tsx | 3 +- src/pages/persons/all_persons/index.tsx | 4 +- src/pages/persons/person_details/index.tsx | 24 +++---- 17 files changed, 58 insertions(+), 125 deletions(-) delete mode 100644 src/features/index.ts diff --git a/src/features/demo/start/index.tsx b/src/features/demo/start/index.tsx index 5419c7a302..48f492ce63 100644 --- a/src/features/demo/start/index.tsx +++ b/src/features/demo/start/index.tsx @@ -4,7 +4,7 @@ import useStart from './useStart'; import AppLoading from '@components/loading'; import Typography from '@components/typography'; -const DemoStatup = () => { +const DemoStartup = () => { const { t } = useAppTranslation(); useStart(); @@ -42,4 +42,4 @@ const DemoStatup = () => { ); }; -export default DemoStatup; +export default DemoStartup; diff --git a/src/features/index.ts b/src/features/index.ts deleted file mode 100644 index 4b1376392a..0000000000 --- a/src/features/index.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* ------------------------------- App Startup ------------------------------ */ -export { Startup } from './app_start'; -export { default as UnsupportedBrowser } from './app_start/shared/unsupported_browser'; - -/* ---------------------------------- About --------------------------------- */ -export { default as About } from './about'; - -/* ------------------------------ App Feedback ------------------------------ */ -export { default as AppFeedback } from './app_feedback'; - -/* ---------------------------- App Notifications --------------------------- */ -export { default as AppNotification } from './app_notification'; - -/* ------------------------------- App Updater ------------------------------ */ -export { default as AppUpdater } from './app_updater'; - -/* -------------------------- Color scheme selector ------------------------- */ -export { default as ColorSchemeSelector } from './color_scheme_selector'; - -/* --------------------------------- Contact -------------------------------- */ -export { default as Contact } from './contact'; - -/* -------------------------------- Dashboard ------------------------------- */ -export { default as DashboardCard } from './dashboard/card'; -export { default as DashboardMenu } from './dashboard/menu'; -export { default as DashboardSkeletonLoader } from './dashboard/skeleton_loader'; - -/* ---------------------------------- Demo ---------------------------------- */ -export { default as DemoBanner } from './demo/banner'; -export { default as DemoNotice } from './demo/notice'; -export { default as DemoStartup } from './demo/start'; - -/* ---------------------------- Meeting material ---------------------------- */ -export { default as EPUBMaterialsImport } from './meeting_materials/epub_import'; -export { default as JWMaterialsImport } from './meeting_materials/jw_import'; -export { default as PublicTalks } from './meeting_materials/public_talks'; - -/* ---------------------------- Language Switcher --------------------------- */ -export { default as LanguageSwitcher } from './language_switcher'; - -/* --------------------------------- Support -------------------------------- */ -export { default as Support } from './support'; - -/* ----------------------------- Theme Switcher ----------------------------- */ -export { default as ThemeSwitcher } from './theme_switcher'; - -/* -------------------------------- Meetings -------------------------------- */ -export { default as MidweekExport } from './meetings/midweek_export'; -export { default as MyAssignments } from './meetings/my_assignments'; -export { default as ScheduleAutofillDialog } from './meetings/schedule_autofill'; -export { default as WeekSelector } from './meetings/week_selector'; - -/* --------------------------------- Persons -------------------------------- */ -export { default as PersonAssignment } from './persons/assignments'; -export { default as PersonBasicInfo } from './persons/basic_info'; -export { default as PersonButtonActions } from './persons/button_actions'; -export { default as PersonEmergencyContacts } from './persons/emergency_contacts'; -export { default as PersonEnrollments } from './persons/enrollments'; -export { default as PersonPrivileges } from './persons/privileges'; -export { default as PersonSpiritualStatus } from './persons/spiritual_status'; -export { default as PersonsFilter } from './persons/filter'; -export { default as PersonsList } from './persons/list'; -export { default as PersonsSearch } from './persons/search'; -export { default as PersonTimeAway } from './persons/time_away'; -export { default as PersonAssignmentsHistory } from './persons/assignments_history'; -export { default as PersonAppUserProfile } from './persons/app_user_profile'; - -/* -------------------------------- Ministry -------------------------------- */ -export { default as MinistryTimer } from './ministry/report/ministry_timer'; diff --git a/src/features/persons/enrollments/index.tsx b/src/features/persons/enrollments/index.tsx index fb381d5db7..481bd441e1 100644 --- a/src/features/persons/enrollments/index.tsx +++ b/src/features/persons/enrollments/index.tsx @@ -6,7 +6,7 @@ import Button from '@components/button'; import EnrollmentItem from './enrollment_item'; import Typography from '@components/typography'; -const Enrollments = () => { +const PersonEnrollments = () => { const { t } = useAppTranslation(); const { isPersonEditor } = useCurrentUser(); @@ -74,4 +74,4 @@ const Enrollments = () => { ); }; -export default Enrollments; +export default PersonEnrollments; diff --git a/src/features/persons/privileges/index.tsx b/src/features/persons/privileges/index.tsx index 3bcbf77a3e..a2b4b0f383 100644 --- a/src/features/persons/privileges/index.tsx +++ b/src/features/persons/privileges/index.tsx @@ -6,7 +6,7 @@ import Button from '@components/button'; import Typography from '@components/typography'; import PrivilegeItem from './privilege_item'; -const Privileges = () => { +const PersonPrivileges = () => { const { t } = useAppTranslation(); const { isPersonEditor } = useCurrentUser(); @@ -76,4 +76,4 @@ const Privileges = () => { ); }; -export default Privileges; +export default PersonPrivileges; diff --git a/src/layouts/navbar/index.tsx b/src/layouts/navbar/index.tsx index e389df8f10..770b6fc27f 100644 --- a/src/layouts/navbar/index.tsx +++ b/src/layouts/navbar/index.tsx @@ -20,18 +20,16 @@ import { IconMail, IconArrowLink, } from '@icons/index'; -import { - AppNotification, - DemoBanner, - LanguageSwitcher, - ThemeSwitcher, -} from '@features/index'; import { useAppTranslation } from '@hooks/index'; import { isDemo } from '@constants/index'; import { NavBarType } from './index.types'; import useNavbar from './useNavbar'; import AccountHeaderIcon from '@components/account_header_icon'; +import AppNotification from '@features/app_notification'; import Button from '@components/button'; +import DemoBanner from '@features/demo/banner'; +import LanguageSwitcher from '@features/language_switcher'; +import ThemeSwitcher from '@features/theme_switcher'; import Typography from '@components/typography'; const baseMenuStyle = { diff --git a/src/layouts/root_layout/index.tsx b/src/layouts/root_layout/index.tsx index 06bb55850a..3321b5c304 100644 --- a/src/layouts/root_layout/index.tsx +++ b/src/layouts/root_layout/index.tsx @@ -3,31 +3,29 @@ import { Outlet } from 'react-router-dom'; import { Box, Container, Toolbar } from '@mui/material'; import { IconClose } from '@components/icons'; import { AppModalWrapper } from '@wrapper/index'; -import { - About, - AppFeedback, - AppUpdater, - Contact, - DemoNotice, - DemoStartup, - EPUBMaterialsImport, - JWMaterialsImport, - MyAssignments, - Startup, - Support, - UnsupportedBrowser, -} from '@features/index'; +import { Startup } from '@features/app_start'; import { isDemo } from '@constants/index'; import useGlobal from '@hooks/useGlobal'; import useRootLayout from './useRootLayout'; +import About from '@features/about'; +import AppFeedback from '@features/app_feedback'; +import AppReminders from '@features/reminders'; +import AppUpdater from '@features/app_updater'; +import Contact from '@features/contact'; import DashboardSkeletonLoader from '@features/dashboard/skeleton_loader'; +import DemoNotice from '@features/demo/notice'; +import DemoStartup from '@features/demo/start'; +import EPUBMaterialsImport from '@features/meeting_materials/epub_import'; import InitialSetup from '@features/dashboard/initial_setup'; import JWAutoImport from '@features/meeting_materials/jw_auto_import'; +import JWMaterialsImport from '@features/meeting_materials/jw_import'; import MigrationNotice from '@features/migration'; +import MyAssignments from '@features/meetings/my_assignments'; import NavBar from '@layouts/navbar'; +import Support from '@features/support'; +import UnsupportedBrowser from '@features/app_start/shared/unsupported_browser'; import WaitingLoader from '@components/waiting_loader'; import WhatsNew from '@features/whats_new'; -import AppReminders from '@features/reminders'; const RootLayout = ({ updatePwa }: { updatePwa: VoidFunction }) => { const { isSupported } = useGlobal(); diff --git a/src/pages/dashboard/congregation/index.tsx b/src/pages/dashboard/congregation/index.tsx index 22523914cc..80a68e6b7e 100644 --- a/src/pages/dashboard/congregation/index.tsx +++ b/src/pages/dashboard/congregation/index.tsx @@ -1,5 +1,4 @@ import { ListItem } from '@mui/material'; -import { DashboardCard, DashboardMenu } from '@features/index'; import { IconGroups, IconManageAccess, @@ -8,6 +7,8 @@ import { } from '@icons/index'; import { useAppTranslation, useCurrentUser } from '@hooks/index'; import useCongregation from './useCongregation'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; const CongregationCard = () => { const { t } = useAppTranslation(); diff --git a/src/pages/dashboard/meeting_materials/index.tsx b/src/pages/dashboard/meeting_materials/index.tsx index d53bbf5a51..f5990d4da1 100644 --- a/src/pages/dashboard/meeting_materials/index.tsx +++ b/src/pages/dashboard/meeting_materials/index.tsx @@ -1,8 +1,9 @@ import { ListItem } from '@mui/material'; -import { DashboardCard, DashboardMenu } from '@features/index'; import { IconImportFile, IconJwOrg, IconPodium } from '@icons/index'; import { useAppTranslation } from '@hooks/index'; import useMeetingMaterials from './useMeetingMaterials'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; const MeetingsMaterialsCard = () => { const { t } = useAppTranslation(); diff --git a/src/pages/dashboard/meetings/index.tsx b/src/pages/dashboard/meetings/index.tsx index ead8f5f8db..0bb048b907 100644 --- a/src/pages/dashboard/meetings/index.tsx +++ b/src/pages/dashboard/meetings/index.tsx @@ -1,5 +1,4 @@ import { ListItem } from '@mui/material'; -import { DashboardCard, DashboardMenu } from '@features/index'; import { IconAssignment, IconCalendarWeek, @@ -9,6 +8,8 @@ import { import { useAppTranslation, useCurrentUser } from '@hooks/index'; import { MeetingsCardProps } from './index.types'; import useMeetings from './useMeetings'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; const MeetingsCard = ({ assignmentCount }: MeetingsCardProps) => { const { t } = useAppTranslation(); diff --git a/src/pages/dashboard/ministry/index.tsx b/src/pages/dashboard/ministry/index.tsx index 8395a2e30d..fec469a589 100644 --- a/src/pages/dashboard/ministry/index.tsx +++ b/src/pages/dashboard/ministry/index.tsx @@ -4,9 +4,11 @@ import { IconPioneerForm, IconStatsYear, } from '@icons/index'; -import { DashboardCard, DashboardMenu, MinistryTimer } from '@features/index'; import { useAppTranslation } from '@hooks/index'; import useMinistry from './useMinistry'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; +import MinistryTimer from '@features/ministry/report/ministry_timer'; const MinistryCard = () => { const { t } = useAppTranslation(); diff --git a/src/pages/dashboard/persons/index.tsx b/src/pages/dashboard/persons/index.tsx index 786d301eb4..c1539dd59a 100644 --- a/src/pages/dashboard/persons/index.tsx +++ b/src/pages/dashboard/persons/index.tsx @@ -1,5 +1,4 @@ import { ListItem } from '@mui/material'; -import { DashboardCard, DashboardMenu } from '@features/index'; import { IconAddPerson, IconApplications, @@ -8,6 +7,8 @@ import { } from '@icons/index'; import { useAppTranslation, useCurrentUser } from '@hooks/index'; import usePersons from './usePersons'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; const PersonsCard = () => { const { t } = useAppTranslation(); diff --git a/src/pages/dashboard/reports/index.tsx b/src/pages/dashboard/reports/index.tsx index 2737dccb4a..5a1ae77054 100644 --- a/src/pages/dashboard/reports/index.tsx +++ b/src/pages/dashboard/reports/index.tsx @@ -1,5 +1,4 @@ import { ListItem } from '@mui/material'; -import { DashboardCard, DashboardMenu } from '@features/index'; import { IconPublisherRecordCard, IconPublishersReports, @@ -7,6 +6,8 @@ import { IconVisitors, } from '@icons/index'; import { useAppTranslation, useCurrentUser } from '@hooks/index'; +import DashboardCard from '@features/dashboard/card'; +import DashboardMenu from '@features/dashboard/menu'; const ReportsCard = () => { const { t } = useAppTranslation(); diff --git a/src/pages/meeting_materials/public_talks_list/index.tsx b/src/pages/meeting_materials/public_talks_list/index.tsx index 66d88b6276..53d7659cde 100644 --- a/src/pages/meeting_materials/public_talks_list/index.tsx +++ b/src/pages/meeting_materials/public_talks_list/index.tsx @@ -1,10 +1,10 @@ import { Box } from '@mui/material'; import { IconExport, IconListView, IconSpreadsheet } from '@components/icons'; +import { useAppTranslation, useBreakpoints } from '@hooks/index'; +import usePublicTalksList from './usePublicTalksList'; import Button from '@components/button'; import PageTitle from '@components/page_title'; -import usePublicTalksList from './usePublicTalksList'; -import { useAppTranslation, useBreakpoints } from '@hooks/index'; -import { PublicTalks } from '@features/index'; +import PublicTalks from '@features/meeting_materials/public_talks'; const PublicTalksList = () => { const { t } = useAppTranslation(); diff --git a/src/pages/meetings/midweek/index.tsx b/src/pages/meetings/midweek/index.tsx index 36ad1360f1..16907b8058 100644 --- a/src/pages/meetings/midweek/index.tsx +++ b/src/pages/meetings/midweek/index.tsx @@ -1,17 +1,15 @@ import { Box } from '@mui/material'; import { IconGenerate, IconPrint, IconPublish } from '@components/icons'; -import { - MidweekExport, - ScheduleAutofillDialog, - WeekSelector, -} from '@features/index'; import { useAppTranslation, useBreakpoints } from '@hooks/index'; import useMidweek from './useMidweek'; import Button from '@components/button'; import MidweekEditor from '@features/meetings/midweek_editor'; +import MidweekExport from '@features/meetings/midweek_export'; import PageTitle from '@components/page_title'; import QuickSettingsMidweekMeeting from '@features/meetings/midweek_editor/quick_settings'; import SchedulePublish from '@features/meetings/schedule_publish'; +import ScheduleAutofillDialog from '@features/meetings/schedule_autofill'; +import WeekSelector from '@features/meetings/week_selector'; const MidweekMeeting = () => { const { t } = useAppTranslation(); diff --git a/src/pages/meetings/weekend/index.tsx b/src/pages/meetings/weekend/index.tsx index cdb364a867..7ee1796557 100644 --- a/src/pages/meetings/weekend/index.tsx +++ b/src/pages/meetings/weekend/index.tsx @@ -1,15 +1,16 @@ import { Box } from '@mui/material'; import { IconGenerate, IconPrint, IconPublish } from '@components/icons'; -import { ScheduleAutofillDialog, WeekSelector } from '@features/index'; import { useAppTranslation, useBreakpoints } from '@hooks/index'; import useWeekend from './useWeekend'; import Button from '@components/button'; import OutgoingTalks from '@features/meetings/outgoing_talks'; import PageTitle from '@components/page_title'; import QuickSettingsWeekendMeeting from '@features/meetings/weekend_editor/quick_settings'; +import ScheduleAutofillDialog from '@features/meetings/schedule_autofill'; import SchedulePublish from '@features/meetings/schedule_publish'; import WeekendEditor from '@features/meetings/weekend_editor'; import WeekendExport from '@features/meetings/weekend_export'; +import WeekSelector from '@features/meetings/week_selector'; const WeekendMeeting = () => { const { t } = useAppTranslation(); diff --git a/src/pages/persons/all_persons/index.tsx b/src/pages/persons/all_persons/index.tsx index c67244b638..85aa41abfb 100644 --- a/src/pages/persons/all_persons/index.tsx +++ b/src/pages/persons/all_persons/index.tsx @@ -10,8 +10,10 @@ import { useBreakpoints, useCurrentUser, } from '@hooks/index'; -import { PersonsFilter, PersonsList, PersonsSearch } from '@features/index'; import useAllPersons from './useAllPersons'; +import PersonsList from '@features/persons/list'; +import PersonsFilter from '@features/persons/filter'; +import PersonsSearch from '@features/persons/search'; const PersonsAll = () => { const { t } = useAppTranslation(); diff --git a/src/pages/persons/person_details/index.tsx b/src/pages/persons/person_details/index.tsx index f1d086083f..eda3d527af 100644 --- a/src/pages/persons/person_details/index.tsx +++ b/src/pages/persons/person_details/index.tsx @@ -5,19 +5,17 @@ import { useBreakpoints, useCurrentUser, } from '@hooks/index'; -import { - PersonAppUserProfile, - PersonAssignment, - PersonAssignmentsHistory, - PersonBasicInfo, - PersonButtonActions, - PersonEmergencyContacts, - PersonEnrollments, - PersonPrivileges, - PersonSpiritualStatus, - PersonTimeAway, -} from '@features/index'; import usePersonDetails from './usePersonDetails'; +import PersonAppUserProfile from '@features/persons/app_user_profile'; +import PersonButtonActions from '@features/persons/button_actions'; +import PersonBasicInfo from '@features/persons/basic_info'; +import PersonEnrollments from '@features/persons/enrollments'; +import PersonSpiritualStatus from '@features/persons/spiritual_status'; +import PersonPrivileges from '@features/persons/privileges'; +import PersonTimeAway from '@features/persons/time_away'; +import PersonEmergencyContacts from '@features/persons/emergency_contacts'; +import PersonAssignmentsHistory from '@features/persons/assignments_history'; +import PersonAssignments from '@features/persons/assignments'; const PersonDetails = () => { const { t } = useAppTranslation(); @@ -86,7 +84,7 @@ const PersonDetails = () => { flexDirection: 'column', }} > - + {!isNewPerson && } From 50efb949dd7fb75fdb56dcfcf97d75bf48c15cf0 Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:45:53 +0300 Subject: [PATCH 4/7] feat(persons): add shortcut to navigate to manage access page --- src/definition/api.ts | 3 +- .../persons/app_user_profile/index.tsx | 39 ++++------ .../app_user_profile/useAppUserProfile.tsx | 76 ++++++++++--------- .../persons/all_persons/useAllPersons.tsx | 25 +++++- src/pages/persons/person_details/index.tsx | 8 +- .../person_details/usePersonDetails.tsx | 5 +- 6 files changed, 89 insertions(+), 67 deletions(-) diff --git a/src/definition/api.ts b/src/definition/api.ts index 5bf8ce1b5a..d0a07365df 100644 --- a/src/definition/api.ts +++ b/src/definition/api.ts @@ -26,7 +26,7 @@ export type SessionResponseType = { os: string; isMobile: boolean; }; - last_seen: number; + last_seen: string; }; export type CongregationCreateResponseType = { @@ -241,6 +241,7 @@ export type CongregationUserType = { user_local_uid: string; user_members_delegate: string[]; pocket_invitation_code?: string; + createdAt?: string; }; sessions?: SessionResponseType[]; }; diff --git a/src/features/persons/app_user_profile/index.tsx b/src/features/persons/app_user_profile/index.tsx index b5fbfc598d..4d88468e9c 100644 --- a/src/features/persons/app_user_profile/index.tsx +++ b/src/features/persons/app_user_profile/index.tsx @@ -1,17 +1,15 @@ import { Box } from '@mui/material'; -import usePersonAppPersonProfile from './useAppUserProfile'; -import Typography from '@components/typography'; +import { IconAddPerson, IconArrowLink } from '@components/icons'; import { useAppTranslation } from '@hooks/index'; +import useAppUserProfile from './useAppUserProfile'; import Button from '@components/button'; -import { IconAddPerson, IconArrowLink } from '@components/icons'; +import Typography from '@components/typography'; +import Markup from '@components/text_markup'; const PersonAppUserProfile = () => { const { t } = useAppTranslation(); - const { - userIsRegistered, - getTextForAppPersonProfileDesc, - navigateToManageAccess, - } = usePersonAppPersonProfile(); + + const { navigateToManageAccess, userDescription, user } = useAppUserProfile(); return ( { display: 'flex', flexDirection: 'column', borderRadius: 'var(--radius-xl)', - backgroundColor: userIsRegistered - ? 'var(--white)' - : 'var(--accent-150)', - border: `1px ${userIsRegistered ? 'solid' : 'dashed'} var(--accent-300)`, + backgroundColor: user ? 'var(--white)' : 'var(--accent-150)', + border: `1px ${user ? 'solid' : 'dashed'} var(--accent-300)`, }} > { flexDirection: 'column', }} > - - {t('tr_appUserProfile')} - - + {t('tr_appUserProfile')} + + ); diff --git a/src/features/persons/app_user_profile/useAppUserProfile.tsx b/src/features/persons/app_user_profile/useAppUserProfile.tsx index 86d2bb0d99..e6f0cd8e7d 100644 --- a/src/features/persons/app_user_profile/useAppUserProfile.tsx +++ b/src/features/persons/app_user_profile/useAppUserProfile.tsx @@ -1,62 +1,66 @@ -import { CongregationUserType } from '@definition/api'; +import { useMemo } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { useAppTranslation } from '@hooks/index'; import { formatDate } from '@services/dateformat'; -import { congregationsPersonsState } from '@states/app'; +import { congregationUsersState } from '@states/app'; import { personCurrentDetailsState } from '@states/persons'; import { shortDateFormatState } from '@states/settings'; -import { useNavigate } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; -const usePersonAppPersonProfile = () => { +const useAppUserProfile = () => { + const navigate = useNavigate(); + const { t } = useAppTranslation(); - const congregationsPersons = useRecoilValue(congregationsPersonsState); + + const congregationsUsers = useRecoilValue(congregationUsersState); const currentPersonDetails = useRecoilValue(personCurrentDetailsState); const shortDateFormat = useRecoilValue(shortDateFormatState); - const navigate = useNavigate(); - const userIsRegistered: boolean = congregationsPersons.some( - (person) => - person.profile.user_local_uid === currentPersonDetails.person_uid - ); - - const currentPersonInCongragation: CongregationUserType = - congregationsPersons.find( + const user = useMemo(() => { + return congregationsUsers.find( (person) => person.profile.user_local_uid === currentPersonDetails.person_uid ); + }, [congregationsUsers, currentPersonDetails]); + + const last_seen = useMemo(() => { + if (!user) return; + + if (!user.sessions) return; + + if (user.sessions.length === 0) return; - const getTextForAppPersonProfileDesc = () => { - if (userIsRegistered) { - const lastTimeOnline = currentPersonInCongragation.sessions[0]?.last_seen; + const last = user.sessions + .sort((a, b) => b.last_seen.localeCompare(a.last_seen)) + .at(0); - const formattedLastTimeOnline = lastTimeOnline - ? formatDate(new Date(lastTimeOnline), shortDateFormat) - : t('tr_notYet'); + return last.last_seen; + }, [user]); - return t('tr_appUserProfileRegisteredDesc', { - lastTimeOnline: formattedLastTimeOnline, - }); + const userDescription = useMemo(() => { + if (!user) { + return t('tr_appUserProfileNotRegisteredDesc'); } - return t('tr_appUserProfileNotRegisteredDesc'); - }; + const createdFormatted = last_seen + ? formatDate(new Date(last_seen), shortDateFormat) + : t('tr_notYet'); + + return t('tr_appUserProfileRegisteredDesc', { + lastTimeOnline: createdFormatted, + }); + }, [user, t, shortDateFormat, last_seen]); const navigateToManageAccess = () => { - if (userIsRegistered) { - navigate(`/manage-access/${currentPersonInCongragation.id}`); + if (user) { + navigate(`/manage-access/${user.id}`); return; } - navigate(`/manage-access/`); - return; + navigate(`/manage-access`); }; - return { - userIsRegistered, - currentPersonInCongragation, - getTextForAppPersonProfileDesc, - navigateToManageAccess, - }; + return { user, userDescription, navigateToManageAccess }; }; -export default usePersonAppPersonProfile; +export default useAppUserProfile; diff --git a/src/pages/persons/all_persons/useAllPersons.tsx b/src/pages/persons/all_persons/useAllPersons.tsx index c8b3e439bc..f00ced0f1f 100644 --- a/src/pages/persons/all_persons/useAllPersons.tsx +++ b/src/pages/persons/all_persons/useAllPersons.tsx @@ -1,17 +1,34 @@ +import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import { useRecoilState, useRecoilValue } from 'recoil'; +import { useQuery } from '@tanstack/react-query'; +import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; import { personCurrentDetailsState, personsFilterOpenState, } from '@states/persons'; import { setPersonCurrentDetails } from '@services/recoil/persons'; +import { apiCongregationUsersGet } from '@services/api/congregation'; +import { congAccountConnectedState, congregationUsersState } from '@states/app'; +import useCurrentUser from '@hooks/useCurrentUser'; const useAllPersons = () => { const navigate = useNavigate(); + const { isAdmin } = useCurrentUser(); + const [isPanelOpen, setIsPanelOpen] = useRecoilState(personsFilterOpenState); + const setUsers = useSetRecoilState(congregationUsersState); + const person = useRecoilValue(personCurrentDetailsState); + const isConnected = useRecoilValue(congAccountConnectedState); + + const { data } = useQuery({ + queryKey: ['congregation_users'], + queryFn: apiCongregationUsersGet, + refetchOnMount: 'always', + enabled: isConnected && isAdmin, + }); const handlePersonAdd = async () => { const newPerson = structuredClone(person); @@ -22,6 +39,12 @@ const useAllPersons = () => { navigate('/persons/new'); }; + useEffect(() => { + if (data && Array.isArray(data?.users)) { + setUsers(data.users); + } + }, [setUsers, data]); + return { handlePersonAdd, isPanelOpen, diff --git a/src/pages/persons/person_details/index.tsx b/src/pages/persons/person_details/index.tsx index eda3d527af..54b633bd44 100644 --- a/src/pages/persons/person_details/index.tsx +++ b/src/pages/persons/person_details/index.tsx @@ -22,9 +22,9 @@ const PersonDetails = () => { const { desktopUp, laptopUp } = useBreakpoints(); - const { isPersonEditor } = useCurrentUser(); + const { isPersonEditor, isAdmin } = useCurrentUser(); - const { isNewPerson, isBaptized, male } = usePersonDetails(); + const { isNewPerson, isBaptized, male, isConnected } = usePersonDetails(); return ( @@ -52,7 +52,9 @@ const PersonDetails = () => { }} > - {!isNewPerson && } + + {!isNewPerson && isConnected && isAdmin && } + {isBaptized && ( diff --git a/src/pages/persons/person_details/usePersonDetails.tsx b/src/pages/persons/person_details/usePersonDetails.tsx index 3b52a9fcd5..3dae5050bb 100644 --- a/src/pages/persons/person_details/usePersonDetails.tsx +++ b/src/pages/persons/person_details/usePersonDetails.tsx @@ -3,6 +3,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { useRecoilState, useRecoilValue } from 'recoil'; import { personCurrentDetailsState, personsActiveState } from '@states/persons'; import { personSchema } from '@services/dexie/schema'; +import { congAccountConnectedState } from '@states/app'; const usePersonDetails = () => { const { id } = useParams(); @@ -11,7 +12,9 @@ const usePersonDetails = () => { const isNewPerson = id === undefined; const [person, setPerson] = useRecoilState(personCurrentDetailsState); + const persons = useRecoilValue(personsActiveState); + const isConnected = useRecoilValue(congAccountConnectedState); const isBaptized = useMemo(() => { return person.person_data.publisher_baptized.active.value; @@ -42,7 +45,7 @@ const usePersonDetails = () => { } }, [id, persons, navigate, isNewPerson, setPerson]); - return { isNewPerson, isBaptized, male }; + return { isNewPerson, isBaptized, male, isConnected }; }; export default usePersonDetails; From 8af50fd2e131c465cffb9c68be2415393cafe69f Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:56:42 +0300 Subject: [PATCH 5/7] fix(startup): incorrect display of congregation create window --- src/features/app_start/vip/startup/useStartup.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/features/app_start/vip/startup/useStartup.tsx b/src/features/app_start/vip/startup/useStartup.tsx index cb9375ba24..839d2c62e8 100644 --- a/src/features/app_start/vip/startup/useStartup.tsx +++ b/src/features/app_start/vip/startup/useStartup.tsx @@ -147,6 +147,7 @@ const useStartup = () => { if ( isAuthenticated && + congName.length === 0 && (remoteMasterKey.length === 0 || remoteAccessCode.length === 0) ) { setCongID(result.cong_id); From fedc5a1c8a86761944dafae3dcdf6e928e7a19da Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:58:29 +0300 Subject: [PATCH 6/7] chore(assignments): fix typo in midweek prayer --- src/services/dexie/assignment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/dexie/assignment.ts b/src/services/dexie/assignment.ts index 20af5b9ee8..72ac6d3d95 100644 --- a/src/services/dexie/assignment.ts +++ b/src/services/dexie/assignment.ts @@ -107,7 +107,7 @@ export const dbAssignmentUpdate = async () => { key: 'tr_prayer', language: lang.locale, }) + - ' ' + + ' (' + getTranslation({ key: 'tr_midweekMeeting', language: lang.locale, From b21fe8ebb418ccea78ded5f25c6e63c6c858315d Mon Sep 17 00:00:00 2001 From: rhahao <26148770+rhahao@users.noreply.github.com> Date: Tue, 10 Dec 2024 22:02:09 +0300 Subject: [PATCH 7/7] chore(persons): update sorting option to get last seen --- src/features/persons/app_user_profile/useAppUserProfile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/persons/app_user_profile/useAppUserProfile.tsx b/src/features/persons/app_user_profile/useAppUserProfile.tsx index e6f0cd8e7d..302a36f297 100644 --- a/src/features/persons/app_user_profile/useAppUserProfile.tsx +++ b/src/features/persons/app_user_profile/useAppUserProfile.tsx @@ -31,7 +31,7 @@ const useAppUserProfile = () => { if (user.sessions.length === 0) return; const last = user.sessions - .sort((a, b) => b.last_seen.localeCompare(a.last_seen)) + .toSorted((a, b) => b.last_seen.localeCompare(a.last_seen)) .at(0); return last.last_seen;