metis-desk/apps/web/src/app.tsx
David bada13a50e feat(dashboard): implement dashboard schemas and API integration
- Added Zod schemas for dashboard queries, entries, summaries, and companies.
- Created dashboard API functions for fetching summary, work, attention, activity, and companies data.
- Developed dashboard components including BlockState, DashboardDetailsDialog, and DashboardPage for rendering dashboard information.
- Implemented quick create functionality for companies, tickets, interventions, assets, and resources.
- Introduced a new ResourceDashboardReader for querying resource-related data.
- Added a StatisticCard component for displaying key performance indicators in the dashboard.
2026-10-08 13:27:27 +02:00

94 lines
2.7 KiB
TypeScript

import { CompaniesWorkspace } from "@metis/companies/client";
import { IdentityWorkspace, identityApi, identityKeys } from "@metis/identity/client";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@repo/shadcn-ui/components/select";
import { useQuery } from "@tanstack/react-query";
import { useId, useState } from "react";
import { useTranslation } from "react-i18next";
function LanguageSwitcher() {
const { t, i18n } = useTranslation("core");
const languageOptions = ["es", "en"].map((value) => ({
value,
label: t(`languageNames.${value}`),
}));
const [languageError, setLanguageError] = useState(false);
const languageLabelId = useId();
return (
<div className="desk-language">
<div className="flex items-center gap-3 text-sm text-muted-foreground">
<span id={languageLabelId}>{t("language")}</span>
<Select
items={languageOptions}
onValueChange={(language) => {
if (language !== "es" && language !== "en") {
return;
}
setLanguageError(false);
i18n
.changeLanguage(language)
.then(() => {
document.documentElement.lang = i18n.resolvedLanguage ?? "es";
})
.catch(() => setLanguageError(true));
}}
value={i18n.resolvedLanguage ?? "es"}
>
<SelectTrigger aria-labelledby={languageLabelId} className="min-w-28">
<SelectValue />
</SelectTrigger>
<SelectContent>
{languageOptions.map((language) => (
<SelectItem key={language.value} value={language.value}>
{language.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{languageError && (
<p className="text-destructive" role="alert">
{t("languageError")}
</p>
)}
</div>
);
}
export function App() {
const session = useQuery({
queryKey: identityKeys.session,
queryFn: identityApi.session,
retry: false,
});
return (
<div className="desk-app">
{!session.data?.user && (
<header className="desk-login-header">
<strong>Metis Desk</strong>
<LanguageSwitcher />
</header>
)}
<IdentityWorkspace
renderWorkspace={(snapshot, accountNavigation) => (
<CompaniesWorkspace
accountNavigation={accountNavigation}
csrfToken={snapshot.csrfToken}
languageSwitcher={<LanguageSwitcher />}
userName={snapshot.user?.name ?? ""}
/>
)}
>
{null}
</IdentityWorkspace>
</div>
);
}