first commit
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
brusnitsyn
2026-04-06 00:06:00 +09:00
commit fb2e6c58e3
409 changed files with 42953 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
<script setup lang="ts">
import { Form, Head } from '@inertiajs/vue3';
import Heading from '@/components/Heading.vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { index as analysisIndex } from '@/routes/reports/analysis';
import { approve, index, store } from '@/routes/reports/periods';
import type { ReportPeriodSummary, Team } from '@/types';
type Props = {
currentTeam?: Team | null;
periods: ReportPeriodSummary[];
months: Array<{ value: number; label: string }>;
years: number[];
};
const props = defineProps<Props>();
defineOptions({
layout: (props: { currentTeam?: Team | null }) => ({
breadcrumbs: [
{
title: 'Отчеты',
href: props.currentTeam ? index(props.currentTeam.slug) : '/',
},
{
title: 'Периоды',
href: props.currentTeam ? index(props.currentTeam.slug) : '/',
},
],
}),
});
</script>
<template>
<Head title="Периоды отчетов" />
<div class="flex flex-col gap-6">
<Heading
title="Периоды отчетов"
description="Создавайте месяцы учета, управляйте их статусом и подготавливайте основу для модулей ввода и анализа."
/>
<div class="grid gap-6 xl:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)]">
<Card class="border-sidebar-border/70">
<CardHeader>
<CardTitle>Создать период</CardTitle>
<CardDescription>
Новый период создается в статусе черновика и доступен
для ввода данных.
</CardDescription>
</CardHeader>
<CardContent>
<Form
v-if="props.currentTeam"
v-bind="store.form(props.currentTeam.slug)"
class="space-y-4"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label for="report-period-year">Год</Label>
<select
id="report-period-year"
name="year"
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
>
<option
v-for="year in years"
:key="year"
:value="year"
>
{{ year }}
</option>
</select>
<p
v-if="errors.year"
class="text-sm text-destructive"
>
{{ errors.year }}
</p>
</div>
<div class="grid gap-2">
<Label for="report-period-month">Месяц</Label>
<select
id="report-period-month"
name="month"
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
>
<option
v-for="month in months"
:key="month.value"
:value="month.value"
>
{{ month.label }}
</option>
</select>
<p
v-if="errors.month"
class="text-sm text-destructive"
>
{{ errors.month }}
</p>
</div>
<Button type="submit" :disabled="processing">
Создать период
</Button>
</Form>
</CardContent>
</Card>
<Card class="border-sidebar-border/70">
<CardHeader>
<CardTitle>Периоды команды</CardTitle>
<CardDescription>
Всего периодов: {{ periods.length }}
</CardDescription>
</CardHeader>
<CardContent class="space-y-3">
<div
v-for="period in periods"
:key="period.id"
class="flex flex-col gap-3 rounded-lg border px-4 py-4 md:flex-row md:items-center md:justify-between"
>
<div class="space-y-1">
<p class="font-medium">{{ period.label }}</p>
<p class="text-sm text-muted-foreground">
Обновлен: {{
period.updatedAt
? new Date(period.updatedAt).toLocaleString(
'ru-RU',
)
: 'нет данных'
}}
</p>
</div>
<div class="flex flex-wrap items-center gap-2">
<Badge
:variant="
period.isEditable ? 'default' : 'secondary'
"
>
{{ period.statusLabel }}
</Badge>
<Button
v-if="props.currentTeam"
as-child
variant="outline"
size="sm"
>
<a
:href="
analysisIndex(props.currentTeam.slug, {
query: { period: period.id },
}).url
"
>
Открыть анализ
</a>
</Button>
<Form
v-if="
props.currentTeam &&
period.isEditable
"
v-bind="
approve.form([
props.currentTeam.slug,
period.id,
])
"
v-slot="{ processing }"
>
<Button
type="submit"
size="sm"
:disabled="processing"
>
Утвердить
</Button>
</Form>
</div>
</div>
<p
v-if="periods.length === 0"
class="py-6 text-center text-sm text-muted-foreground"
>
Периоды еще не созданы.
</p>
</CardContent>
</Card>
</div>
</div>
</template>