refactor: simplify approval process in owner verifications by removing approval dialog and related logic for improved user experience
This commit is contained in:
parent
322af0c1e8
commit
26d4794489
@ -31,12 +31,9 @@ const props = defineProps<{
|
||||
|
||||
const { can } = useCan();
|
||||
|
||||
const approveDialogOpen = ref(false);
|
||||
const rejectDialogOpen = ref(false);
|
||||
|
||||
const approveForm = useForm({
|
||||
approval_note: '',
|
||||
});
|
||||
const approveForm = useForm({});
|
||||
|
||||
const rejectForm = useForm({
|
||||
reason: '',
|
||||
@ -46,11 +43,6 @@ function submitApprove() {
|
||||
approveForm
|
||||
.post(`/admin/manage/owner-verifications/${props.cutting.id}/approve`, {
|
||||
preserveScroll: true,
|
||||
onSuccess: () => {
|
||||
approveDialogOpen.value = false;
|
||||
approveForm.reset();
|
||||
toast.success('Verifikasi berhasil disetujui.');
|
||||
},
|
||||
onError: (errors) => {
|
||||
const message = Object.values(errors)[0];
|
||||
toast.error(message ?? 'Gagal menyetujui verifikasi.');
|
||||
@ -65,7 +57,6 @@ function submitReject() {
|
||||
onSuccess: () => {
|
||||
rejectDialogOpen.value = false;
|
||||
rejectForm.reset();
|
||||
toast.success('Verifikasi berhasil ditolak.');
|
||||
},
|
||||
onError: (errors) => {
|
||||
const message = Object.values(errors)[0];
|
||||
@ -83,7 +74,8 @@ function submitReject() {
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
class="text-green-600 hover:text-green-700"
|
||||
@click="approveDialogOpen = true"
|
||||
:disabled="approveForm.processing"
|
||||
@click="submitApprove"
|
||||
>
|
||||
<Check class="size-3.5" />
|
||||
<span class="sr-only">Setujui</span>
|
||||
@ -108,59 +100,6 @@ function submitReject() {
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
<!-- Approve Dialog -->
|
||||
<Dialog v-model:open="approveDialogOpen">
|
||||
<DialogContent class="sm:max-w-lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Setujui Verifikasi</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="rounded-md border p-3 text-xs space-y-2">
|
||||
<div>
|
||||
<span class="text-muted-foreground">Cutting:</span>
|
||||
<span class="ml-1 font-medium">#{{ cutting.id }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-muted-foreground">Deskripsi:</span>
|
||||
<span class="ml-1 font-medium">{{ cutting.description ?? '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Field>
|
||||
<FieldLabel for="approval-note">Catatan (Opsional)</FieldLabel>
|
||||
<Textarea
|
||||
id="approval-note"
|
||||
v-model="approveForm.approval_note"
|
||||
placeholder="Tambahkan catatan persetujuan..."
|
||||
rows="3"
|
||||
/>
|
||||
<FieldError
|
||||
:errors="approveForm.errors.approval_note ? [approveForm.errors.approval_note] : []"
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
@click="approveDialogOpen = false"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
:disabled="approveForm.processing"
|
||||
@click="submitApprove"
|
||||
>
|
||||
<Check class="size-4" />
|
||||
Setujui
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<!-- Reject Dialog -->
|
||||
<Dialog v-model:open="rejectDialogOpen">
|
||||
<DialogContent class="sm:max-w-lg">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { router, useForm } from '@inertiajs/vue3';
|
||||
import { Check, Copy } from '@lucide/vue';
|
||||
import { Check } from '@lucide/vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { toast } from 'vue-sonner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@ -43,7 +43,6 @@ const { can } = useCan();
|
||||
|
||||
const verifyDialogOpen = ref(false);
|
||||
const allMatches = ref(true);
|
||||
const useSamePrice = ref(true);
|
||||
|
||||
function buildEmptyPrices(): Record<string, string> {
|
||||
return Object.fromEntries(PRICE_TYPES.map((type) => [type, '']));
|
||||
@ -73,7 +72,6 @@ const verifyForm = useForm({
|
||||
watch(verifyDialogOpen, (isOpen) => {
|
||||
if (isOpen) {
|
||||
allMatches.value = true;
|
||||
useSamePrice.value = true;
|
||||
verifyForm.verification_note = '';
|
||||
verifyForm.results = props.cutting.results.map(res => ({
|
||||
product_variant_id: res.product_variant?.id || 0,
|
||||
@ -118,20 +116,6 @@ function setAllMatches(value: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleUseSamePrice(checked: boolean) {
|
||||
useSamePrice.value = checked;
|
||||
|
||||
if (!checked || !verifyForm.variant_prices[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const source = verifyForm.variant_prices[0].prices;
|
||||
verifyForm.variant_prices = verifyForm.variant_prices.map((row) => ({
|
||||
...row,
|
||||
prices: { ...source },
|
||||
}));
|
||||
}
|
||||
|
||||
function setSharedPrice(type: string, value: string) {
|
||||
verifyForm.shared_prices[type] = value;
|
||||
verifyForm.variant_prices = verifyForm.variant_prices.map((row) => ({
|
||||
@ -140,27 +124,6 @@ function setSharedPrice(type: string, value: string) {
|
||||
}));
|
||||
}
|
||||
|
||||
function setVariantPrice(index: number, type: string, value: string) {
|
||||
const row = verifyForm.variant_prices[index];
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
|
||||
row.prices[type] = value;
|
||||
}
|
||||
|
||||
function applyPriceToAll(index: number) {
|
||||
const source = verifyForm.variant_prices[index];
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
verifyForm.variant_prices = verifyForm.variant_prices.map((row) => ({
|
||||
...row,
|
||||
prices: { ...source.prices },
|
||||
}));
|
||||
}
|
||||
|
||||
function buildResultPricesPayload() {
|
||||
return verifyForm.variant_prices.map((row) => ({
|
||||
product_variant_id: row.product_variant_id,
|
||||
@ -281,18 +244,7 @@ function submitVerify() {
|
||||
|
||||
<Separator />
|
||||
|
||||
<div v-if="verifyForm.variant_prices.length > 1" class="flex items-center justify-between rounded-lg border p-3">
|
||||
<Label for="use-same-price" class="text-sm font-medium">
|
||||
Gunakan harga yang sama untuk semua varian
|
||||
</Label>
|
||||
<Switch
|
||||
id="use-same-price"
|
||||
:model-value="useSamePrice"
|
||||
@update:model-value="toggleUseSamePrice"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="useSamePrice" class="space-y-2">
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm font-medium">Harga</p>
|
||||
<div class="grid gap-2 sm:grid-cols-2">
|
||||
<Field v-for="type in PRICE_TYPES" :key="`shared-${type}`">
|
||||
@ -308,38 +260,6 @@ function submitVerify() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="space-y-3">
|
||||
<p class="text-sm font-medium">Harga Per Varian</p>
|
||||
<div v-for="(row, index) in verifyForm.variant_prices" :key="row.product_variant_id" class="space-y-2 rounded-lg border p-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm font-medium truncate">{{ row.name }}</p>
|
||||
<Button
|
||||
v-if="verifyForm.variant_prices.length > 1"
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
class="shrink-0"
|
||||
@click="applyPriceToAll(index)"
|
||||
>
|
||||
<Copy class="size-3" />
|
||||
Terapkan ke Semua
|
||||
</Button>
|
||||
</div>
|
||||
<div class="grid gap-2 sm:grid-cols-2">
|
||||
<Field v-for="type in PRICE_TYPES" :key="`${row.product_variant_id}-${type}`">
|
||||
<FieldLabel class="text-xs" :for="`variant-price-${index}-${type}`">
|
||||
{{ PRICE_TYPE_LABELS[type] }}
|
||||
</FieldLabel>
|
||||
<RupiahInput
|
||||
:id="`variant-price-${index}-${type}`"
|
||||
:model-value="row.prices[type]"
|
||||
@update:model-value="setVariantPrice(index, type, $event)"
|
||||
/>
|
||||
</Field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FieldError
|
||||
:errors="verifyForm.errors.result_prices ? [verifyForm.errors.result_prices] : []"
|
||||
/>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user