فهرست منبع

refactor: dedicated order edit modal and diagnostic button

unknown 1 روز پیش
والد
کامیت
deb380a2f0
1فایلهای تغییر یافته به همراه84 افزوده شده و 65 حذف شده
  1. 84 65
      src/pages/Admin.vue

+ 84 - 65
src/pages/Admin.vue

@@ -8,9 +8,12 @@
     <Header />
     <main class="container mx-auto px-4 pt-32 pb-20">
 
-      <!-- DEPLOY INDICATOR -->
-      <div class="bg-rose-600 text-white text-[10px] py-1 text-center font-bold uppercase tracking-widest mb-4 rounded-lg">
-        DEPLOY VERIFIED: 12:50 CEST
+      <!-- DEPLOY INDICATOR & DIAGNOSTIC -->
+      <div class="bg-rose-600 text-white text-[10px] py-2 px-4 flex justify-between items-center font-bold uppercase tracking-widest mb-4 rounded-lg">
+        <span>DEPLOY VERIFIED: 12:51 CEST</span>
+        <button v-if="orders.length > 0" @click="handleEditOrder(orders[0])" class="bg-white text-rose-600 px-3 py-1 rounded hover:bg-rose-100 transition-colors">
+          DEBUG: OPEN FIRST ORDER
+        </button>
       </div>
 
       <!-- Admin Header -->
@@ -135,82 +138,92 @@
       </div>
     </main>
 
-    <!-- Global Modals -->
-    <div v-if="showAddModal" class="fixed inset-0 z-[99999] flex items-center justify-center p-4">
-      <div class="absolute inset-0 bg-background/80 backdrop-blur-sm" @click="closeModals" />
-      <div class="relative w-full max-w-lg bg-card border border-border/50 rounded-3xl p-8 shadow-2xl overflow-y-auto max-h-[90vh]">
-         <h3 class="text-xl font-bold font-display mb-6">{{ editingMaterial || editingService || editingPost || editingOrder ? t('admin.actions.edit') : t("admin.addNew") }}</h3>
+    <!-- DEDICATED ORDER EDIT MODAL -->
+    <div v-if="showOrderEditModal" class="fixed inset-0 z-[99999] flex items-center justify-center p-4">
+      <div class="absolute inset-0 bg-background/90 backdrop-blur-md" @click="showOrderEditModal = false" />
+      <div class="relative w-full max-w-2xl bg-card border border-primary/30 rounded-3xl p-8 shadow-2xl overflow-y-auto max-h-[90vh]">
+         <div class="flex justify-between items-center mb-6">
+           <h3 class="text-2xl font-black font-display text-gradient">Edit Order #{{ editingOrder?.id }}</h3>
+           <button @click="showOrderEditModal = false" class="p-2 hover:bg-white/5 rounded-full transition-colors"><X class="w-6 h-6" /></button>
+         </div>
          
-         <!-- Order Edit Form -->
-         <form v-if="editingOrder" @submit.prevent="handleSaveOrder" class="space-y-4">
-           <!-- Form items... no changes there -->
-                <div class="grid grid-cols-2 gap-4">
+         <form v-if="editingOrder" @submit.prevent="handleSaveOrder" class="space-y-6">
+            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
+                <div class="space-y-4">
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("auth.fields.firstName") }}</label>
-                    <input v-model="orderForm.first_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("auth.fields.firstName") }}</label>
+                    <input v-model="orderForm.first_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm focus:ring-2 ring-primary/20 outline-none" />
                   </div>
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("auth.fields.lastName") }}</label>
-                    <input v-model="orderForm.last_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("auth.fields.lastName") }}</label>
+                    <input v-model="orderForm.last_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm focus:ring-2 ring-primary/20 outline-none" />
                   </div>
-                </div>
-                <div class="grid grid-cols-2 gap-4">
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("auth.fields.email") }}</label>
-                    <input v-model="orderForm.email" type="email" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("auth.fields.email") }}</label>
+                    <input v-model="orderForm.email" type="email" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm focus:ring-2 ring-primary/20 outline-none" />
                   </div>
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.phone") }}</label>
-                    <input v-model="orderForm.phone" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("admin.fields.phone") }}</label>
+                    <input v-model="orderForm.phone" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm focus:ring-2 ring-primary/20 outline-none" />
                   </div>
                 </div>
