Files
econom/resources/js/pages/reports/periods/Index.vue
brusnitsyn fb2e6c58e3
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
first commit
2026-04-06 00:06:00 +09:00

209 lines
8.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>