i18n (all 3 languages - EN, ES, PT-BR): - ApiKeys page + CreateApiKeyDialog: 26 strings - billing/Processing page: 8 strings - onboarding/Step1 + Step2: 10 strings (new onboarding.php) - UserMenuContent: 7 strings (Account, Theme, Language, Log out) - PhotoUpload: 4 strings (Upload, Remove, hint) - TimezoneCombobox: 3 strings - DatePicker: 1 string - workspaces/Create + Index: full i18n (new workspaces.php) Toast system: - Unify Toast.vue with Sonner (copied from sendkit) - Flash messages + JS toasts use same system - Icon colors via CSS (success/error/warning/info) - Position bottom-right UI improvements: - Posts Edit: move trash/schedule/publish to header-right slot - Posts Edit: labels/hashtags/datepicker stay in top bar with platforms - Posts Edit: delete post requires typing DELETE to confirm - Posts Edit: Labels button with icon+text, always visible - DatePicker: w-full by default, w-auto via class override - Fix "Etiquetas" -> "Etiqueta" (remove plural) - Posts breadcrumbs: /posts shows "Posts > All Posts" - Calendar breadcrumbs: "Posts > Calendar" - Edit breadcrumbs: "Posts > Edit Post" - Remove unused AppHeader.vue and AppHeaderLayout.vue All 728 tests passing.
77 lines
2.8 KiB
Vue
77 lines
2.8 KiB
Vue
<script setup lang="ts">
|
|
import { Form } from '@inertiajs/vue3';
|
|
import { trans } from 'laravel-vue-i18n';
|
|
import { ref } from 'vue';
|
|
|
|
import ApiKeyController from '@/actions/App/Http/Controllers/App/ApiKeyController';
|
|
import DatePicker from '@/components/DatePicker.vue';
|
|
import InputError from '@/components/InputError.vue';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from '@/components/ui/dialog';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
|
|
const open = defineModel<boolean>('open', { default: false });
|
|
|
|
const expiresAt = ref('');
|
|
|
|
const onSuccess = () => {
|
|
expiresAt.value = '';
|
|
open.value = false;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Dialog v-model:open="open">
|
|
<DialogContent class="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>{{ $t('settings.api_keys.create_dialog.title') }}</DialogTitle>
|
|
<DialogDescription>
|
|
{{ $t('settings.api_keys.create_dialog.description') }}
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<Form
|
|
v-bind="ApiKeyController.store.form()"
|
|
class="space-y-4"
|
|
v-slot="{ errors, processing }"
|
|
@success="onSuccess"
|
|
>
|
|
<div class="grid gap-2">
|
|
<Label for="token-name">{{ $t('settings.api_keys.create_dialog.name') }}</Label>
|
|
<Input
|
|
id="token-name"
|
|
name="name"
|
|
:placeholder="trans('settings.api_keys.create_dialog.name_placeholder')"
|
|
/>
|
|
<InputError :message="errors.name" />
|
|
</div>
|
|
<div class="grid gap-2">
|
|
<Label>{{ $t('settings.api_keys.create_dialog.expires') }}</Label>
|
|
<DatePicker
|
|
name="token-expires"
|
|
v-model="expiresAt"
|
|
:show-time="false"
|
|
:placeholder="trans('settings.api_keys.create_dialog.expires_placeholder')"
|
|
/>
|
|
<input type="hidden" name="expires_at" :value="expiresAt" />
|
|
<InputError :message="errors.expires_at" />
|
|
</div>
|
|
<DialogFooter>
|
|
<Button type="submit" :disabled="processing">
|
|
{{ $t('settings.api_keys.create_dialog.submit') }}
|
|
</Button>
|
|
<Button type="button" variant="secondary" @click="open = false">
|
|
{{ $t('settings.api_keys.create_dialog.cancel') }}
|
|
</Button>
|
|
</DialogFooter>
|
|
</Form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</template>
|