202 lines
12 KiB
PHP
202 lines
12 KiB
PHP
<div x-data="{
|
|
step: 1,
|
|
loading: false,
|
|
settings: @js(auth()->user()->company->settings ?? []),
|
|
formData: {
|
|
names: { zh_TW: '', en: '', ja: '' },
|
|
barcode: '',
|
|
spec: '',
|
|
category_id: '',
|
|
manufacturer: '',
|
|
track_limit: 10,
|
|
spring_limit: 10,
|
|
price: 0,
|
|
cost: 0,
|
|
member_price: 0,
|
|
metadata: {
|
|
material_code: '',
|
|
full_points: 0,
|
|
half_points: 0,
|
|
half_points_cash: 0
|
|
}
|
|
},
|
|
async submit() {
|
|
this.loading = true;
|
|
try {
|
|
const response = await fetch('{{ route('admin.products.store') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
},
|
|
body: JSON.stringify(this.formData)
|
|
});
|
|
const result = await response.json();
|
|
if (result.success) {
|
|
window.location.reload();
|
|
} else {
|
|
alert(result.message || 'Saving failed');
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
}
|
|
}" class="p-4 sm:p-7">
|
|
<!-- Header -->
|
|
<div class="text-center mb-8">
|
|
<h3 class="text-2xl font-black text-slate-800 dark:text-white tracking-tight uppercase">
|
|
{{ __('Create New Product') }}
|
|
</h3>
|
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">
|
|
{{ __('Add a new item to your product collection') }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Stepper (Optional but adds luxury feel) -->
|
|
<div class="flex items-center justify-center gap-4 mb-8">
|
|
<div :class="step >= 1 ? 'bg-cyan-500 text-white' : 'bg-slate-100 dark:bg-slate-800 text-slate-400'" class="w-8 h-8 rounded-full flex items-center justify-center text-xs font-black transition-all">1</div>
|
|
<div class="w-12 h-px bg-slate-200 dark:border-slate-700"></div>
|
|
<div :class="step >= 2 ? 'bg-cyan-500 text-white' : 'bg-slate-100 dark:bg-slate-800 text-slate-400'" class="w-8 h-8 rounded-full flex items-center justify-center text-xs font-black transition-all">2</div>
|
|
</div>
|
|
|
|
<form @submit.prevent="submit">
|
|
<!-- Step 1: Basic Info & Multilingual Names -->
|
|
<div x-show="step === 1" x-transition class="space-y-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<!-- Multilingual Names -->
|
|
<div class="md:col-span-3 space-y-4">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Product Name') }} ({{ __('Multilingual') }})</label>
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<div class="relative">
|
|
<span class="absolute top-2.5 left-3 text-[10px] font-black text-cyan-500/50 uppercase">ZH</span>
|
|
<input type="text" x-model="formData.names.zh_TW" required placeholder="{{ __('Traditional Chinese') }}" class="luxury-input pl-10">
|
|
</div>
|
|
<div class="relative">
|
|
<span class="absolute top-2.5 left-3 text-[10px] font-black text-cyan-500/50 uppercase">EN</span>
|
|
<input type="text" x-model="formData.names.en" placeholder="{{ __('English') }}" class="luxury-input pl-10">
|
|
</div>
|
|
<div class="relative">
|
|
<span class="absolute top-2.5 left-3 text-[10px] font-black text-cyan-500/50 uppercase">JA</span>
|
|
<input type="text" x-model="formData.names.ja" placeholder="{{ __('Japanese') }}" class="luxury-input pl-10">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Barcode & Spec -->
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Barcode') }}</label>
|
|
<input type="text" x-model="formData.barcode" class="luxury-input">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Specification') }}</label>
|
|
<input type="text" x-model="formData.spec" class="luxury-input">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Category') }}</label>
|
|
<select x-model="formData.category_id" class="luxury-input">
|
|
<option value="">{{ __('Select Category') }}</option>
|
|
@foreach($categories as $cat)
|
|
<option value="{{ $cat->id }}">{{ $cat->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end pt-4">
|
|
<button type="button" @click="step = 2" class="px-8 py-3 bg-slate-900 dark:bg-slate-700 text-white rounded-xl font-black text-xs uppercase tracking-[0.2em] hover:bg-cyan-600 transition-all shadow-lg shadow-cyan-500/10">
|
|
{{ __('Next') }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Step 2: Logistics & Pricing -->
|
|
<div x-show="step === 2" x-transition class="space-y-6">
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-6">
|
|
<!-- Track & Spring Limits -->
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Track Limit') }}</label>
|
|
<input type="number" x-model="formData.track_limit" class="luxury-input">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Spring Limit') }}</label>
|
|
<input type="number" x-model="formData.spring_limit" class="luxury-input">
|
|
</div>
|
|
<div class="col-span-2 space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Manufacturer') }}</label>
|
|
<input type="text" x-model="formData.manufacturer" class="luxury-input">
|
|
</div>
|
|
|
|
<!-- Pricing -->
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Price') }}</label>
|
|
<input type="number" x-model="formData.price" class="luxury-input">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Cost') }}</label>
|
|
<input type="number" x-model="formData.cost" class="luxury-input">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Member Price') }}</label>
|
|
<input type="number" x-model="formData.member_price" class="luxury-input">
|
|
</div>
|
|
|
|
<!-- Feature Toggled Fields: Material Code -->
|
|
<template x-if="settings.show_material_code">
|
|
<div class="space-y-2">
|
|
<label class="block text-xs font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Material Code') }}</label>
|
|
<input type="text" x-model="formData.metadata.material_code" class="luxury-input border-cyan-500/30">
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<!-- Points Settings Area (Feature Toggled) -->
|
|
<template x-if="settings.show_points_management">
|
|
<div class="p-6 bg-slate-50 dark:bg-slate-800/50 rounded-2xl border border-slate-100 dark:border-slate-700/50 space-y-6 mt-4">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500"></div>
|
|
<h4 class="text-[11px] font-black text-slate-400 uppercase tracking-widest">{{ __('Points Management') }}</h4>
|
|
</div>
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
<div class="space-y-2">
|
|
<label class="block text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Full Points') }}</label>
|
|
<input type="number" x-model="formData.metadata.full_points" class="luxury-input bg-white dark:bg-slate-900">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Half Points') }}</label>
|
|
<input type="number" x-model="formData.metadata.half_points" class="luxury-input bg-white dark:bg-slate-900">
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-widest pl-1">{{ __('Half Points Cash') }}</label>
|
|
<input type="number" x-model="formData.metadata.half_points_cash" class="luxury-input bg-white dark:bg-slate-900">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<div class="flex justify-between items-center pt-8 border-t border-slate-100 dark:border-slate-800">
|
|
<button type="button" @click="step = 1" class="text-xs font-black text-slate-400 uppercase tracking-widest hover:text-slate-600 transition-colors">
|
|
{{ __('Back') }}
|
|
</button>
|
|
<div class="flex gap-4">
|
|
<button type="button" @click="$dispatch('close-modal', 'create-product')" class="px-6 py-3 text-slate-400 font-black text-xs uppercase tracking-widest hover:text-slate-600">
|
|
{{ __('Cancel') }}
|
|
</button>
|
|
<button type="submit"
|
|
:disabled="loading"
|
|
class="px-10 py-3 bg-cyan-600 text-white rounded-xl font-black text-xs uppercase tracking-[0.2em] hover:bg-cyan-500 transition-all shadow-xl shadow-cyan-500/20 flex items-center gap-2">
|
|
<template x-if="loading">
|
|
<svg class="animate-spin h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
</template>
|
|
<span x-text="loading ? '{{ __('Saving...') }}' : '{{ __('Save Product') }}'"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|