-                <div class="space-y-1">
-                  <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.address") }}</label>
-                  <input v-model="orderForm.shipping_address" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
-                </div>
-                <div class="space-y-1">
-                  <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.projectNotes") }}</label>
-                  <textarea v-model="orderForm.notes" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm h-20" />
-                </div>
 
-                <div class="grid grid-cols-2 gap-4 pt-4 border-t border-border/10">
+                <div class="space-y-4">
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.totalPrice") }} (EUR)</label>
-                    <input v-model.number="orderForm.total_price" type="number" step="0.01" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("admin.fields.address") }}</label>
+                    <input v-model="orderForm.shipping_address" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm focus:ring-2 ring-primary/20 outline-none" />
                   </div>
                   <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.quantity") }}</label>
-                    <input v-model.number="orderForm.quantity" type="number" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
+                    <label class="text-[10px] font-bold uppercase text-muted-foreground ml-1">{{ t("admin.fields.projectNotes") }}</label>
+                    <textarea v-model="orderForm.notes" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm h-[132px] focus:ring-2 ring-primary/20 outline-none resize-none" />
                   </div>
                 </div>
-                <div class="grid grid-cols-2 gap-4">
-                  <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.material") }}</label>
-                    <input v-model="orderForm.material_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
-                  </div>
-                  <div class="space-y-1">
-                    <label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.colors") }}</label>
-                    <input v-model="orderForm.color_name" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
-                  </div>
+            </div>
+
+            <div class="p-6 bg-primary/5 rounded-2xl border border-primary/10 grid grid-cols-2 md:grid-cols-4 gap-6">
+                <div class="space-y-1">
+                  <label class="text-[10px] font-bold uppercase text-primary/60 ml-1">{{ t("admin.fields.totalPrice") }} (EUR)</label>
+                  <input v-model.number="orderForm.total_price" type="number" step="0.01" class="w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm font-bold" />
                 </div>
-                <!-- Review Edit fallback -->
-                <div v-if="orderForm.review_text" class="pt-4 border-t border-border/10 space-y-4">
-                   <div class="space-y-1">
-                     <label class="text-[10px] font-bold uppercase ml-1">Review Text</label>
-                     <textarea v-model="orderForm.review_text" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm h-20" />
-                   </div>
-                   <div class="space-y-1">
-                     <label class="text-[10px] font-bold uppercase ml-1">Rating (1-5)</label>
-                     <input v-model.number="orderForm.rating" type="number" min="1" max="5" class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" />
-                   </div>
+                <div class="space-y-1">
+                  <label class="text-[10px] font-bold uppercase text-primary/60 ml-1">{{ t("admin.fields.quantity") }}</label>
+                  <input v-model.number="orderForm.quantity" type="number" class="w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm font-bold" />
                 </div>
-
-                <div class="flex gap-3 pt-6 border-t border-border/10">
-                  <Button type="button" variant="ghost" class="flex-1" @click="closeModals">{{ t("admin.actions.cancel") }}</Button>
-                  <Button type="submit" variant="hero" class="flex-1">{{ t("admin.actions.save") }}</Button>
+                <div class="space-y-1">
+                  <label class="text-[10px] font-bold uppercase text-primary/60 ml-1">{{ t("admin.fields.material") }}</label>
+                  <input v-model="orderForm.material_name" class="w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm" />
                 </div>
