Compare commits
No commits in common. "3c684629643e93bfaca186de1451ff33f83d4e0d" and "ac449e135348cc792280f51bf2aefbaee11aaf18" have entirely different histories.
3c68462964
...
ac449e1353
@ -1,74 +1,70 @@
|
|||||||
'use client';
|
"use client"
|
||||||
|
|
||||||
import { Link, usePage } from '@inertiajs/react';
|
import { Link, usePage } from "@inertiajs/react";
|
||||||
import {
|
import {
|
||||||
SidebarGroup,
|
SidebarGroup,
|
||||||
SidebarGroupLabel,
|
SidebarGroupLabel,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuButton,
|
SidebarMenuButton,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem
|
||||||
} from '@/components/ui/sidebar';
|
} from "@/components/ui/sidebar";
|
||||||
|
|
||||||
export type NavItem = {
|
export type NavItem = {
|
||||||
name: string;
|
name: string
|
||||||
url: string;
|
url: string
|
||||||
icon: React.ComponentType<{ className?: string }>;
|
icon: React.ComponentType<{ className?: string }>
|
||||||
};
|
}
|
||||||
|
|
||||||
export type NavGroup = {
|
export type NavGroup = {
|
||||||
label: string;
|
label: string
|
||||||
items: NavItem[];
|
items: NavItem[]
|
||||||
};
|
}
|
||||||
|
|
||||||
export function NavMain({ items }: { items: (NavGroup | NavItem)[] }) {
|
export function NavMain({
|
||||||
const { url } = usePage();
|
items,
|
||||||
|
}: {
|
||||||
return (
|
items: (NavGroup | NavItem)[]
|
||||||
<>
|
}) {
|
||||||
{items.map((item) => {
|
const { url } = usePage()
|
||||||
if ('label' in item) {
|
|
||||||
return (
|
return (
|
||||||
<SidebarGroup key={item.label}>
|
<>
|
||||||
<SidebarGroupLabel>{item.label}</SidebarGroupLabel>
|
{items.map((item) => {
|
||||||
<SidebarMenu>
|
if ("label" in item) {
|
||||||
{item.items.map((child) => (
|
return (
|
||||||
<SidebarMenuItem key={child.name}>
|
<SidebarGroup key={item.label}>
|
||||||
<SidebarMenuButton
|
<SidebarGroupLabel>{item.label}</SidebarGroupLabel>
|
||||||
asChild
|
<SidebarMenu>
|
||||||
isActive={url === child.url}
|
{item.items.map((child) => (
|
||||||
tooltip={child.name}
|
<SidebarMenuItem key={child.name}>
|
||||||
>
|
<SidebarMenuButton asChild isActive={url === child.url} tooltip={child.name}>
|
||||||
<Link href={child.url}>
|
<Link href={child.url}>
|
||||||
<child.icon className="h-4 w-4" />
|
<child.icon className="h-4 w-4" />
|
||||||
<span>{child.name}</span>
|
<span>{child.name}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
))}
|
))}
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarGroup>
|
</SidebarGroup>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarGroup key={item.name}>
|
<SidebarGroup key={item.name}>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton
|
<SidebarMenuButton asChild isActive={url === item.url} tooltip={item.name}>
|
||||||
asChild
|
<a href={item.url}>
|
||||||
isActive={url === item.url}
|
<item.icon className="h-4 w-4" />
|
||||||
tooltip={item.name}
|
<span>{item.name}</span>
|
||||||
>
|
</a>
|
||||||
<Link href={item.url}>
|
</SidebarMenuButton>
|
||||||
<item.icon className="h-4 w-4" />
|
</SidebarMenuItem>
|
||||||
<span>{item.name}</span>
|
</SidebarMenu>
|
||||||
</Link>
|
</SidebarGroup>
|
||||||
</SidebarMenuButton>
|
)
|
||||||
</SidebarMenuItem>
|
})}
|
||||||
</SidebarMenu>
|
</>
|
||||||
</SidebarGroup>
|
)
|
||||||
);
|
|
||||||
})}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +1,42 @@
|
|||||||
'use client';
|
"use client"
|
||||||
|
|
||||||
import { Link } from '@inertiajs/react';
|
import type {Icon} from "@tabler/icons-react";
|
||||||
import type { Icon } from '@tabler/icons-react';
|
import * as React from "react"
|
||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SidebarGroup,
|
SidebarGroup,
|
||||||
SidebarGroupContent,
|
SidebarGroupContent,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuButton,
|
SidebarMenuButton,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
} from '@/components/ui/sidebar';
|
} from "@/components/ui/sidebar"
|
||||||
|
|
||||||
export function NavSecondary({
|
export function NavSecondary({
|
||||||
items,
|
items,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
items: {
|
items: {
|
||||||
title: string;
|
title: string
|
||||||
url: string;
|
url: string
|
||||||
icon: Icon;
|
icon: Icon
|
||||||
}[];
|
}[]
|
||||||
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
|
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
|
||||||
return (
|
return (
|
||||||
<SidebarGroup {...props}>
|
<SidebarGroup {...props}>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
{items.map((item) => (
|
{items.map((item) => (
|
||||||
<SidebarMenuItem key={item.title}>
|
<SidebarMenuItem key={item.title}>
|
||||||
<SidebarMenuButton asChild tooltip={item.title}>
|
<SidebarMenuButton asChild tooltip={item.title}>
|
||||||
<Link href={item.url}>
|
<a href={item.url}>
|
||||||
<item.icon />
|
<item.icon />
|
||||||
<span>{item.title}</span>
|
<span>{item.title}</span>
|
||||||
</Link>
|
</a>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
))}
|
))}
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarGroupContent>
|
</SidebarGroupContent>
|
||||||
</SidebarGroup>
|
</SidebarGroup>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Pencil, Plus, Trash2 } from 'lucide-react';
|
import { ArrowLeft, Pencil, Plus, Trash2 } from 'lucide-react';
|
||||||
@ -161,10 +161,10 @@ export default function SubmissionIndex({
|
|||||||
title="Pengumpulan Tugas"
|
title="Pengumpulan Tugas"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={assignmentIndex.url()}>
|
<a href={assignmentIndex.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, CheckCircle2, Save, XCircle } from 'lucide-react';
|
import { ArrowLeft, CheckCircle2, Save, XCircle } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -86,10 +86,10 @@ export default function AttendanceSession({
|
|||||||
title="Kehadiran"
|
title="Kehadiran"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={attendanceIndex.url()}>
|
<a href={attendanceIndex.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Paperclip, Pencil, Plus, Trash2 } from 'lucide-react';
|
import { ArrowLeft, Paperclip, Pencil, Plus, Trash2 } from 'lucide-react';
|
||||||
@ -176,10 +176,10 @@ export default function TuitionPaymentIndex({ invoice, payments }: Props) {
|
|||||||
title="Pembayaran"
|
title="Pembayaran"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={tuitionInvoiceIndex.url()}>
|
<a href={tuitionInvoiceIndex.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Trash2, UserPlus } from 'lucide-react';
|
import { ArrowLeft, Trash2, UserPlus } from 'lucide-react';
|
||||||
@ -109,10 +109,10 @@ export default function ClassEnrollmentIndex({
|
|||||||
title="Peserta Kelas"
|
title="Peserta Kelas"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={courseClassIndex.url()}>
|
<a href={courseClassIndex.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -7,13 +7,7 @@ import InputError from '@/components/input-error';
|
|||||||
import { PageHeader } from '@/components/page-header';
|
import { PageHeader } from '@/components/page-header';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import {
|
import { Combobox, ComboboxContent, ComboboxInput, ComboboxItem, ComboboxList } from '@/components/ui/combobox';
|
||||||
Combobox,
|
|
||||||
ComboboxContent,
|
|
||||||
ComboboxInput,
|
|
||||||
ComboboxItem,
|
|
||||||
ComboboxList,
|
|
||||||
} from '@/components/ui/combobox';
|
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import { PhoneInput } from '@/components/ui/phone-input';
|
import { PhoneInput } from '@/components/ui/phone-input';
|
||||||
@ -41,10 +35,10 @@ export default function AdministratorCreate({ roles }: Props) {
|
|||||||
title="Tambah Administrator"
|
title="Tambah Administrator"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -59,62 +53,29 @@ export default function AdministratorCreate({ roles }: Props) {
|
|||||||
<CardContent className="grid gap-4 md:grid-cols-3">
|
<CardContent className="grid gap-4 md:grid-cols-3">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="username">
|
<Label htmlFor="username">
|
||||||
Username{' '}
|
Username <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="username" name="username" placeholder="Masukkan username" />
|
||||||
id="username"
|
|
||||||
name="username"
|
|
||||||
placeholder="Masukkan username"
|
|
||||||
/>
|
|
||||||
<InputError message={errors.username} />
|
<InputError message={errors.username} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="email">
|
<Label htmlFor="email">
|
||||||
Email{' '}
|
Email <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="email" name="email" type="email" placeholder="Masukkan email" />
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
placeholder="Masukkan email"
|
|
||||||
/>
|
|
||||||
<InputError message={errors.email} />
|
<InputError message={errors.email} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Role{' '}
|
Role <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="role" value={role} />
|
||||||
type="hidden"
|
<Combobox value={role} onValueChange={(v) => setRole(v ?? '')}>
|
||||||
name="role"
|
<ComboboxInput placeholder="Pilih role" className="w-full" />
|
||||||
value={role}
|
|
||||||
/>
|
|
||||||
<Combobox
|
|
||||||
value={role}
|
|
||||||
onValueChange={(v) =>
|
|
||||||
setRole(v ?? '')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ComboboxInput
|
|
||||||
placeholder="Pilih role"
|
|
||||||
className="w-full"
|
|
||||||
/>
|
|
||||||
<ComboboxContent>
|
<ComboboxContent>
|
||||||
<ComboboxList>
|
<ComboboxList>
|
||||||
{roles.map((r) => (
|
{roles.map((r) => (
|
||||||
<ComboboxItem
|
<ComboboxItem key={r.id} value={r.name}>
|
||||||
key={r.id}
|
|
||||||
value={r.name}
|
|
||||||
>
|
|
||||||
{r.name}
|
{r.name}
|
||||||
</ComboboxItem>
|
</ComboboxItem>
|
||||||
))}
|
))}
|
||||||
@ -133,138 +94,57 @@ export default function AdministratorCreate({ roles }: Props) {
|
|||||||
<CardContent className="grid gap-4 md:grid-cols-2">
|
<CardContent className="grid gap-4 md:grid-cols-2">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="full_name">
|
<Label htmlFor="full_name">
|
||||||
Nama Lengkap{' '}
|
Nama Lengkap <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="full_name" name="full_name" placeholder="Masukkan nama lengkap" />
|
||||||
id="full_name"
|
<InputError message={errors.full_name} />
|
||||||
name="full_name"
|
|
||||||
placeholder="Masukkan nama lengkap"
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.full_name}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="phone_number">
|
<Label htmlFor="phone_number">
|
||||||
Nomor Telepon{' '}
|
Nomor Telepon <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<PhoneInput
|
<PhoneInput id="phone_number" name="phone_number" placeholder="08xx xxxx xxxx" />
|
||||||
id="phone_number"
|
<InputError message={errors.phone_number} />
|
||||||
name="phone_number"
|
|
||||||
placeholder="08xx xxxx xxxx"
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.phone_number}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-4 md:col-span-2 md:grid-cols-3">
|
<div className="grid gap-4 md:col-span-2 md:grid-cols-3">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Jenis Kelamin{' '}
|
Jenis Kelamin <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="gender" value={gender} />
|
||||||
type="hidden"
|
<RadioGroup value={gender} onValueChange={setGender} className="flex gap-4">
|
||||||
name="gender"
|
|
||||||
value={gender}
|
|
||||||
/>
|
|
||||||
<RadioGroup
|
|
||||||
value={gender}
|
|
||||||
onValueChange={setGender}
|
|
||||||
className="flex gap-4"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupItem
|
<RadioGroupItem value="male" id="male" />
|
||||||
value="male"
|
<Label htmlFor="male" className="font-normal">Laki-laki</Label>
|
||||||
id="male"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor="male"
|
|
||||||
className="font-normal"
|
|
||||||
>
|
|
||||||
Laki-laki
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupItem
|
<RadioGroupItem value="female" id="female" />
|
||||||
value="female"
|
<Label htmlFor="female" className="font-normal">Perempuan</Label>
|
||||||
id="female"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor="female"
|
|
||||||
className="font-normal"
|
|
||||||
>
|
|
||||||
Perempuan
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<InputError
|
<InputError message={errors.gender} />
|
||||||
message={errors.gender}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Tempat Lahir{' '}
|
Tempat Lahir <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input name="birth_place" placeholder="Masukkan tempat lahir" />
|
||||||
name="birth_place"
|
<InputError message={errors.birth_place} />
|
||||||
placeholder="Masukkan tempat lahir"
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.birth_place}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Tanggal Lahir{' '}
|
Tanggal Lahir <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="birth_date" value={birthDate ? format(birthDate, 'yyyy-MM-dd') : ''} />
|
||||||
type="hidden"
|
<DatePicker value={birthDate} onChange={setBirthDate} />
|
||||||
name="birth_date"
|
<InputError message={errors.birth_date} />
|
||||||
value={
|
|
||||||
birthDate
|
|
||||||
? format(
|
|
||||||
birthDate,
|
|
||||||
'yyyy-MM-dd',
|
|
||||||
)
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<DatePicker
|
|
||||||
value={birthDate}
|
|
||||||
onChange={setBirthDate}
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.birth_date}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2 md:col-span-2">
|
<div className="grid gap-2 md:col-span-2">
|
||||||
<Label htmlFor="address">
|
<Label htmlFor="address">
|
||||||
Alamat{' '}
|
Alamat <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea id="address" name="address" placeholder="Masukkan alamat" />
|
||||||
id="address"
|
|
||||||
name="address"
|
|
||||||
placeholder="Masukkan alamat"
|
|
||||||
/>
|
|
||||||
<InputError message={errors.address} />
|
<InputError message={errors.address} />
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -7,13 +7,7 @@ import InputError from '@/components/input-error';
|
|||||||
import { PageHeader } from '@/components/page-header';
|
import { PageHeader } from '@/components/page-header';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import {
|
import { Combobox, ComboboxContent, ComboboxInput, ComboboxItem, ComboboxList } from '@/components/ui/combobox';
|
||||||
Combobox,
|
|
||||||
ComboboxContent,
|
|
||||||
ComboboxInput,
|
|
||||||
ComboboxItem,
|
|
||||||
ComboboxList,
|
|
||||||
} from '@/components/ui/combobox';
|
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
import { PhoneInput } from '@/components/ui/phone-input';
|
import { PhoneInput } from '@/components/ui/phone-input';
|
||||||
@ -27,14 +21,7 @@ type User = {
|
|||||||
id: number;
|
id: number;
|
||||||
username: string;
|
username: string;
|
||||||
email: string;
|
email: string;
|
||||||
profile: {
|
profile: { full_name: string; phone_number: string; address: string; gender: string; birth_date: string; birth_place: string } | null;
|
||||||
full_name: string;
|
|
||||||
phone_number: string;
|
|
||||||
address: string;
|
|
||||||
gender: string;
|
|
||||||
birth_date: string;
|
|
||||||
birth_place: string;
|
|
||||||
} | null;
|
|
||||||
roles: { id: number; name: string }[];
|
roles: { id: number; name: string }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,9 +33,7 @@ type Props = {
|
|||||||
export default function AdministratorEdit({ user, roles }: Props) {
|
export default function AdministratorEdit({ user, roles }: Props) {
|
||||||
const [gender, setGender] = useState(user.profile?.gender ?? '');
|
const [gender, setGender] = useState(user.profile?.gender ?? '');
|
||||||
const [birthDate, setBirthDate] = useState<Date | undefined>(
|
const [birthDate, setBirthDate] = useState<Date | undefined>(
|
||||||
user.profile?.birth_date
|
user.profile?.birth_date ? new Date(user.profile.birth_date) : undefined
|
||||||
? new Date(user.profile.birth_date)
|
|
||||||
: undefined,
|
|
||||||
);
|
);
|
||||||
const [role, setRole] = useState(user.roles?.[0]?.name ?? '');
|
const [role, setRole] = useState(user.roles?.[0]?.name ?? '');
|
||||||
|
|
||||||
@ -61,10 +46,10 @@ export default function AdministratorEdit({ user, roles }: Props) {
|
|||||||
title="Edit Administrator"
|
title="Edit Administrator"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -79,62 +64,29 @@ export default function AdministratorEdit({ user, roles }: Props) {
|
|||||||
<CardContent className="grid gap-4 md:grid-cols-3">
|
<CardContent className="grid gap-4 md:grid-cols-3">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="username">
|
<Label htmlFor="username">
|
||||||
Username{' '}
|
Username <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="username" name="username" defaultValue={user.username} />
|
||||||
id="username"
|
|
||||||
name="username"
|
|
||||||
defaultValue={user.username}
|
|
||||||
/>
|
|
||||||
<InputError message={errors.username} />
|
<InputError message={errors.username} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="email">
|
<Label htmlFor="email">
|
||||||
Email{' '}
|
Email <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="email" name="email" type="email" defaultValue={user.email} />
|
||||||
id="email"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
defaultValue={user.email}
|
|
||||||
/>
|
|
||||||
<InputError message={errors.email} />
|
<InputError message={errors.email} />
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Role{' '}
|
Role <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="role" value={role} />
|
||||||
type="hidden"
|
<Combobox value={role} onValueChange={(v) => setRole(v ?? '')}>
|
||||||
name="role"
|
<ComboboxInput placeholder="Pilih role" className="w-full" />
|
||||||
value={role}
|
|
||||||
/>
|
|
||||||
<Combobox
|
|
||||||
value={role}
|
|
||||||
onValueChange={(v) =>
|
|
||||||
setRole(v ?? '')
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<ComboboxInput
|
|
||||||
placeholder="Pilih role"
|
|
||||||
className="w-full"
|
|
||||||
/>
|
|
||||||
<ComboboxContent>
|
<ComboboxContent>
|
||||||
<ComboboxList>
|
<ComboboxList>
|
||||||
{roles.map((r) => (
|
{roles.map((r) => (
|
||||||
<ComboboxItem
|
<ComboboxItem key={r.id} value={r.name}>
|
||||||
key={r.id}
|
|
||||||
value={r.name}
|
|
||||||
>
|
|
||||||
{r.name}
|
{r.name}
|
||||||
</ComboboxItem>
|
</ComboboxItem>
|
||||||
))}
|
))}
|
||||||
@ -153,147 +105,57 @@ export default function AdministratorEdit({ user, roles }: Props) {
|
|||||||
<CardContent className="grid gap-4 md:grid-cols-2">
|
<CardContent className="grid gap-4 md:grid-cols-2">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="full_name">
|
<Label htmlFor="full_name">
|
||||||
Nama Lengkap{' '}
|
Nama Lengkap <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input id="full_name" name="full_name" defaultValue={user.profile?.full_name ?? ''} />
|
||||||
id="full_name"
|
<InputError message={errors.full_name} />
|
||||||
name="full_name"
|
|
||||||
defaultValue={
|
|
||||||
user.profile?.full_name ?? ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.full_name}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="phone_number">
|
<Label htmlFor="phone_number">
|
||||||
Nomor Telepon{' '}
|
Nomor Telepon <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<PhoneInput
|
<PhoneInput id="phone_number" name="phone_number" value={user.profile?.phone_number ?? ''} />
|
||||||
id="phone_number"
|
<InputError message={errors.phone_number} />
|
||||||
name="phone_number"
|
|
||||||
value={
|
|
||||||
user.profile?.phone_number ?? ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.phone_number}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-4 md:col-span-2 md:grid-cols-3">
|
<div className="grid gap-4 md:col-span-2 md:grid-cols-3">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Jenis Kelamin{' '}
|
Jenis Kelamin <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="gender" value={gender} />
|
||||||
type="hidden"
|
<RadioGroup value={gender} onValueChange={setGender} className="flex gap-4">
|
||||||
name="gender"
|
|
||||||
value={gender}
|
|
||||||
/>
|
|
||||||
<RadioGroup
|
|
||||||
value={gender}
|
|
||||||
onValueChange={setGender}
|
|
||||||
className="flex gap-4"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupItem
|
<RadioGroupItem value="male" id="male" />
|
||||||
value="male"
|
<Label htmlFor="male" className="font-normal">Laki-laki</Label>
|
||||||
id="male"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor="male"
|
|
||||||
className="font-normal"
|
|
||||||
>
|
|
||||||
Laki-laki
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<RadioGroupItem
|
<RadioGroupItem value="female" id="female" />
|
||||||
value="female"
|
<Label htmlFor="female" className="font-normal">Perempuan</Label>
|
||||||
id="female"
|
|
||||||
/>
|
|
||||||
<Label
|
|
||||||
htmlFor="female"
|
|
||||||
className="font-normal"
|
|
||||||
>
|
|
||||||
Perempuan
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<InputError
|
<InputError message={errors.gender} />
|
||||||
message={errors.gender}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Tempat Lahir{' '}
|
Tempat Lahir <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input name="birth_place" defaultValue={user.profile?.birth_place ?? ''} />
|
||||||
name="birth_place"
|
<InputError message={errors.birth_place} />
|
||||||
defaultValue={
|
|
||||||
user.profile?.birth_place ??
|
|
||||||
''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.birth_place}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label>
|
<Label>
|
||||||
Tanggal Lahir{' '}
|
Tanggal Lahir <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input type="hidden" name="birth_date" value={birthDate ? format(birthDate, 'yyyy-MM-dd') : ''} />
|
||||||
type="hidden"
|
<DatePicker value={birthDate} onChange={setBirthDate} />
|
||||||
name="birth_date"
|
<InputError message={errors.birth_date} />
|
||||||
value={
|
|
||||||
birthDate
|
|
||||||
? format(
|
|
||||||
birthDate,
|
|
||||||
'yyyy-MM-dd',
|
|
||||||
)
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<DatePicker
|
|
||||||
value={birthDate}
|
|
||||||
onChange={setBirthDate}
|
|
||||||
/>
|
|
||||||
<InputError
|
|
||||||
message={errors.birth_date}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-2 md:col-span-2">
|
<div className="grid gap-2 md:col-span-2">
|
||||||
<Label htmlFor="address">
|
<Label htmlFor="address">
|
||||||
Alamat{' '}
|
Alamat <span className="text-red-500">*</span>
|
||||||
<span className="text-red-500">
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea id="address" name="address" defaultValue={user.profile?.address ?? ''} />
|
||||||
id="address"
|
|
||||||
name="address"
|
|
||||||
defaultValue={
|
|
||||||
user.profile?.address ?? ''
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<InputError message={errors.address} />
|
<InputError message={errors.address} />
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { Plus, RotateCcw } from 'lucide-react';
|
import { Plus, RotateCcw } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
@ -118,10 +118,10 @@ export default function AdministratorIndex({ administrators, filters }: Props) {
|
|||||||
title="Administrator"
|
title="Administrator"
|
||||||
actions={
|
actions={
|
||||||
<Button asChild>
|
<Button asChild>
|
||||||
<Link href={create.url()}>
|
<a href={create.url()}>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
Tambah
|
Tambah
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -49,10 +49,10 @@ export default function LecturerCreate({ departments }: Props) {
|
|||||||
title="Tambah Dosen"
|
title="Tambah Dosen"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -76,10 +76,10 @@ export default function LecturerEdit({ user, departments }: Props) {
|
|||||||
title="Edit Dosen"
|
title="Edit Dosen"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { FileSpreadsheet, Plus, RotateCcw } from 'lucide-react';
|
import { FileSpreadsheet, Plus, RotateCcw } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
@ -147,10 +147,10 @@ export default function LecturerIndex({
|
|||||||
</a>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
<Button asChild>
|
<Button asChild>
|
||||||
<Link href={create.url()}>
|
<a href={create.url()}>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
Tambah
|
Tambah
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -56,10 +56,10 @@ export default function StudentCreate({ departments, lecturers }: Props) {
|
|||||||
title="Tambah Mahasiswa"
|
title="Tambah Mahasiswa"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Form, Head, Link } from '@inertiajs/react';
|
import { Form, Head } from '@inertiajs/react';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { ArrowLeft, Save } from 'lucide-react';
|
import { ArrowLeft, Save } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
@ -85,10 +85,10 @@ export default function StudentEdit({ user, departments, lecturers }: Props) {
|
|||||||
title="Edit Mahasiswa"
|
title="Edit Mahasiswa"
|
||||||
actions={
|
actions={
|
||||||
<Button variant="outline" asChild>
|
<Button variant="outline" asChild>
|
||||||
<Link href={index.url()}>
|
<a href={index.url()}>
|
||||||
<ArrowLeft className="h-4 w-4" />
|
<ArrowLeft className="h-4 w-4" />
|
||||||
Kembali
|
Kembali
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Head, Link, router } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import { FileSpreadsheet, Info, Plus, RotateCcw } from 'lucide-react';
|
import { FileSpreadsheet, Info, Plus, RotateCcw } from 'lucide-react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { ConfirmDialog } from '@/components/confirm-dialog';
|
import { ConfirmDialog } from '@/components/confirm-dialog';
|
||||||
@ -179,10 +179,10 @@ export default function StudentIndex({
|
|||||||
</a>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
<Button asChild>
|
<Button asChild>
|
||||||
<Link href={create.url()}>
|
<a href={create.url()}>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
Tambah
|
Tambah
|
||||||
</Link>
|
</a>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user