first commit
This commit is contained in:
297
resources/js/pages/references/departments/Index.vue
Normal file
297
resources/js/pages/references/departments/Index.vue
Normal file
@@ -0,0 +1,297 @@
|
||||
<script setup lang="ts">
|
||||
import { Form, Head } from '@inertiajs/vue3';
|
||||
import { Building2, FolderPlus, Plus } from 'lucide-vue-next';
|
||||
import InputError from '@/components/InputError.vue';
|
||||
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 {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import { index, store as storeDepartment } from '@/routes/references/departments';
|
||||
import { store as storeDepartmentProfile } from '@/routes/references/department-profiles';
|
||||
import type { Department, DepartmentProfile, Team } from '@/types';
|
||||
|
||||
type Props = {
|
||||
currentTeam?: Team | null;
|
||||
departmentProfiles: DepartmentProfile[];
|
||||
departments: Department[];
|
||||
};
|
||||
|
||||
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">
|
||||
<div class="flex flex-col gap-2">
|
||||
<Heading
|
||||
title="Отделения"
|
||||
description="Управляйте профилями отделений и создавайте сами отделения в одном разделе."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 xl:grid-cols-[minmax(0,0.95fr)_minmax(0,1.05fr)]">
|
||||
<Card class="border-sidebar-border/70">
|
||||
<CardHeader>
|
||||
<CardTitle class="flex items-center gap-2 text-base">
|
||||
<FolderPlus class="h-4 w-4" />
|
||||
Создать профиль отделения
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Профиль используется как категория, к которой
|
||||
привязывается отделение.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form
|
||||
v-bind="
|
||||
props.currentTeam
|
||||
? storeDepartmentProfile.form(
|
||||
props.currentTeam.slug,
|
||||
)
|
||||
: undefined
|
||||
"
|
||||
class="space-y-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
<Label for="department-profile-name">
|
||||
Название профиля
|
||||
</Label>
|
||||
<Input
|
||||
id="department-profile-name"
|
||||
name="name"
|
||||
data-test="department-profile-name"
|
||||
placeholder="Например, Клинический профиль"
|
||||
required
|
||||
/>
|
||||
<InputError :message="errors.name" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
data-test="department-profile-submit"
|
||||
:disabled="processing"
|
||||
class="w-full sm:w-auto"
|
||||
>
|
||||
<Plus class="h-4 w-4" />
|
||||
Создать профиль
|
||||
</Button>
|
||||
</Form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card class="border-sidebar-border/70">
|
||||
<CardHeader>
|
||||
<CardTitle class="flex items-center gap-2 text-base">
|
||||
<Building2 class="h-4 w-4" />
|
||||
Создать отделение
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
Укажите название, профиль и статус активности для
|
||||
нового отделения.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Form
|
||||
v-bind="
|
||||
props.currentTeam
|
||||
? storeDepartment.form(props.currentTeam.slug)
|
||||
: undefined
|
||||
"
|
||||
class="space-y-4"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
<Label for="department-name">Название отделения</Label>
|
||||
<Input
|
||||
id="department-name"
|
||||
name="name"
|
||||
data-test="department-name"
|
||||
placeholder="Например, Приемное отделение"
|
||||
required
|
||||
/>
|
||||
<InputError :message="errors.name" />
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="department-profile">Профиль</Label>
|
||||
<Select
|
||||
name="department_profile_id"
|
||||
data-test="department-profile-id"
|
||||
>
|
||||
<SelectTrigger
|
||||
id="department-profile"
|
||||
class="w-full"
|
||||
>
|
||||
<SelectValue
|
||||
placeholder="Выберите профиль отделения"
|
||||
/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem
|
||||
v-for="departmentProfile in departmentProfiles"
|
||||
:key="departmentProfile.id"
|
||||
:value="String(departmentProfile.id)"
|
||||
>
|
||||
{{ departmentProfile.name }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<InputError
|
||||
:message="errors.department_profile_id"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="department-status">Статус</Label>
|
||||
<Select
|
||||
name="is_active"
|
||||
default-value="1"
|
||||
data-test="department-is-active"
|
||||
>
|
||||
<SelectTrigger
|
||||
id="department-status"
|
||||
class="w-full"
|
||||
>
|
||||
<SelectValue placeholder="Выберите статус" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="1">Активно</SelectItem>
|
||||
<SelectItem value="0">Неактивно</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<InputError :message="errors.is_active" />
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
data-test="department-submit"
|
||||
:disabled="processing || departmentProfiles.length === 0"
|
||||
class="w-full sm:w-auto"
|
||||
>
|
||||
<Plus class="h-4 w-4" />
|
||||
Создать отделение
|
||||
</Button>
|
||||
</Form>
|
||||
|
||||
<p
|
||||
v-if="departmentProfiles.length === 0"
|
||||
class="mt-3 text-sm text-muted-foreground"
|
||||
>
|
||||
Сначала создайте хотя бы один профиль отделения.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-6 xl:grid-cols-2">
|
||||
<Card class="border-sidebar-border/70">
|
||||
<CardHeader>
|
||||
<CardTitle>Профили отделений</CardTitle>
|
||||
<CardDescription>
|
||||
Всего профилей: {{ departmentProfiles.length }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-3">
|
||||
<div
|
||||
v-for="departmentProfile in departmentProfiles"
|
||||
:key="departmentProfile.id"
|
||||
class="flex items-center justify-between rounded-lg border px-4 py-3"
|
||||
>
|
||||
<div>
|
||||
<p class="font-medium">
|
||||
{{ departmentProfile.name }}
|
||||
</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
Отделений: {{
|
||||
departmentProfile.departmentsCount
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="departmentProfiles.length === 0"
|
||||
class="py-6 text-center text-sm text-muted-foreground"
|
||||
>
|
||||
Профили отделений пока не созданы.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card class="border-sidebar-border/70">
|
||||
<CardHeader>
|
||||
<CardTitle>Список отделений</CardTitle>
|
||||
<CardDescription>
|
||||
Всего отделений: {{ departments.length }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-3">
|
||||
<div
|
||||
v-for="department in departments"
|
||||
:key="department.id"
|
||||
class="flex items-center justify-between rounded-lg border px-4 py-3"
|
||||
>
|
||||
<div>
|
||||
<p class="font-medium">{{ department.name }}</p>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
Профиль:
|
||||
{{ department.departmentProfile.name }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Badge
|
||||
:variant="
|
||||
department.isActive ? 'default' : 'secondary'
|
||||
"
|
||||
>
|
||||
{{
|
||||
department.isActive
|
||||
? 'Активно'
|
||||
: 'Неактивно'
|
||||
}}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<p
|
||||
v-if="departments.length === 0"
|
||||
class="py-6 text-center text-sm text-muted-foreground"
|
||||
>
|
||||
Отделения пока не созданы.
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user