-              </form>
-              
+                <div class="space-y-1">
+                  <label class="text-[10px] font-bold uppercase text-primary/60 ml-1">{{ t("admin.fields.colors") }}</label>
+                  <input v-model="orderForm.color_name" class="w-full bg-background border border-border/50 rounded-xl px-3 py-2 text-sm" />
+                </div>
+            </div>
+
+            <!-- Review Feedback -->
+            <div v-if="orderForm.review_text" class="p-4 bg-amber-500/5 border border-amber-500/20 rounded-2xl space-y-3">
+               <div class="flex justify-between items-center">
+                 <label class="text-[10px] font-bold uppercase text-amber-500 ml-1">Client Review Content</label>
+                 <div class="flex gap-1">
+                    <Star v-for="i in 5" :key="i" class="w-3 h-3" :class="orderForm.rating >= i ? 'text-amber-500 fill-amber-500' : 'text-muted-foreground/20'" />
+                 </div>
+               </div>
+               <textarea v-model="orderForm.review_text" class="w-full bg-background/50 border border-border/50 rounded-xl px-4 py-3 text-xs h-20 italic" />
+            </div>
+
+            <div class="flex gap-4 pt-4">
+              <Button type="button" variant="hero" class="flex-1 rounded-2xl h-12 bg-muted hover:bg-muted/80 text-foreground" @click="showOrderEditModal = false">{{ t("admin.actions.cancel") }}</Button>
+              <Button type="submit" variant="hero" class="flex-[2] rounded-2xl h-12 shadow-glow">{{ t("admin.actions.save") }}</Button>
+            </div>
+         </form>
+      </div>
+    </div>
+
+    <!-- Global Modals -->
+    <div v-if="showAddModal" class="fixed inset-0 z-[99999] flex items-center justify-center p-4">
+      <div class="absolute inset-0 bg-background/80 backdrop-blur-sm" @click="closeModals" />
+      <div class="relative w-full max-w-lg bg-card border border-border/50 rounded-3xl p-8 shadow-2xl overflow-y-auto max-h-[90vh]">
+         <h3 class="text-xl font-bold font-display mb-6">{{ editingMaterial || editingService || editingPost ? t('admin.actions.edit') : t("admin.addNew") }}</h3>
+         
               <!-- Material Modal Form -->
               <form v-if="activeTab === 'materials'" @submit.prevent="handleSaveMaterial" class="space-y-4">
                 <div class="space-y-1"><label class="text-[10px] font-bold uppercase ml-1">{{ t("admin.fields.nameEn") }}</label><input v-model="matForm.name_en" required class="w-full bg-background border border-border/50 rounded-xl px-4 py-3 text-sm" /></div>
@@ -279,7 +292,7 @@ import { toast } from "vue-sonner";
 // Icons
 import { 
   Package, Clock, RefreshCw, Search, Layers, Plus, Database, 
-  Newspaper, History, X, Users, ImageIcon, Truck, CheckCircle2, XCircle
+  Newspaper, History, X, Users, ImageIcon, Truck, CheckCircle2, XCircle, Star
 } from "lucide-vue-next";
 
 // UI Components
@@ -380,6 +393,7 @@ watch([searchQuery], () => {
 
 // Modals State & Forms
 const showAddModal = ref(false);
+const showOrderEditModal = ref(false);
 const editingMaterial = ref<any | null>(null);
 const editingService = ref<any | null>(null);
 const editingPost = ref<any | null>(null);
@@ -409,7 +423,7 @@ const handleEditOrder = (order: any) => {
     review_text: order.review_text || "",
     rating: order.rating || 0
   });
-  showAddModal.value = true;
+  showOrderEditModal.value = true;
 };
 
 const newColor = ref("");
@@ -537,14 +551,19 @@ const handleResetPassword = async (id: number) => {
 // Modal Actions
 const handleAddNew = () => { closeModals(); showAddModal.value = true; };
 
-const closeModals = () => {
-  showAddModal.value = false; editingMaterial.value = null; editingService.value = null; editingPost.value = null; editingOrder.value = null;
+function closeModals() {
+  showAddModal.value = false;
+  showOrderEditModal.value = false;
+  editingMaterial.value = null;
+  editingService.value = null; 
+  editingPost.value = null; 
+  editingOrder.value = null;
   Object.assign(matForm, { name_en: "", name_ru: "", name_me: "", name_ua: "", desc_en: "", desc_ru: "", desc_ua: "", desc_me: "", price_per_cm3: 0, available_colors: [], is_active: true });
   Object.assign(svcForm, { name_en: "", name_ru: "", name_me: "", name_ua: "", desc_en: "", desc_ru: "", desc_ua: "", desc_me: "", tech_type: "", is_active: true });
   Object.assign(userForm, { email: "", password: "", first_name: "", last_name: "", phone: "" });
   Object.assign(postForm, { slug: "", title_en: "", title_me: "", title_ru: "", title_ua: "", category: "Technology", image_url: "", is_published: true });
   Object.assign(orderForm, { total_price: 0, material_name: "", color_name: "", quantity: 1, first_name: "", last_name: "", email: "", phone: "", shipping_address: "", notes: "", review_text: "", rating: 0 });
-};
+}
 
 function addColor() { if (newColor.value) { matForm.available_colors.push(newColor.value); newColor.value = ""; } }
 function removeColor(idx: number) { matForm.available_colors.splice(idx, 1); }