Created
March 13, 2026 18:40
-
-
Save bulentsakarya/888ba82d6c706a291a602a3bb7c6918f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| City Controller index metod | |
| /** | |
| * İl listeleme sayfası. | |
| */ | |
| public function index(?string $countryId = null): Response | |
| { | |
| return Inertia::render('panel/definitions/City/Index', [ | |
| 'cities' => $this->cityService->all($countryId), | |
| 'selectedCountry' => Country::find($countryId), | |
| 'selectedCountryId' => $countryId, | |
| ]); | |
| } | |
| City Service all metod | |
| public function all(?string $countryId = null): LengthAwarePaginator | |
| { | |
| return City::query() | |
| ->with('country:id,name') | |
| ->when($countryId, fn ($q) => $q->where('country_id', $countryId)) | |
| ->orderBy('sort_order') | |
| ->orderBy('name') | |
| ->paginate(config('otomasyon.pagination.per_page', 15)); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script setup lang="ts"> | |
| import { Head, router, useForm } from '@inertiajs/vue3'; | |
| import { | |
| Plus, | |
| Pencil, | |
| Trash2, | |
| Loader2, | |
| X, | |
| Check, | |
| ChevronLeft, | |
| ChevronRight, | |
| MapPin, | |
| } from 'lucide-vue-next'; | |
| import { ref } from 'vue'; | |
| import { | |
| store, | |
| update, | |
| destroy, | |
| } from '@/actions/App/Http/Controllers/Panel/Definitions/CityController'; | |
| import Heading from '@/components/common/Heading.vue'; | |
| import InputError from '@/components/common/InputError.vue'; | |
| import { | |
| AlertDialog, | |
| AlertDialogAction, | |
| AlertDialogCancel, | |
| AlertDialogContent, | |
| AlertDialogDescription, | |
| AlertDialogFooter, | |
| AlertDialogHeader, | |
| AlertDialogTitle, | |
| } from '@/components/ui/alert-dialog'; | |
| import { Badge } from '@/components/ui/badge'; | |
| import { Button } from '@/components/ui/button'; | |
| import EmptyState from '@/components/ui/empty-state/EmptyState.vue'; | |
| import { Input } from '@/components/ui/input'; | |
| import { Label } from '@/components/ui/label'; | |
| import { | |
| Pagination, | |
| PaginationContent, | |
| PaginationItem, | |
| PaginationNext, | |
| PaginationPrevious, | |
| } from '@/components/ui/pagination'; | |
| import { | |
| Sheet, | |
| SheetContent, | |
| SheetDescription, | |
| SheetFooter, | |
| SheetHeader, | |
| SheetTitle, | |
| } from '@/components/ui/sheet'; | |
| import { Switch } from '@/components/ui/switch'; | |
| import { | |
| Table, | |
| TableBody, | |
| TableCell, | |
| TableHead, | |
| TableHeader, | |
| TableRow, | |
| } from '@/components/ui/table'; | |
| import { useClearFormErrors } from '@/composables/useClearFormErrors'; | |
| import AppLayout from '@/layouts/PanelLayout.vue'; | |
| import DefinitionsLayout from '@/pages/panel/definitions/partials/Layout.vue'; | |
| import { index as cityRoute } from '@/routes/panel/settings/definitions/cities'; | |
| import { index as districtRoute } from '@/routes/panel/settings/definitions/districts'; | |
| import { | |
| type BreadcrumbItem, | |
| type City, | |
| type Country, | |
| type PaginationResponse, | |
| } from '@/types'; | |
| const props = defineProps<{ | |
| cities: PaginationResponse<City>; | |
| selectedCountry?: Country; | |
| selectedCountryId?: string; | |
| }>(); | |
| const breadcrumbItems: BreadcrumbItem[] = [ | |
| { title: 'Tanımlamalar', href: '#' }, | |
| { title: 'Şehirler', href: cityRoute().url }, | |
| ]; | |
| const isSheetOpen = ref(false); | |
| const showDeleteDialog = ref(false); | |
| const editingCity = ref<City | null>(null); | |
| const form = useForm({ | |
| country_id: props.selectedCountryId || '', | |
| name: '', | |
| is_active: true, | |
| }); | |
| useClearFormErrors(form); | |
| function openCreateSheet() { | |
| editingCity.value = null; | |
| form.reset(); | |
| form.country_id = props.selectedCountryId || ''; | |
| form.clearErrors(); | |
| isSheetOpen.value = true; | |
| } | |
| function openEditSheet(city: City) { | |
| editingCity.value = city; | |
| form.country_id = city.country_id; | |
| form.name = city.name; | |
| form.is_active = city.is_active; | |
| form.clearErrors(); | |
| isSheetOpen.value = true; | |
| } | |
| function submitForm() { | |
| if (editingCity.value) { | |
| form.put(update.url(editingCity.value.id), { | |
| onSuccess: () => { | |
| isSheetOpen.value = false; | |
| }, | |
| }); | |
| } else { | |
| form.post(store.url(), { | |
| onSuccess: () => { | |
| isSheetOpen.value = false; | |
| form.reset(); | |
| }, | |
| }); | |
| } | |
| } | |
| function openDeleteDialog() { | |
| showDeleteDialog.value = true; | |
| } | |
| function confirmDelete() { | |
| if (!editingCity.value) return; | |
| form.delete(destroy.url(editingCity.value.id), { | |
| onSuccess: () => { | |
| showDeleteDialog.value = false; | |
| isSheetOpen.value = false; | |
| editingCity.value = null; | |
| }, | |
| }); | |
| } | |
| function handlePageChange(page: number) { | |
| router.visit(window.location.href, { | |
| data: { page }, | |
| preserveScroll: true, | |
| preserveState: true, | |
| }); | |
| } | |
| const goToDistricts = (cityId: string) => { | |
| router.get(districtRoute().url, { city: cityId }); | |
| }; | |
| </script> | |
| <template> | |
| <AppLayout :breadcrumbs="breadcrumbItems"> | |
| <Head title="Şehirler" /> | |
| <DefinitionsLayout> | |
| <div class="space-y-6"> | |
| <div | |
| class="flex flex-col justify-between gap-4 px-2 sm:flex-row sm:items-center" | |
| > | |
| <Heading | |
| variant="small" | |
| title="Şehirler" | |
| description="Sistem üzerinde kullanılan il/şehir tanımlamaları." | |
| /> | |
| <Button size="sm" class="h-9" @click="openCreateSheet"> | |
| <Plus class="mr-2 h-4 w-4" /> | |
| Yeni Şehir Ekle | |
| </Button> | |
| </div> | |
| <template v-if="cities.data.length > 0"> | |
| <div | |
| class="mx-2 rounded-md border border-border bg-card shadow-none" | |
| > | |
| <Table> | |
| <TableHeader> | |
| <TableRow> | |
| <TableHead>Ad</TableHead> | |
| <TableHead class="text-center" | |
| >İlçeler</TableHead | |
| > | |
| <TableHead class="text-center" | |
| >Durum</TableHead | |
| > | |
| <TableHead class="w-[120px] text-right" | |
| >İşlemler</TableHead | |
| > | |
| </TableRow> | |
| </TableHeader> | |
| <TableBody> | |
| <TableRow | |
| v-for="city in cities.data" | |
| :key="city.id" | |
| class="transition-colors hover:bg-muted/50" | |
| > | |
| <TableCell class="font-medium">{{ | |
| city.name | |
| }}</TableCell> | |
| <TableCell class="text-center"> | |
| <Button | |
| variant="outline" | |
| size="sm" | |
| class="h-8 px-2" | |
| @click="goToDistricts(city.id)" | |
| > | |
| <MapPin class="mr-1 h-3.5 w-3.5" /> | |
| İlçeleri Gör | |
| </Button> | |
| </TableCell> | |
| <TableCell class="text-center"> | |
| <Badge | |
| :variant=" | |
| city.is_active | |
| ? 'default' | |
| : 'secondary' | |
| " | |
| > | |
| {{ | |
| city.is_active | |
| ? 'Aktif' | |
| : 'Pasif' | |
| }} | |
| </Badge> | |
| </TableCell> | |
| <TableCell class="text-right"> | |
| <Button | |
| variant="outline" | |
| size="sm" | |
| class="h-8 px-2" | |
| @click="openEditSheet(city)" | |
| > | |
| <Pencil class="mr-1.5 h-3 w-3" /> | |
| Düzenle | |
| </Button> | |
| </TableCell> | |
| </TableRow> | |
| </TableBody> | |
| </Table> | |
| </div> | |
| <div | |
| v-if="cities.last_page > 1" | |
| class="mt-4 flex flex-col items-center justify-between gap-4 px-2 sm:flex-row" | |
| > | |
| <div class="text-sm font-medium text-muted-foreground"> | |
| Toplam {{ cities.total }} kayıttan | |
| {{ cities.from }}-{{ cities.to }} arası gösteriliyor | |
| </div> | |
| <Pagination | |
| :total="cities.total" | |
| :items-per-page="cities.per_page" | |
| :default-page="cities.current_page" | |
| @update:page="handlePageChange" | |
| > | |
| <PaginationContent> | |
| <PaginationPrevious class="cursor-pointer"> | |
| <ChevronLeft class="h-4 w-4" /> | |
| </PaginationPrevious> | |
| <template | |
| v-for="(item, index) in cities.links" | |
| :key="index" | |
| > | |
| <PaginationItem | |
| v-if=" | |
| item.url && | |
| !isNaN(Number(item.label)) | |
| " | |
| :value="index" | |
| > | |
| <Button | |
| size="icon" | |
| variant="ghost" | |
| class="h-9 w-9" | |
| :class="{ border: item.active }" | |
| @click=" | |
| handlePageChange( | |
| Number(item.label), | |
| ) | |
| " | |
| > | |
| {{ item.label }} | |
| </Button> | |
| </PaginationItem> | |
| </template> | |
| <PaginationNext class="cursor-pointer"> | |
| <ChevronRight class="h-4 w-4" /> | |
| </PaginationNext> | |
| </PaginationContent> | |
| </Pagination> | |
| </div> | |
| </template> | |
| <div v-else class="mx-2"> | |
| <EmptyState | |
| title="Şehir Bulunamadı" | |
| description="Sistemde henüz hiç il oluşturulmamış." | |
| :action-label="'Yeni Şehir Ekle'" | |
| @action="openCreateSheet()" | |
| /> | |
| </div> | |
| </div> | |
| <Sheet v-model:open="isSheetOpen"> | |
| <SheetContent | |
| side="right" | |
| class="flex h-full flex-col p-0 sm:max-w-[400px]" | |
| > | |
| <SheetHeader class="shrink-0 border-b p-6"> | |
| <SheetTitle class="flex items-center gap-2 text-xl"> | |
| <Pencil | |
| v-if="editingCity" | |
| class="h-5 w-5 text-primary" | |
| /> | |
| <Plus v-else class="h-5 w-5 text-primary" /> | |
| {{ | |
| editingCity | |
| ? 'Şehir Düzenle' | |
| : 'Yeni Şehir Ekle' | |
| }} | |
| </SheetTitle> | |
| <SheetDescription> | |
| {{ | |
| editingCity | |
| ? 'Şehir bilgilerini güncelleyin.' | |
| : 'Sisteme yeni bir il ekleyin.' | |
| }} | |
| </SheetDescription> | |
| </SheetHeader> | |
| <form | |
| id="cityForm" | |
| class="flex-1 space-y-6 overflow-y-auto p-6" | |
| @submit.prevent="submitForm" | |
| > | |
| <div class="space-y-2"> | |
| <Label for="name" class="text-sm font-bold" | |
| >Şehir Adı</Label | |
| > | |
| <Input | |
| id="name" | |
| v-model="form.name" | |
| placeholder="İstanbul" | |
| class="h-11" | |
| /> | |
| <InputError :message="form.errors.name" /> | |
| </div> | |
| <div class="flex items-center gap-2"> | |
| <Switch | |
| id="is_active" | |
| :checked="form.is_active" | |
| @update:checked="form.is_active = $event" | |
| /> | |
| <Label for="is_active">Aktif</Label> | |
| </div> | |
| </form> | |
| <SheetFooter class="shrink-0 border-t bg-muted/10 p-6"> | |
| <div class="flex w-full flex-col gap-3"> | |
| <Button | |
| type="submit" | |
| form="cityForm" | |
| class="h-11 w-full" | |
| :disabled="form.processing" | |
| > | |
| <Loader2 | |
| v-if="form.processing" | |
| class="mr-2 h-4 w-4 animate-spin" | |
| /> | |
| <Check v-else class="mr-2 h-4 w-4" /> | |
| {{ | |
| form.processing | |
| ? 'Kaydediliyor...' | |
| : editingCity | |
| ? 'Değişiklikleri Kaydet' | |
| : 'Şehir Ekle' | |
| }} | |
| </Button> | |
| <Button | |
| type="button" | |
| variant="ghost" | |
| class="h-11 w-full" | |
| @click="isSheetOpen = false" | |
| > | |
| <X class="mr-2 h-4 w-4" /> İptal | |
| </Button> | |
| <Button | |
| v-if="editingCity" | |
| type="button" | |
| variant="outline" | |
| class="h-11 w-full border-destructive/30 text-destructive hover:bg-destructive/5" | |
| @click="openDeleteDialog" | |
| > | |
| <Trash2 class="mr-2 h-4 w-4" /> | |
| Şehiri Sil | |
| </Button> | |
| </div> | |
| </SheetFooter> | |
| </SheetContent> | |
| </Sheet> | |
| <AlertDialog v-model:open="showDeleteDialog"> | |
| <AlertDialogContent> | |
| <AlertDialogHeader> | |
| <AlertDialogTitle | |
| >Şehiri silmek istediğinize emin | |
| misiniz?</AlertDialogTitle | |
| > | |
| <AlertDialogDescription> | |
| <strong>{{ editingCity?.name }}</strong> kalıcı | |
| olarak silinecektir. Bu işlem geri alınamaz. | |
| </AlertDialogDescription> | |
| </AlertDialogHeader> | |
| <AlertDialogFooter> | |
| <AlertDialogCancel>İptal</AlertDialogCancel> | |
| <AlertDialogAction | |
| class="bg-destructive text-destructive-foreground hover:bg-destructive/90" | |
| @click="confirmDelete" | |
| > | |
| Evet, Sil | |
| </AlertDialogAction> | |
| </AlertDialogFooter> | |
| </AlertDialogContent> | |
| </AlertDialog> | |
| </DefinitionsLayout> | |
| </AppLayout> | |
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Country Controller index metod | |
| /** | |
| * Ülke listeleme sayfası. | |
| */ | |
| public function index(): Response | |
| { | |
| return Inertia::render('panel/definitions/Country/Index', [ | |
| 'countries' => $this->countryService->all(), | |
| 'defaultCountryId' => settings('default_country'), | |
| ]); | |
| } | |
| Country Service all metod | |
| public function all(): LengthAwarePaginator | |
| { | |
| return Country::query() | |
| ->orderBy('sort_order') | |
| ->orderBy('name') | |
| ->paginate(config('otomasyon.pagination.per_page', 15)); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script setup lang="ts"> | |
| import { Head, router, useForm } from '@inertiajs/vue3'; | |
| import { Plus, Pencil, Trash2, Loader2, X, Check, ChevronLeft, ChevronRight, MapPin } from 'lucide-vue-next'; | |
| import { ref } from 'vue'; | |
| import { store, update, destroy } from '@/actions/App/Http/Controllers/Panel/Definitions/CountryController'; | |
| import Heading from '@/components/common/Heading.vue'; | |
| import InputError from '@/components/common/InputError.vue'; | |
| import { | |
| AlertDialog, | |
| AlertDialogAction, | |
| AlertDialogCancel, | |
| AlertDialogContent, | |
| AlertDialogDescription, | |
| AlertDialogFooter, | |
| AlertDialogHeader, | |
| AlertDialogTitle, | |
| } from '@/components/ui/alert-dialog'; | |
| import { Badge } from '@/components/ui/badge'; | |
| import { Button } from '@/components/ui/button'; | |
| import EmptyState from '@/components/ui/empty-state/EmptyState.vue'; | |
| import { Input } from '@/components/ui/input'; | |
| import { Label } from '@/components/ui/label'; | |
| import { | |
| Pagination, | |
| PaginationContent, | |
| PaginationItem, | |
| PaginationNext, | |
| PaginationPrevious, | |
| } from '@/components/ui/pagination'; | |
| import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle } from '@/components/ui/sheet'; | |
| import { Switch } from '@/components/ui/switch'; | |
| import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; | |
| import { useClearFormErrors } from '@/composables/useClearFormErrors'; | |
| import AppLayout from '@/layouts/PanelLayout.vue'; | |
| import DefinitionsLayout from '@/pages/panel/definitions/partials/Layout.vue'; | |
| import { index as cityIndex } from '@/routes/panel/settings/definitions/cities'; | |
| import { index as countryRoute } from '@/routes/panel/settings/definitions/countries'; | |
| import { type BreadcrumbItem, type Country, type PaginationResponse } from '@/types'; | |
| const props = defineProps<{ | |
| countries: PaginationResponse<Country>; | |
| defaultCountryId: string | null; | |
| }>(); | |
| const breadcrumbItems: BreadcrumbItem[] = [ | |
| { title: 'Tanımlamalar', href: '#' }, | |
| { title: 'Ülkeler', href: countryRoute().url }, | |
| ]; | |
| const isSheetOpen = ref(false); | |
| const showDeleteDialog = ref(false); | |
| const editingCountry = ref<Country | null>(null); | |
| const form = useForm({ | |
| code: '', | |
| name: '', | |
| is_active: true, | |
| sort_order: 0, | |
| }); | |
| useClearFormErrors(form); | |
| function openCreateSheet() { | |
| editingCountry.value = null; | |
| form.reset(); | |
| form.clearErrors(); | |
| isSheetOpen.value = true; | |
| } | |
| function openEditSheet(country: Country) { | |
| editingCountry.value = country; | |
| form.code = country.code; | |
| form.name = country.name; | |
| form.is_active = country.is_active; | |
| form.sort_order = country.sort_order; | |
| form.clearErrors(); | |
| isSheetOpen.value = true; | |
| } | |
| function submitForm() { | |
| if (editingCountry.value) { | |
| form.put(update.url(editingCountry.value.id), { | |
| onSuccess: () => { isSheetOpen.value = false; }, | |
| }); | |
| } else { | |
| form.post(store.url(), { | |
| onSuccess: () => { isSheetOpen.value = false; form.reset(); }, | |
| }); | |
| } | |
| } | |
| function openDeleteDialog() { | |
| showDeleteDialog.value = true; | |
| } | |
| function confirmDelete() { | |
| if (!editingCountry.value) return; | |
| form.delete(destroy.url(editingCountry.value.id), { | |
| onSuccess: () => { | |
| showDeleteDialog.value = false; | |
| isSheetOpen.value = false; | |
| editingCountry.value = null; | |
| }, | |
| }); | |
| } | |
| function handlePageChange(page: number) { | |
| router.visit(countryRoute().url, { | |
| data: { page }, | |
| preserveScroll: true, | |
| preserveState: true, | |
| }); | |
| } | |
| const goToCities = (countryId: string) => { | |
| router.get(cityIndex().url, { country: countryId }); | |
| }; | |
| </script> | |
| <template> | |
| <AppLayout :breadcrumbs="breadcrumbItems"> | |
| <Head title="Ülkeler" /> | |
| <DefinitionsLayout> | |
| <div class="space-y-6"> | |
| <div class="flex flex-col justify-between gap-4 sm:flex-row sm:items-center px-2"> | |
| <Heading variant="small" title="Ülkeler" | |
| description="Sistem üzerinde kullanılan ülke tanımlamaları." /> | |
| <div> | |
| <Button size="sm" class="h-9" @click="openCreateSheet"> | |
| <Plus class="mr-2 h-4 w-4" /> | |
| Yeni Ülke Ekle | |
| </Button> | |
| </div> | |
| </div> | |
| <template v-if="countries.data.length > 0"> | |
| <div class="rounded-md border border-border bg-card shadow-none mx-2"> | |
| <Table> | |
| <TableHeader> | |
| <TableRow> | |
| <TableHead>Kod</TableHead> | |
| <TableHead>Ad</TableHead> | |
| <TableHead>Şehirler</TableHead> | |
| <TableHead class="text-center">Varsayılan</TableHead> | |
| <TableHead class="text-center">Durum</TableHead> | |
| <TableHead class="text-right w-[100px]">İşlemler | |
| </TableHead> | |
| </TableRow> | |
| </TableHeader> | |
| <TableBody> | |
| <TableRow v-for="country in countries.data" :key="country.id" | |
| class="hover:bg-muted/50 transition-colors"> | |
| <TableCell class="font-medium">{{ country.code }}</TableCell> | |
| <TableCell>{{ country.name }}</TableCell> | |
| <TableCell> | |
| <Button | |
| variant="outline" | |
| size="sm" | |
| class="h-8" | |
| @click="goToCities(country.id)" | |
| > | |
| <MapPin class="mr-1 h-4 w-4" /> | |
| İlleri Gör | |
| </Button> | |
| </TableCell> | |
| <TableCell class="text-center"> | |
| <Badge v-if="country.id === props.defaultCountryId" variant="default">Varsayılan | |
| </Badge> | |
| </TableCell> | |
| <TableCell class="text-center"> | |
| <Badge :variant="country.is_active ? 'default' : 'secondary'"> | |
| {{ country.is_active ? 'Aktif' : 'Pasif' }} | |
| </Badge> | |
| </TableCell> | |
| <TableCell class="text-right"> | |
| <Button variant="outline" size="sm" class="h-8" @click="openEditSheet(country)"> | |
| <Pencil class="mr-2 h-3.5 w-3.5" /> | |
| Düzenle | |
| </Button> | |
| </TableCell> | |
| </TableRow> | |
| </TableBody> | |
| </Table> | |
| </div> | |
| <div v-if="countries.last_page > 1" | |
| class="mt-4 flex flex-col items-center justify-between gap-4 sm:flex-row px-2"> | |
| <div class="text-sm text-muted-foreground font-medium"> | |
| Toplam {{ countries.total }} kayıttan {{ countries.from }}-{{ countries.to }} arası | |
| gösteriliyor | |
| </div> | |
| <Pagination :total="countries.total" :items-per-page="countries.per_page" | |
| :default-page="countries.current_page" @update:page="handlePageChange"> | |
| <PaginationContent> | |
| <PaginationPrevious class="cursor-pointer"> | |
| <ChevronLeft class="h-4 w-4" /> | |
| </PaginationPrevious> | |
| <template v-for="(item, index) in countries.links" :key="index"> | |
| <PaginationItem v-if="item.url && !isNaN(Number(item.label))" :value="index"> | |
| <Button size="icon" variant="ghost" class="h-9 w-9" | |
| :class="{ 'border': item.active }" | |
| @click="handlePageChange(Number(item.label))"> | |
| {{ item.label }} | |
| </Button> | |
| </PaginationItem> | |
| </template> | |
| <PaginationNext class="cursor-pointer"> | |
| <ChevronRight class="h-4 w-4" /> | |
| </PaginationNext> | |
| </PaginationContent> | |
| </Pagination> | |
| </div> | |
| </template> | |
| <div v-else class="mx-2"> | |
| <EmptyState title="Ülke Bulunamadı" description="Sistemde henüz hiç ülke oluşturulmamış." | |
| :action-label="'Yeni Ülke Ekle'" | |
| @action="openCreateSheet()" /> | |
| </div> | |
| </div> | |
| <Sheet v-model:open="isSheetOpen"> | |
| <SheetContent side="right" class="sm:max-w-[400px] p-0 flex flex-col h-full"> | |
| <SheetHeader class="p-6 border-b shrink-0"> | |
| <SheetTitle class="flex items-center gap-2 text-xl"> | |
| <Pencil v-if="editingCountry" class="h-5 w-5 text-primary" /> | |
| <Plus v-else class="h-5 w-5 text-primary" /> | |
| {{ editingCountry ? 'Ülke Düzenle' : 'Yeni Ülke Ekle' }} | |
| </SheetTitle> | |
| <SheetDescription> | |
| {{ editingCountry ? 'Ülke bilgilerini güncelleyin.' : 'Sisteme yeni bir ülke ekleyin.' }} | |
| </SheetDescription> | |
| </SheetHeader> | |
| <form id="countryForm" class="flex-1 overflow-y-auto p-6 space-y-6" @submit.prevent="submitForm"> | |
| <div class="space-y-2"> | |
| <Label for="code" class="text-sm font-bold">Kod</Label> | |
| <Input id="code" v-model="form.code" placeholder="TR" class="h-11" /> | |
| <InputError :message="form.errors.code" /> | |
| </div> | |
| <div class="space-y-2"> | |
| <Label for="name" class="text-sm font-bold">Ad</Label> | |
| <Input id="name" v-model="form.name" placeholder="Türkiye" class="h-11" /> | |
| <InputError :message="form.errors.name" /> | |
| </div> | |
| <div class="space-y-2"> | |
| <Label for="sort_order" class="text-sm font-bold">Sıralama</Label> | |
| <Input id="sort_order" v-model.number="form.sort_order" type="number" min="0" | |
| class="h-11" /> | |
| <InputError :message="form.errors.sort_order" /> | |
| </div> | |
| <div class="flex items-center gap-2"> | |
| <Switch id="is_active" v-model:checked="form.is_active" /> | |
| <Label for="is_active">Aktif</Label> | |
| </div> | |
| </form> | |
| <SheetFooter class="p-6 border-t bg-muted/10 shrink-0"> | |
| <div class="flex w-full flex-col gap-3"> | |
| <Button type="submit" form="countryForm" class="w-full h-11" :disabled="form.processing"> | |
| <Loader2 v-if="form.processing" class="mr-2 h-4 w-4 animate-spin" /> | |
| <Check v-else class="mr-2 h-4 w-4" /> | |
| {{ form.processing ? 'Kaydediliyor...' : (editingCountry ? 'Değişiklikleri Kaydet' : | |
| 'Ülke Ekle') }} | |
| </Button> | |
| <Button type="button" variant="ghost" class="w-full h-11" @click="isSheetOpen = false"> | |
| <X class="mr-2 h-4 w-4" /> İptal | |
| </Button> | |
| <Button v-if="editingCountry && editingCountry.id !== props.defaultCountryId" | |
| type="button" variant="outline" | |
| class="w-full h-11 text-destructive border-destructive/30 hover:bg-destructive/5" | |
| @click="openDeleteDialog"> | |
| <Trash2 class="mr-2 h-4 w-4" /> | |
| Ülkeyi Sil | |
| </Button> | |
| </div> | |
| </SheetFooter> | |
| </SheetContent> | |
| </Sheet> | |
| <AlertDialog v-model:open="showDeleteDialog"> | |
| <AlertDialogContent> | |
| <AlertDialogHeader> | |
| <AlertDialogTitle>Ülkeyi silmek istediğinize emin misiniz?</AlertDialogTitle> | |
| <AlertDialogDescription> | |
| <strong>{{ editingCountry?.name }} ({{ editingCountry?.code }})</strong> kalıcı olarak | |
| silinecektir. Bu | |
| işlem geri alınamaz. | |
| </AlertDialogDescription> | |
| </AlertDialogHeader> | |
| <AlertDialogFooter> | |
| <AlertDialogCancel>İptal</AlertDialogCancel> | |
| <AlertDialogAction class="bg-destructive text-destructive-foreground hover:bg-destructive/90" | |
| @click="confirmDelete"> | |
| Evet, Sil | |
| </AlertDialogAction> | |
| </AlertDialogFooter> | |
| </AlertDialogContent> | |
| </AlertDialog> | |
| </DefinitionsLayout> | |
| </AppLayout> | |
| </template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export type Country = { | |
| id: string; | |
| code: string; | |
| name: string; | |
| is_active: boolean; | |
| sort_order: number; | |
| created_at: string; | |
| updated_at: string; | |
| }; | |
| export type City = { | |
| id: string; | |
| country_id: string; | |
| name: string; | |
| is_active: boolean; | |
| sort_order: number; | |
| created_at: string; | |
| updated_at: string; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment