146 lines
4.3 KiB
Vue
146 lines
4.3 KiB
Vue
<script setup lang="ts">
|
||
import { ref, computed, watch } from 'vue';
|
||
import AppLayout from '@/layouts/AppLayout.vue';
|
||
import { Head, Link, useForm, usePage } from '@inertiajs/vue3';
|
||
import type { BreadcrumbItem } from '@/types';
|
||
|
||
import { Button } from '@/components/ui/button';
|
||
import { Label } from '@/components/ui/label';
|
||
|
||
import {
|
||
Combobox,
|
||
ComboboxAnchor,
|
||
ComboboxTrigger,
|
||
ComboboxEmpty,
|
||
ComboboxGroup,
|
||
ComboboxItem,
|
||
ComboboxItemIndicator,
|
||
ComboboxList,
|
||
} from '@/components/ui/combobox';
|
||
import { Check, ChevronsUpDown } from 'lucide-vue-next';
|
||
|
||
interface CategoryOption {
|
||
key: string;
|
||
description: string;
|
||
}
|
||
|
||
interface PageProps {
|
||
[key: string]: any
|
||
categories: CategoryOption[];
|
||
}
|
||
|
||
const page = usePage<PageProps>();
|
||
const categories = computed(() => page.props.categories);
|
||
|
||
const form = useForm({
|
||
category: '', // will hold the chosen key (e.g. 'smartdok')
|
||
key: '', // the actual API‐key string
|
||
});
|
||
|
||
// Bind this to the Combobox’s modelValue:
|
||
const selectedCategory = ref<CategoryOption | null>(
|
||
// No preselection by default
|
||
null
|
||
);
|
||
|
||
// Whenever the user picks a category, update form.category:
|
||
watch(selectedCategory, (val) => {
|
||
form.category = val?.key ?? '';
|
||
});
|
||
|
||
const breadcrumbs: BreadcrumbItem[] = [
|
||
{ title: 'Dashbord', href: '/dashboard' },
|
||
{ title: 'Legg til api-nøkkel', href: route('apikeys.create') },
|
||
];
|
||
|
||
function submit() {
|
||
form.post(route('apikeys.store'));
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<Head title="Legg til API nøkkel" />
|
||
|
||
<AppLayout :breadcrumbs="breadcrumbs">
|
||
<div class="p-6 space-y-8 max-w-2xl mx-auto">
|
||
<h3 class="text-2xl font-extrabold">Legg til API nøkkel for ny tjeneste</h3>
|
||
|
||
<form @submit.prevent="submit" class="space-y-6">
|
||
<!-- Non-searchable dropdown for “Tjeneste” -->
|
||
<div>
|
||
<Label for="combobox-category">Tjeneste</Label>
|
||
<Combobox
|
||
v-model:modelValue="selectedCategory"
|
||
by="description"
|
||
class="mt-2"
|
||
>
|
||
<ComboboxAnchor>
|
||
<ComboboxTrigger as-child>
|
||
<Button
|
||
id="combobox-category"
|
||
variant="outline"
|
||
class="justify-between w-full"
|
||
>
|
||
{{
|
||
selectedCategory
|
||
? selectedCategory.description
|
||
: 'Velg en tjeneste…'
|
||
}}
|
||
<ChevronsUpDown class="ml-2 h-4 w-4 opacity-50" />
|
||
</Button>
|
||
</ComboboxTrigger>
|
||
</ComboboxAnchor>
|
||
|
||
<ComboboxList class="mt-1 w-full">
|
||
<ComboboxEmpty>
|
||
Ingen tjenester funnet…
|
||
</ComboboxEmpty>
|
||
<ComboboxGroup>
|
||
<ComboboxItem
|
||
v-for="opt in categories"
|
||
:key="opt.key"
|
||
:value="opt"
|
||
class="flex items-center justify-between px-3 py-2 hover:bg-accent focus:bg-accent cursor-pointer"
|
||
>
|
||
{{ opt.description }}
|
||
<ComboboxItemIndicator>
|
||
<Check class="ml-auto h-4 w-4" />
|
||
</ComboboxItemIndicator>
|
||
</ComboboxItem>
|
||
</ComboboxGroup>
|
||
</ComboboxList>
|
||
</Combobox>
|
||
<p v-if="form.errors.category" class="mt-1 text-sm text-red-600">
|
||
{{ form.errors.category }}
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Free‐form “Key” (API‐nøkkelverdi) -->
|
||
<div>
|
||
<Label for="key">Nøkkelverdi</Label>
|
||
<textarea
|
||
id="key"
|
||
v-model="form.key"
|
||
placeholder="Skriv eller lim inn nøkkelstrengen"
|
||
class="mt-2 w-full rounded-md border px-3 py-2 text-base focus:outline-none focus:ring-2 focus:ring-primary"
|
||
rows="4"
|
||
></textarea>
|
||
<p v-if="form.errors.key" class="mt-1 text-sm text-red-600">
|
||
{{ form.errors.key }}
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Actions -->
|
||
<div class="flex justify-end space-x-4">
|
||
<Link :href="route('dashboard')">
|
||
<Button variant="outline">Avbryt</Button>
|
||
</Link>
|
||
<Button type="submit" :disabled="form.processing">
|
||
Lagre
|
||
</Button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</AppLayout>
|
||
</template>
|