import { getSession, useSession } from "next-auth/react"; import useTranslation from "next-translate/useTranslation"; import Head from "next/head"; import { useRouter } from "next/router"; import { connect } from "react-redux"; import pLimit from "p-limit"; import { getIP } from "../../actions/core/logger"; import { consoleLogger } from "../../actions/core/logger"; import { getPersonalAccount, getPortalLogin } from "../../actions/services/accountService"; import { getCase, getPortalModuleDetails } from "../../actions/services/caseService"; import { createContainerProxy, getAwaitingSubmissionFromBlob, getRepsFromBlob } from "../../actions/services/documentService"; import { getMyCases, getMyLPACases, getWatchedCases } from "../../actions/services/portalService"; import { splitWatchedCasesBySubmissionState } from "../../lib/domain/dashboard-policy"; import Breadcrumbs from "../../components/breadcrumbs"; import CookieBanner from "../../components/cookieBanner"; import Footer from "../../components/footer"; import Header from "../../components/header"; import MyPortal from "../../components/myportal"; import { getFormCollectionByID } from "../../components/utils"; import { setAccountDetails, setContainerID, setLoggedInUserId } from "../../store/accountDetails/action"; import { setAwaitingSubmissionDetails, setAwaitingSubmissionFromBlob } from "../../store/awaitingSubmission/action"; import { setShowReps, setLocale } from "../../store/currentView/action"; import { setMyCases, setMyCasesDetails } from "../../store/myCases/action"; import { setMyRepresentations, setMyRepresentationsDetails, setMySubmittedReps, setMySubmittedRepsDetails } from "../../store/myRepresentations/action"; import { wrapper } from "../../store/store"; import { setWatchedCases, setWatchedCasesDetails } from "../../store/watchedCases/action"; const Home = (props) => { const { footerLinks, myCases, myRepresentations, watchedCases, awaitingSubmission, accountDetails, showFileUpload, showLoginCheck, currentView, mySubmittedReps, docsOffline } = props; const { t } = useTranslation(); const router = useRouter(); const { locale, query } = router; const { appealtypes } = query; useSession(); // keeping original hook usage, even if not directly referenced return (
{t("myportal:page-title")} - {t("common:service-name")} <>
); }; export const getServerSideProps = wrapper.getServerSideProps( (store) => async (ctx) => { const { req, locale } = ctx; getIP(req); const cookies = req.cookies || {}; const thisSession = await getSession(ctx); if (!thisSession) { consoleLogger({ name: "MyPortalIndexAuthGuard", reasonCode: "NO_SESSION", message: "myportal index loader missing session; redirecting to signin" }); return { redirect: { destination: "/auth/signin", permanent: false } }; } if (!thisSession?.user?.email || !thisSession?.user?.id) { consoleLogger({ name: "MyPortalIndexAuthGuard", reasonCode: "NO_SESSION_USER", message: "myportal index loader missing session user identity; redirecting to signin", hasSessionUserEmail: !!thisSession?.user?.email, hasSessionUserId: !!thisSession?.user?.id }); return { redirect: { destination: "/auth/signin", permanent: false } }; } let contacts = []; try { const loggedInUserResponse = await getPortalLogin( thisSession.user.email ); contacts = loggedInUserResponse?.value || []; } catch (error) { consoleLogger({ name: "MyPortalIndexAuthGuard", reasonCode: "UPSTREAM_FAILURE", message: "myportal index loader portal login lookup failed; redirecting to signin", error: error?.message }); return { redirect: { destination: "/auth/signin", permanent: false } }; } if (contacts.length > 1) { return { redirect: { destination: locale === "cy" ? "/cy/manylionpellach" : "/furtherdetails", permanent: false } }; } const loggedInUser = contacts[0]?.contactid; if (!loggedInUser) { consoleLogger({ name: "MyPortalIndexAuthGuard", reasonCode: "CONTACT_LOOKUP_FAILED", message: "myportal index loader missing CRM contact id; redirecting to signin" }); return { redirect: { destination: "/auth/signin", permanent: false } }; } await createContainerProxy(thisSession.user.id); const accountDetails = await getPersonalAccount(loggedInUser); if (accountDetails?.errorCode) { return { redirect: { destination: "/myportal/error", permanent: false } }; } const lpaId = accountDetails[ "pinswg_contact_associatedlpa@OData.Community.Display.V1.FormattedValue" ]; const isLPA = accountDetails.pinswg_typeofinvolvement === 846040012; const [ myCases, myRepresentations, watchedCases, awaitingSubmissionFromBlob ] = await Promise.all([ isLPA ? getMyLPACases(lpaId) : getMyCases(loggedInUser), getRepsFromBlob(thisSession.user.id), getWatchedCases(loggedInUser), getAwaitingSubmissionFromBlob(thisSession.user.id) ]); // put current locale into store (this is the URL locale) store.dispatch(setLocale(locale)); // Determine preferred locale (cookie overrides account preference) let preferredLocale = accountDetails.pinswg_preferredlanguage === 846040000 ? "cy" : "en"; if (cookies.pedw_locale) preferredLocale = cookies.pedw_locale; // (Optional) redirect logic (kept commented as in your newer file) // const pathWithoutLocale = ctx.resolvedUrl.replace(/^\/(cy|en)/, ""); // if (preferredLocale !== locale) { // return { // redirect: { // destination: `/${preferredLocale}${pathWithoutLocale}`, // permanent: false, // }, // }; // } const showLoginCheck = Boolean(process.env.SHOWLOGIN); const showReps = Boolean(process.env.SHOWREPRESENTATIONS); store.dispatch(setShowReps(showReps, showLoginCheck)); const { watchedCases: filteredWatchedCases, submittedRepresentations: mySubmittedReps } = splitWatchedCasesBySubmissionState(watchedCases.value); // Newer getDetails implementation (bounded concurrency, fewer edge-case bugs) const getDetails = async (resultsObj, detailsType) => { const limitRequests = pLimit(5); const arr = []; const list = detailsType === "mySubmittedReps" ? resultsObj : resultsObj.value; const tasks = list.map((item) => limitRequests(async () => { try { let caseID = ""; switch (detailsType) { case "myCases": caseID = item.pinswg_title; break; case "myWatchedCases": case "mySubmittedReps": caseID = item[ "_pinswg_watchedcase_value@OData.Community.Display.V1.FormattedValue" ]; break; case "awaitingSubmission": caseID = item.ticketnumber; break; case "myRepresentations": caseID = item.casereference; break; default: caseID = item.pinswg_title; } if (!item.pinswg_appealcasetype) return; const collectionName = getFormCollectionByID( item.pinswg_appealcasetype ).LogicalCollectionName; const details = await getPortalModuleDetails( collectionName, caseID ); arr.push(details); } catch (err) { console.error("Error fetching details:", err); } }) ); await Promise.all(tasks); return arr; }; const [ myCasesDetails, watchedCasesDetails, mySubmittedRepsDetails, myRepresentationsDetails ] = await Promise.all([ getDetails(myCases, "myCases"), getDetails(filteredWatchedCases, "myWatchedCases"), getDetails(mySubmittedReps, "mySubmittedReps"), getDetails(myRepresentations, "myRepresentations") ]); store.dispatch(setAccountDetails(accountDetails)); store.dispatch(setLoggedInUserId(loggedInUser)); store.dispatch(setMyCases(myCases)); store.dispatch(setMyCasesDetails(myCasesDetails)); store.dispatch(setMyRepresentations(myRepresentations)); store.dispatch(setMyRepresentationsDetails(myRepresentationsDetails)); store.dispatch(setWatchedCases(filteredWatchedCases)); store.dispatch(setWatchedCasesDetails(watchedCasesDetails)); store.dispatch(setMySubmittedReps(mySubmittedReps)); store.dispatch(setMySubmittedRepsDetails(mySubmittedRepsDetails)); store.dispatch( setAwaitingSubmissionFromBlob(awaitingSubmissionFromBlob) ); store.dispatch( setAwaitingSubmissionDetails(awaitingSubmissionFromBlob) ); store.dispatch(setContainerID(thisSession.user.id)); return { props: { showFileUpload: Boolean(process.env.SHOWFILEUPLOAD), containerID: thisSession.user.id, showLoginCheck, docsOffline: process.env.DOCAPI_OFFLINE || false } }; } ); const mapStateToProps = (state) => ({ accountDetails: state.accountDetails, currentView: state.currentView, search: state.search, searchResultsObj: state.searchResultsObj, formData: state.formData, appealType: state.appealType, form: state.form, myCases: state.myCases, watchedCases: state.watchedCases, myRepresentations: state.myRepresentations, mySubmittedReps: state.myRepresentations.mySubmittedReps, awaitingSubmission: state.awaitingSubmission }); export default connect(mapStateToProps)(Home);