113 lines
5.1 KiB
TypeScript
113 lines
5.1 KiB
TypeScript
import { useTranslation } from "react-i18next";
|
|
import { LoaderFunctionArgs, MetaFunction } from "react-router";
|
|
import { useLoaderData } from "react-router";
|
|
import { CheckCircleIcon, CircleIcon } from "~/components/ui/icons/vendor";
|
|
import { getTranslations } from "~/locale/i18next.server";
|
|
import ButtonSecondary from "~/components/ui/buttons/ButtonSecondary";
|
|
import { getSetupSteps } from "~/utils/services/setupService";
|
|
import { SetupItem } from "~/application/dtos/setup/SetupItem";
|
|
import { requireAuth } from "~/utils/loaders.middleware";
|
|
|
|
// type SetupItem = {
|
|
// title: string;
|
|
// description: string;
|
|
// completed: boolean;
|
|
// path: string;
|
|
// };
|
|
|
|
type LoaderData = {
|
|
title: string;
|
|
items: SetupItem[];
|
|
};
|
|
|
|
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
|
|
await requireAuth({ request, params });
|
|
const { t } = await getTranslations(request);
|
|
|
|
const items = await getSetupSteps();
|
|
|
|
const data: LoaderData = {
|
|
title: `${t("app.sidebar.setup")} | ${process.env.APP_NAME}`,
|
|
items,
|
|
};
|
|
return data;
|
|
};
|
|
|
|
export const meta: MetaFunction<typeof loader> = ({ data }) => [{ title: data?.title }];
|
|
|
|
export default function AdminNavigationRoute() {
|
|
const { t } = useTranslation();
|
|
const data = useLoaderData<LoaderData>();
|
|
|
|
return (
|
|
<div>
|
|
{/* <div className="bg-background shadow-2xs border-b border-border w-full py-2">
|
|
<div className="mx-auto max-w-5xl xl:max-w-7xl flex items-center justify-between px-4 sm:px-6 lg:px-8 space-x-2">
|
|
<h1 className="flex-1 font-bold flex items-center truncate">
|
|
{t("app.sidebar.setup")}
|
|
|
|
<span className="ml-2 inline-flex items-center px-3 py-0.5 rounded-full text-xs font-medium bg-secondary text-foreground border border-border">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-teal-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"
|
|
/>
|
|
</svg>
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-orange-500" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
<path strokeLinecap="round" strokeLinejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
</svg>
|
|
</span>
|
|
</h1>
|
|
</div>
|
|
</div> */}
|
|
<div className="mx-auto max-w-4xl space-y-2 px-4 pt-2 sm:px-6 lg:px-8">
|
|
<div className="">
|
|
<div className="flex items-start space-x-8 p-6">
|
|
{/* <div className="bg-theme-50 border border-theme-300 rounded-full p-2">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
className="h-12 w-12 text-theme-400"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
strokeWidth={2}
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"
|
|
/>
|
|
</svg>
|
|
</div> */}
|
|
<div className="space-y-3">
|
|
<h3 className=" text-lg font-bold">{t("admin.setup.headline")}</h3>
|
|
<p className="text-muted-foreground">{t("admin.setup.description")}</p>
|
|
<ul className=" space-y-4">
|
|
{data.items.map((item, idx) => {
|
|
return (
|
|
<li key={idx} className="border-border bg-background space-y-3 rounded-lg border p-4">
|
|
<div className="flex items-center space-x-2">
|
|
{!item.completed ? (
|
|
<CircleIcon className="border-border h-6 w-6 rounded-full border text-gray-300" />
|
|
) : (
|
|
<CheckCircleIcon className="h-6 w-6 rounded-full border border-teal-500 text-teal-500" />
|
|
)}
|
|
<div className=" font-medium">{item.title}</div>
|
|
</div>
|
|
<p className=" text-sm">{item.description}</p>
|
|
<ButtonSecondary to={item.path} className="mt-3">
|
|
{item.completed ? t("app.sidebar.setup") : `${t("shared.goTo")} ` + item.title.toLowerCase()} →
|
|
</ButtonSecondary>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|