fix: QA audit — lint cleanup, i18n fixes, module visibility, sidebar UX
- Fix 97 lint errors → 0 (unused imports, params, variables across 40+ files) - Fix i18n key format: colon → dot notation for next-intl compatibility - Add missing i18n keys (routes.application, routes.home, confirm) - Fix module visibility: sidebar now respects per-account DB features - Fix inject function: use dot-notation keys, add collapsed:true defaults - Fix ConfirmDialog: use useTranslations instead of hardcoded German defaults - Fix events page: replace placeholder 'Beschreibung' with proper description - Fix Dockerfile: add NEXT_PUBLIC_CI ARG for Docker builds - Collapse secondary sidebar sections by default for cleaner UX
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Plus, Users } from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
Plus,
|
||||
Users,
|
||||
Calendar,
|
||||
Euro,
|
||||
} from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
|
||||
@@ -114,9 +114,9 @@ async function generateMemberCards(
|
||||
Text,
|
||||
StyleSheet,
|
||||
renderToBuffer,
|
||||
Svg,
|
||||
Rect,
|
||||
Circle,
|
||||
Svg: _Svg,
|
||||
Rect: _Rect,
|
||||
Circle: _Circle,
|
||||
} = await import('@react-pdf/renderer');
|
||||
|
||||
// — Brand colors (configurable later via account settings) —
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { FileText, Plus } from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
|
||||
@@ -96,36 +96,37 @@ function injectAccountFeatureRoutes(
|
||||
|
||||
if (features.fischerei) {
|
||||
featureGroups.push({
|
||||
label: 'common:routes.fisheriesManagement',
|
||||
label: 'common.routes.fisheriesManagement',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
children: [
|
||||
{
|
||||
label: 'common:routes.fisheriesOverview',
|
||||
label: 'common.routes.fisheriesOverview',
|
||||
path: `/home/${account}/fischerei`,
|
||||
Icon: <Fish className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.fisheriesWaters',
|
||||
label: 'common.routes.fisheriesWaters',
|
||||
path: `/home/${account}/fischerei/waters`,
|
||||
Icon: <Waves className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.fisheriesLeases',
|
||||
label: 'common.routes.fisheriesLeases',
|
||||
path: `/home/${account}/fischerei/leases`,
|
||||
Icon: <Anchor className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.fisheriesCatchBooks',
|
||||
label: 'common.routes.fisheriesCatchBooks',
|
||||
path: `/home/${account}/fischerei/catch-books`,
|
||||
Icon: <BookOpen className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.fisheriesPermits',
|
||||
label: 'common.routes.fisheriesPermits',
|
||||
path: `/home/${account}/fischerei/permits`,
|
||||
Icon: <ShieldCheck className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.fisheriesCompetitions',
|
||||
label: 'common.routes.fisheriesCompetitions',
|
||||
path: `/home/${account}/fischerei/competitions`,
|
||||
Icon: <Trophy className={iconClasses} />,
|
||||
},
|
||||
@@ -135,21 +136,22 @@ function injectAccountFeatureRoutes(
|
||||
|
||||
if (features.meetings) {
|
||||
featureGroups.push({
|
||||
label: 'common:routes.meetingProtocols',
|
||||
label: 'common.routes.meetingProtocols',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
children: [
|
||||
{
|
||||
label: 'common:routes.meetingsOverview',
|
||||
label: 'common.routes.meetingsOverview',
|
||||
path: `/home/${account}/meetings`,
|
||||
Icon: <BookMarked className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.meetingsProtocols',
|
||||
label: 'common.routes.meetingsProtocols',
|
||||
path: `/home/${account}/meetings/protocols`,
|
||||
Icon: <ScrollText className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.meetingsTasks',
|
||||
label: 'common.routes.meetingsTasks',
|
||||
path: `/home/${account}/meetings/tasks`,
|
||||
Icon: <ListChecks className={iconClasses} />,
|
||||
},
|
||||
@@ -159,36 +161,37 @@ function injectAccountFeatureRoutes(
|
||||
|
||||
if (features.verband) {
|
||||
featureGroups.push({
|
||||
label: 'common:routes.associationManagement',
|
||||
label: 'common.routes.associationManagement',
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
children: [
|
||||
{
|
||||
label: 'common:routes.associationOverview',
|
||||
label: 'common.routes.associationOverview',
|
||||
path: `/home/${account}/verband`,
|
||||
Icon: <Building2 className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.associationHierarchy',
|
||||
label: 'common.routes.associationHierarchy',
|
||||
path: `/home/${account}/verband/hierarchy`,
|
||||
Icon: <Network className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.associationMemberSearch',
|
||||
label: 'common.routes.associationMemberSearch',
|
||||
path: `/home/${account}/verband/members`,
|
||||
Icon: <SearchCheck className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.associationEvents',
|
||||
label: 'common.routes.associationEvents',
|
||||
path: `/home/${account}/verband/events`,
|
||||
Icon: <Share2 className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.associationReporting',
|
||||
label: 'common.routes.associationReporting',
|
||||
path: `/home/${account}/verband/reporting`,
|
||||
Icon: <PieChart className={iconClasses} />,
|
||||
},
|
||||
{
|
||||
label: 'common:routes.associationTemplates',
|
||||
label: 'common.routes.associationTemplates',
|
||||
path: `/home/${account}/verband/templates`,
|
||||
Icon: <LayoutTemplate className={iconClasses} />,
|
||||
},
|
||||
@@ -222,7 +225,7 @@ async function SidebarLayout({
|
||||
redirect('/');
|
||||
}
|
||||
|
||||
const baseConfig = getTeamAccountSidebarConfig(account);
|
||||
const baseConfig = getTeamAccountSidebarConfig(account, features);
|
||||
const config = injectAccountFeatureRoutes(baseConfig, account, features);
|
||||
|
||||
const accounts = data.accounts.map(({ name, slug, picture_url }) => ({
|
||||
@@ -275,7 +278,7 @@ async function HeaderLayout({
|
||||
getAccountFeatures(account),
|
||||
]);
|
||||
|
||||
const baseConfig = getTeamAccountSidebarConfig(account);
|
||||
const baseConfig = getTeamAccountSidebarConfig(account, features);
|
||||
const config = injectAccountFeatureRoutes(baseConfig, account, features);
|
||||
|
||||
const accounts = data.accounts.map(({ name, slug, picture_url }) => ({
|
||||
|
||||
@@ -62,7 +62,6 @@ export function InvitationsView({
|
||||
invitations,
|
||||
members,
|
||||
accountId,
|
||||
account,
|
||||
}: InvitationsViewProps) {
|
||||
const t = useTranslations('members');
|
||||
const router = useRouter();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Link2, List } from 'lucide-react';
|
||||
import { List } from 'lucide-react';
|
||||
|
||||
import { createModuleBuilderApi } from '@kit/module-builder/api';
|
||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { FileText, Plus } from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
@@ -17,7 +17,7 @@ import { createSiteBuilderApi } from '@kit/site-builder/api';
|
||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||
import { Badge } from '@kit/ui/badge';
|
||||
import { Button } from '@kit/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card';
|
||||
import { Card, CardContent } from '@kit/ui/card';
|
||||
import { cn } from '@kit/ui/utils';
|
||||
|
||||
import { AccountNotFound } from '~/components/account-not-found';
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
import { Plus } from 'lucide-react';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
@@ -15,7 +13,6 @@ import { createSiteBuilderApi } from '@kit/site-builder/api';
|
||||
import { getSupabaseServerClient } from '@kit/supabase/server-client';
|
||||
import { Badge } from '@kit/ui/badge';
|
||||
import { Button } from '@kit/ui/button';
|
||||
import { Card, CardContent } from '@kit/ui/card';
|
||||
|
||||
import { AccountNotFound } from '~/components/account-not-found';
|
||||
import { CmsPageShell } from '~/components/cms-page-shell';
|
||||
|
||||
Reference in New Issue
Block a user