Created
May 2, 2023 19:02
-
-
Save AlexandroMtzG/4126c495c3bd29343f6cdbc83147c617 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { json, LoaderFunction, V2_MetaFunction } from "@remix-run/node"; | |
import { useLoaderData, useSearchParams } from "@remix-run/react"; | |
import { useAppData } from "~/utils/data/useAppData"; | |
import { DashboardLoaderData, loadDashboardData } from "~/utils/data/useDashboardData"; | |
import { i18nHelper } from "~/locale/i18n.utils"; | |
import { getAppDashboardStats } from "~/utils/services/appDashboardService"; | |
import ProfileBanner from "~/components/app/ProfileBanner"; | |
import { DashboardStats } from "~/components/ui/stats/DashboardStats"; | |
import { getTenantIdFromUrl } from "~/utils/services/urlService"; | |
import { Stat } from "~/application/dtos/stats/Stat"; | |
import InputSelector from "~/components/ui/input/InputSelector"; | |
import PeriodHelper, { defaultPeriodFilter, PeriodFilters } from "~/utils/helpers/PeriodHelper"; | |
import { useTranslation } from "react-i18next"; | |
import ServerError from "~/components/ui/errors/ServerError"; | |
import { getServerTiming } from "~/utils/performance/timing.server"; | |
import { serverTimingHeaders } from "~/utils/performance/defaults.server"; | |
export { serverTimingHeaders as headers }; | |
type LoaderData = DashboardLoaderData & { | |
title: string; | |
stats: Stat[]; | |
}; | |
export let loader: LoaderFunction = async ({ request, params }) => { | |
const { time, getServerTimingHeader } = getServerTiming(); | |
let { t } = await time("i18nHelper", i18nHelper(request)); | |
const tenantId = await time("getTenantIdFromUrl", getTenantIdFromUrl(params)); | |
const stats = await time("getAppDashboardStats", getAppDashboardStats({ t, tenantId, gte: PeriodHelper.getGreaterThanOrEqualsFromRequest({ request }) })); | |
const data: LoaderData = { | |
title: `${t("app.sidebar.dashboard")} | ${process.env.APP_NAME}`, | |
...(await time("loadDashboardData", loadDashboardData(params))), | |
stats, | |
}; | |
return json(data, { headers: getServerTimingHeader() }); | |
}; | |
export const meta: V2_MetaFunction = ({ data }) => [{ title: data?.title }]; | |
export default function DashboardRoute() { | |
const { t } = useTranslation(); | |
const appData = useAppData(); | |
const data = useLoaderData<LoaderData>(); | |
const [searchParams, setSearchParams] = useSearchParams(); | |
return ( | |
<main className="relative z-0 flex-1 overflow-y-auto pb-8"> | |
{/*Page header */} | |
<div className="hidden bg-white shadow md:block lg:border-t lg:border-gray-200"> | |
<ProfileBanner user={appData.user} /> | |
</div> | |
<div className="mx-auto grid h-screen max-w-5xl gap-5 px-4 py-5 sm:px-8"> | |
{appData.permissions.includes("app.dashboard.view") ? ( | |
<div className="space-y-3"> | |
<div className="flex items-center justify-between space-x-2"> | |
<h3 className="flex-grow font-medium leading-4 text-gray-900">{t("app.dashboard.summary")}</h3> | |
<div> | |
<InputSelector | |
className="w-44" | |
withSearch={false} | |
name="period" | |
value={searchParams.get("period")?.toString() ?? defaultPeriodFilter} | |
options={PeriodFilters.map((f) => { | |
return { | |
value: f.value, | |
name: t(f.name), | |
}; | |
})} | |
setValue={(value) => { | |
if (value) { | |
searchParams.set("period", value?.toString() ?? ""); | |
} else { | |
searchParams.delete("period"); | |
} | |
setSearchParams(searchParams); | |
}} | |
/> | |
</div> | |
</div> | |
<DashboardStats items={data.stats} /> | |
</div> | |
) : ( | |
<div className="font-medium">You don't have permission to view the dashboard.</div> | |
)} | |
</div> | |
</main> | |
); | |
} | |
export function ErrorBoundary() { | |
return <ServerError />; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment