diff --git a/src/components/GanttChart/AddQueueDialog.vue b/src/components/GanttChart/AddQueueDialog.vue
index 92a78eced3c5a90f2c4d9f229eb4a75912b01b18..f6f4b28f52424eab94c25fd14b0b9ce592ce2f07 100644
--- a/src/components/GanttChart/AddQueueDialog.vue
+++ b/src/components/GanttChart/AddQueueDialog.vue
@@ -40,7 +40,6 @@
           <label>Produced Quantity:</label>
           <input v-model.number="form.producedQuantity" type="number" required />
         </div>
-
         <!-- ปุ่ม Add หรือ Save Changes -->
         <div class="dialog-buttons">
           <button type="submit" class="primary-btn">
@@ -53,78 +52,106 @@
   </div>
 </template>
 
+<script setup lang="ts">
+import { reactive, ref, watch } from 'vue'
 
-<script>
-export default {
-  name: 'AddQueueDialog',
-  props: {
-    visible: Boolean,
-    queueItem: Object, // รับ queueItem ถ้ามี
-  },
-  data() {
-    return {
-      form: {
-        machineID: '',
-        orderID: null,
-        pageNumber: null,
-        startTime: '',
-        finishTime: '',
-        status: '',
-        bottleSize: '',
-        producedQuantity: null,
-      },
-      machines: [
-        { machineID: 'MC1', name: 'เครื่องเป่าขวด' },
-        { machineID: 'MC2', name: 'เครื่องเป่าขวด2' },
-        { machineID: 'MC3', name: 'เครื่องสวมฉลาก' },
-        { machineID: 'MC4', name: 'เครื่องสวมฉลาก2' },
-        { machineID: 'MC5', name: 'เครื่องบรรจุ+แพ็ค' },
-      ],
-      isEditing: false, // เช็คว่าเป็นโหมด Edit หรือไม่
-    };
-  },
-  watch: {
-    queueItem(newItem) {
-      if (newItem) {
-        this.form = { ...newItem }; // ถ้าเป็น Edit โยนค่ามาใส่ฟอร์ม
-        this.isEditing = true;
-      } else {
-        this.resetForm();
-        this.isEditing = false;
-      }
-    },
-  },
-  methods: {
-    closeDialog() {
-      console.log("Closing dialog"); // Debugging
-      this.$emit("close");
-      this.resetForm();
-    },
-    handleSubmit() {
-      if (this.isEditing) {
-        this.$emit("edit", { ...this.form }); // ส่งข้อมูลไปอัปเดต Queue
-      } else {
-        this.$emit("add", { ...this.form, queueID: Date.now() }); // กรณีเพิ่มใหม่ต้องให้ queueID ไม่ซ้ำ
-      }
-      this.closeDialog();
-    },
-    resetForm() {
-      this.form = {
-        machineID: '',
-        orderID: null,
-        pageNumber: null,
-        startTime: '',
-        finishTime: '',
-        status: '',
-        bottleSize: '',
-        producedQuantity: null,
-      };
-    },
+interface QueueItem {
+  machineID: string
+  orderID: number | null
+  pageNumber: number | null
+  startTime: string
+  finishTime: string
+  status: string
+  bottleSize: string
+  producedQuantity: number | null
+  queueID?: number
+}
+
+interface Machine {
+  machineID: string
+  name: string
+}
+
+// Props
+const props = defineProps<{
+  visible: boolean
+  queueItem?: QueueItem
+}>()
+
+// Emits
+const emit = defineEmits<{
+  (e: 'close'): void
+  (e: 'edit', payload: QueueItem): void
+  (e: 'add', payload: QueueItem): void
+}>()
+
+// Reactive form state
+const form = reactive<QueueItem>({
+  machineID: '',
+  orderID: null,
+  pageNumber: null,
+  startTime: '',
+  finishTime: '',
+  status: '',
+  bottleSize: '',
+  producedQuantity: null,
+})
+
+// Static machines list
+const machines: Machine[] = [
+  { machineID: 'MC1', name: 'เครื่องเป่าขวด' },
+  { machineID: 'MC2', name: 'เครื่องเป่าขวด2' },
+  { machineID: 'MC3', name: 'เครื่องสวมฉลาก' },
+  { machineID: 'MC4', name: 'เครื่องสวมฉลาก2' },
+  { machineID: 'MC5', name: 'เครื่องบรรจุ+แพ็ค' },
+]
+
+// Track editing mode
+const isEditing = ref(false)
+
+// Functions
+function resetForm() {
+  form.machineID = ''
+  form.orderID = null
+  form.pageNumber = null
+  form.startTime = ''
+  form.finishTime = ''
+  form.status = ''
+  form.bottleSize = ''
+  form.producedQuantity = null
+}
+
+function closeDialog() {
+  console.log("Closing dialog")
+  emit("close")
+  resetForm()
+}
+
+function handleSubmit() {
+  if (isEditing.value) {
+    emit("edit", { ...form })
+  } else {
+    emit("add", { ...form, queueID: Date.now() })
+  }
+  closeDialog()
+}
+
+// Watch for changes on queueItem prop to toggle edit mode
+watch(
+  () => props.queueItem,
+  (newItem) => {
+    if (newItem) {
+      Object.assign(form, newItem)
+      isEditing.value = true
+    } else {
+      resetForm()
+      isEditing.value = false
+    }
   },
-};
+  { immediate: true }
+)
 </script>
 
-
 <style scoped>
 .add-queue-dialog-overlay {
   position: fixed;
@@ -201,4 +228,4 @@ export default {
   font-size: 24px;
   color: #2B2E3F;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/src/components/GanttChart/GanttChart.vue b/src/components/GanttChart/GanttChart.vue
index a32b2ac9fc8ee92d28346fc6aa9803cce91b4715..6583f9536449852901649751328a88702123032f 100644
--- a/src/components/GanttChart/GanttChart.vue
+++ b/src/components/GanttChart/GanttChart.vue
@@ -3,10 +3,11 @@
     <div class="gantt-header">
       <!-- Calendar: เชื่อมกับ selectedDate -->
       <GanttCalendar v-model:modelValue="selectedDate" />
-      
+
       <!-- ปุ่ม Make a queue พร้อม event listener -->
-      <MakequeueBtn @updateQueue="handleUpdateQueue" />
+      <MakequeueBtn @click="queueStore.makeQueue()" />
     </div>
+
     <!-- Gantt Chart UI -->
     <div class="gantt-chart">
       <!-- Header: Time Scale -->
@@ -21,41 +22,26 @@
 
       <!-- Rows: เครื่องจักรแต่ละตัว -->
       <div class="rows">
-        <div
-          v-for="machine in machines"
-          :key="machine.id"
-          class="row"
-          @dragover.prevent="onDragOver($event)"
-          @drop="onDrop($event, machine.machineID)"
-        >
+        <div v-for="machine in machines" :key="machine.machineID" class="row" @dragover.prevent="onDragOver($event)"
+          @drop="onDrop($event, machine.machineID)">
           <div class="machine-label">
-            {{ machine.name }}
+            {{ machine.machineID }}
           </div>
           <div class="row-timeline">
             <!-- เส้นแนวตั้ง (Grid Lines) -->
-            <div
-              v-for="hour in hours"
-              :key="'line-' + hour"
-              class="vertical-line"
-              :style="getLineStyle(hour)"
-            ></div>
+            <div v-for="hour in hours" :key="'line-' + hour" class="vertical-line" :style="getLineStyle(hour)"></div>
 
             <!-- แสดง Queue ที่ตรงกับวันที่ (selectedDate), Page, และ Machine -->
-            <div
-              v-for="item in filteredQueue(machine.machineID)"
-              :key="item.queueID"
-              class="order"
+            <div v-for="item in filteredQueue(machine.machineID)" :key="item.queueID" class="order"
               :class="{ 'faded': draggingQueue && draggingQueue.queueID === item.queueID }"
-              :style="getQueueStyle(item)"
-            >
+              :style="getQueueStyle(item)">
+
               <!-- Handle สำหรับ Resize ด้านซ้าย -->
               <div class="resize-handle left" @mousedown="onResizeStart($event, item, 'left')"></div>
 
               <!-- ส่วนกลางของ Order ใช้สำหรับลาก และเปิด Dialog เมื่อคลิก -->
-              <div class="order-content" draggable="true"
-                @dragstart="onDragStart($event, item)"
-                @dragend="onDragEnd($event, item)"
-                @click.stop="openQueueDialog(item)">
+              <div class="order-content" draggable="true" @dragstart="onDragStart($event, item)"
+                @dragend="onDragEnd($event, item)" @click.stop="openQueueDialog(item)">
                 {{ item.orderID }} ({{ getTimeString(item.startTime) }} - {{ getTimeString(item.finishTime) }})
               </div>
 
@@ -68,7 +54,8 @@
 
       <!-- Ghost Queue (ขณะลาก) -->
       <div v-if="ghostQueue" class="drag-ghost" :style="ghostStyle">
-        {{ ghostQueue.orderID }} ({{ getTimeString(ghostQueue.startTime) }} - {{ getTimeString(ghostQueue.finishTime) }})
+        {{ ghostQueue.orderID }} ({{ getTimeString(ghostQueue.startTime) }} - {{ getTimeString(ghostQueue.finishTime)
+        }})
       </div>
 
       <v-divider :thickness="7"></v-divider>
@@ -99,419 +86,468 @@
         </div>
 
         <!-- AddQueueDialog (สำหรับเพิ่ม/แก้ไข) -->
-        <AddQueueDialog
-          :visible="showAddDialog"
-          :queueItem="selectedQueueItem"
-          @close="closeAddQueueDialog"
-          @add="handleAddQueue"
-          @edit="handleEditQueue"
-        />
+        <AddQueueDialog :visible="showAddDialog" :queueItem="selectedQueueItem" @close="closeAddQueueDialog"
+          @add="handleAddQueue" @edit="handleEditQueue" />
       </div>
 
       <!-- Order Dialog (สำหรับดูรายละเอียดเพิ่มเติม) -->
-      <OrderDialog
-        v-if="selectedQueueItem && !showAddDialog"
-        :queueItem="selectedQueueItem"
-        :color="getQueueColor(selectedQueueItem.orderID)"
-        @close="closeQueueDialog"
-        @edit="openAddQueueDialogForEdit"
-        @delete="deleteQueueItem"
-      />
+      <OrderDialog v-if="selectedQueueItem && !showAddDialog" :queueItem="selectedQueueItem"
+        :color="getQueueColor(selectedQueueItem.orderID)" @close="closeQueueDialog" @edit="openAddQueueDialogForEdit"
+        @delete="deleteQueueItem" />
     </div>
   </div>
 </template>
 
-<script>
+<script lang="ts" setup>
+import { ref, reactive, computed, onMounted, onBeforeUnmount, watch } from 'vue';
 import GanttCalendar from './GanttCalendar.vue';
 import OrderDialog from './OrderDialog.vue';
 import AddQueueDialog from './AddQueueDialog.vue';
 import MakequeueBtn from './MakequeueBtn.vue';
 import './ganttChart.css';
-
-export default {
-  name: 'GanttChart',
-  components: {
-    MakequeueBtn,
-    GanttCalendar,
-    OrderDialog,
-    AddQueueDialog,
-  },
-  data() {
-    return {
-      showAddDialog: false,
-      // ค่าจาก Calendar
-      selectedDate: '1/1/2025',
-
-      // กำหนดช่วงเวลาใน Gantt
-      startTime: '08:00',
-      endTime: '17:00',
-
-      // รายการเครื่องจักร
-      machines: [
-        { machineID: 'MC1' , name: 'เครื่องเป่าขวด' },
-        { machineID: 'MC2' , name: 'เครื่องเป่าขวด2' },
-        { machineID: 'MC3' , name: 'เครื่องสวมฉลาก' },
-        { machineID: 'MC4' , name: 'เครื่องบรรจุ+แพ็ค' },
-      ],
-
-      // รายการ Queue เริ่มต้น (สามารถเปลี่ยนแปลงได้)
-      Queue: [
-        {
-          queueID: 1,
-          machineID: 'MC1',
-          orderID: 5,
-          pageNumber: 1,
-          startTime: '1/1/2025 09:00',
-          finishTime: '1/1/2025 11:00',
-          status: 'Process',
-          bottleSize: '600ml',
-          producedQuantity: 400,
-        },
-        {
-          queueID: 2,
-          machineID: 'MC2',
-          orderID: 1,
-          pageNumber: 1,
-          startTime: '1/1/2025 13:00',
-          finishTime: '1/1/2025 15:00',
-          status: 'Waiting',
-          bottleSize: '500ml',
-          producedQuantity: 200,
-        },
-      ],
-
-      // Drag/Drop และ Resize
-      draggingQueue: null,
-      dragOffset: 0,
-      resizingQueue: null,
-      resizeDirection: null,
-
-      // Ghost Queue (ขณะลาก)
-      ghostQueue: null,
-      ghostStyle: {
-        position: 'fixed',
-        top: '0px',
-        left: '0px',
-        display: 'none',
-        width: 'auto',
-        height: '40px',
-        lineHeight: '40px',
-        padding: '0 10px',
-        borderRadius: '10px',
-        pointerEvents: 'none',
-        backgroundColor: '#4caf50',
-        color: '#fff',
-        zIndex: 9999,
-      },
-
-      // Pagination
-      pages: [1, 2],
-      currentPage: 1,
-      pageToShowDelete: null,
-
-      // Dialog
-      selectedQueueItem: null,
-    };
-  },
-  computed: {
-    // สร้าง list ของชั่วโมงทั้งหมดจาก startTime ถึง endTime
-    hours() {
-      const startHour = parseInt(this.startTime.split(':')[0]);
-      const endHour = parseInt(this.endTime.split(':')[0]);
-      return Array.from({ length: endHour - startHour + 1 }, (_, i) => startHour + i);
-    },
-  },
-  methods: {
-    // รับข้อมูล Queue ที่ส่งมาจาก MakequeueBtn
-    handleUpdateQueue(newQueue) {
-      console.log("Received new queue:", newQueue);
-      // ในที่นี้เราสามารถแทนที่ Queue เดิมหรือ merge กับข้อมูลที่มีอยู่
-      // ตัวอย่างนี้ใช้แทนที่ Queue ทั้งหมด
-      this.Queue = newQueue;
-    },
-
-    // -------------------- Dialog & Edit --------------------
-    openQueueDialog(item) {
-      this.selectedQueueItem = { ...item };
-    },
-    closeQueueDialog() {
-      this.selectedQueueItem = null;
-    },
-    openAddQueueDialog() {
-      this.selectedQueueItem = null;
-      this.showAddDialog = true;
-    },
-    deleteQueueItem(item) {
-      this.Queue = this.Queue.filter(q => q.queueID !== item.queueID);
-      this.closeQueueDialog();
-    },
-    openAddQueueDialogForEdit(queueItem) {
-      this.selectedQueueItem = { ...queueItem };
-      this.showAddDialog = true;
-    },
-    closeAddQueueDialog() {
-      this.showAddDialog = false;
-      this.selectedQueueItem = null;
-    },
-    handleAddQueue(newQueueItem) {
-      this.Queue.push({
-        queueID: this.Queue.length + 1,
-        ...newQueueItem,
-      });
-      this.showAddDialog = false;
-    },
-    handleEditQueue(updatedQueueItem) {
-      const index = this.Queue.findIndex(q => q.queueID === updatedQueueItem.queueID);
-      if (index !== -1) {
-        this.Queue.splice(index, 1, { ...updatedQueueItem });
-      }
-      this.selectedQueueItem = null;
-      this.showAddDialog = false;
-    },
-
-    // -------------------- Utility Functions --------------------
-    formatHour(hour) {
-      return (hour < 10 ? '0' + hour : hour) + ':00';
-    },
-    getDateString(dateTimeStr) {
-      return dateTimeStr.split(' ')[0];
-    },
-    getTimeString(dateTimeStr) {
-      return dateTimeStr.split(' ')[1];
-    },
-    filteredQueue(machineID) {
-      return this.Queue.filter((q) => {
-        const queueDate = this.getDateString(q.startTime);
-        return (
-          q.machineID === machineID &&
-          q.pageNumber === this.currentPage &&
-          queueDate === this.selectedDate
-        );
-      });
-    },
-    getQueueColor(orderID) {
-      const colors = ['#F58181', '#FDDC5C', '#C5A1BC', '#49E060'];
-      return colors[(orderID - 1) % colors.length];
-    },
-    getQueueStyle(item) {
-      const start = this.getTimeString(item.startTime);
-      const end = this.getTimeString(item.finishTime);
-      const startDecimal = this.timeToDecimal(start);
-      const endDecimal = this.timeToDecimal(end);
-      const timelineStart = this.timeToDecimal(this.startTime);
-      const timelineEnd = this.timeToDecimal(this.endTime);
-
-      const ratioStart = (startDecimal - timelineStart) / (timelineEnd - timelineStart);
-      const ratioEnd = (endDecimal - timelineStart) / (timelineEnd - timelineStart);
-
-      return {
-        left: ratioStart * 100 + '%',
-        width: (ratioEnd - ratioStart) * 100 + '%',
-        backgroundColor: this.getQueueColor(item.orderID),
-        color: '#fff',
-        borderRadius: '10px',
-        textAlign: 'center',
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-        padding: '5px',
-        fontSize: '14px',
-      };
-    },
-    getLineStyle(hour) {
-      const timelineStart = this.timeToDecimal(this.startTime);
-      const timelineEnd = this.timeToDecimal(this.endTime);
-      const ratio = (hour - timelineStart) / (timelineEnd - timelineStart);
-      return { left: ratio * 100 + '%' };
-    },
-    timeToDecimal(timeStr) {
-      const [hours, minutes] = timeStr.split(':').map(Number);
-      return hours + minutes / 60;
-    },
-    decimalToTime(decimal) {
-      const hours = Math.floor(decimal);
-      const minutes = Math.round((decimal - hours) * 60);
-      return (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes);
-    },
-
-    // -------------------- Drag/Drop & Resize --------------------
-    onDragStart(event, item) {
-      this.draggingQueue = item;
-      const rect = event.target.getBoundingClientRect();
-      this.dragOffset = rect.width / 2;
-      const emptyImg = document.createElement('img');
-      emptyImg.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
-      event.dataTransfer.setDragImage(emptyImg, 0, 0);
-
-      this.ghostQueue = { ...item };
-      this.ghostStyle.display = 'block';
-      this.ghostStyle.backgroundColor = this.getQueueColor(item.orderID);
-
-      document.addEventListener('dragover', this.onDragOverGlobal);
-      document.addEventListener('dragend', this.onDragEndGlobal);
-    },
-    onDragOver(event) {
-      event.preventDefault();
-    },
-    onDragOverGlobal(event) {
-      event.preventDefault();
-      const rowTimeline = document.querySelector('.row-timeline');
-      if (!rowTimeline) return;
-      const timelineRect = rowTimeline.getBoundingClientRect();
-      const timelineWidth = timelineRect.width;
-      const offsetX = event.clientX - timelineRect.left;
-
-      let ratio = offsetX / timelineWidth;
-      ratio = Math.min(Math.max(ratio, 0), 1);
-
-      const timelineStart = this.timeToDecimal(this.startTime);
-      const timelineEnd = this.timeToDecimal(this.endTime);
-      const startDecimal = this.timeToDecimal(this.getTimeString(this.draggingQueue.startTime));
-      const endDecimal = this.timeToDecimal(this.getTimeString(this.draggingQueue.finishTime));
-      const duration = endDecimal - startDecimal;
-
-      let newStartDecimal = timelineStart + ratio * (timelineEnd - timelineStart);
-      newStartDecimal = Math.round(newStartDecimal * 2) / 2;
-      let newEndDecimal = newStartDecimal + duration;
-      if (newEndDecimal > timelineEnd) {
-        newEndDecimal = timelineEnd;
-        newStartDecimal = newEndDecimal - duration;
-      }
-
-      const datePart = this.getDateString(this.draggingQueue.startTime);
-      const newStartStr = datePart + ' ' + this.decimalToTime(newStartDecimal);
-      const newEndStr = datePart + ' ' + this.decimalToTime(newEndDecimal);
-
-      this.ghostQueue.startTime = newStartStr;
-      this.ghostQueue.finishTime = newEndStr;
-
-      const snappedRatioStart = (newStartDecimal - timelineStart) / (timelineEnd - timelineStart);
-      const snappedLeft = timelineRect.left + snappedRatioStart * timelineWidth;
-      const snappedRatioEnd = (newEndDecimal - timelineStart) / (timelineEnd - timelineStart);
-      const snappedWidth = (snappedRatioEnd - snappedRatioStart) * timelineWidth;
-
-      const rows = document.querySelectorAll('.row');
-      let closestRow = null;
-      let minDistance = Infinity;
-      rows.forEach((row) => {
-        const rect = row.getBoundingClientRect();
-        const distance = Math.abs(event.clientY - rect.top);
-        if (distance < minDistance) {
-          minDistance = distance;
-          closestRow = row;
-        }
-      });
-
-      if (closestRow) {
-        this.ghostQueue.machineID = closestRow.querySelector('.machine-label').textContent.trim();
-        this.ghostStyle.top = closestRow.getBoundingClientRect().top + 'px';
-      }
-
-      this.ghostStyle.left = snappedLeft + 'px';
-      this.ghostStyle.width = snappedWidth + 'px';
-    },
-    onDragEndGlobal() {
-      this.ghostQueue = null;
-      this.ghostStyle.display = 'none';
-      this.draggingQueue = null;
-      document.removeEventListener('dragend', this.onDragEndGlobal);
-    },
-    onDragEnd(event, item) {
-      if (!this.ghostQueue) return;
-      item.startTime = this.ghostQueue.startTime;
-      item.finishTime = this.ghostQueue.finishTime;
-      item.machineID = this.ghostQueue.machineID;
-      document.removeEventListener('dragover', this.onDragOverGlobal);
-      this.ghostQueue = null;
-      this.ghostStyle.display = 'none';
-      this.draggingQueue = null;
-    },
-    onDrop(event, newMachine) {
-      event.preventDefault();
-      if (this.draggingQueue && this.ghostQueue) {
-        this.draggingQueue.startTime = this.ghostQueue.startTime;
-        this.draggingQueue.finishTime = this.ghostQueue.finishTime;
-        this.draggingQueue.machineID = newMachine;
-      }
-      this.ghostQueue = null;
-      this.ghostStyle.display = 'none';
-      this.draggingQueue = null;
-    },
-    onResizeStart(event, item, direction) {
-      event.preventDefault();
-      this.resizingQueue = item;
-      this.resizeDirection = direction;
-      document.addEventListener('mousemove', this.onResizing);
-      document.addEventListener('mouseup', this.onResizeEnd);
-    },
-    onResizing(event) {
-      if (!this.resizingQueue) return;
-      const rowTimeline = document.querySelector('.row-timeline');
-      if (!rowTimeline) return;
-      const timelineRect = rowTimeline.getBoundingClientRect();
-      const timelineWidth = timelineRect.width;
-      const offsetX = event.clientX - timelineRect.left;
-
-      let ratio = offsetX / timelineWidth;
-      ratio = Math.min(Math.max(ratio, 0), 1);
-
-      const timelineStart = this.timeToDecimal(this.startTime);
-      const timelineEnd = this.timeToDecimal(this.endTime);
-      const startDec = this.timeToDecimal(this.getTimeString(this.resizingQueue.startTime));
-      const endDec = this.timeToDecimal(this.getTimeString(this.resizingQueue.finishTime));
-      let newTimeDecimal = timelineStart + ratio * (timelineEnd - timelineStart);
-      newTimeDecimal = Math.round(newTimeDecimal * 2) / 2;
-      const datePart = this.getDateString(this.resizingQueue.startTime);
-
-      if (this.resizeDirection === 'left') {
-        if (newTimeDecimal >= endDec) return;
-        const newStartStr = datePart + ' ' + this.decimalToTime(newTimeDecimal);
-        this.resizingQueue.startTime = newStartStr;
-      } else if (this.resizeDirection === 'right') {
-        if (newTimeDecimal <= startDec) return;
-        const newEndStr = datePart + ' ' + this.decimalToTime(newTimeDecimal);
-        this.resizingQueue.finishTime = newEndStr;
-      }
-    },
-    onResizeEnd() {
-      this.resizingQueue = null;
-      this.resizeDirection = null;
-      document.removeEventListener('mousemove', this.onResizing);
-      document.removeEventListener('mouseup', this.onResizeEnd);
-    },
-    addPage() {
-      if (this.pages.length < 10) {
-        const newPage = this.pages.length + 1;
-        this.pages.push(newPage);
-      } else {
-        alert("Maximum of 10 pages allowed.");
-      }
-    },
-    onPageRightClick(page, event) {
-      event.preventDefault();
-      this.pageToShowDelete = page;
-    },
-    deletePage(page) {
-      const index = this.pages.indexOf(page);
-      if (index !== -1) {
-        this.pages.splice(index, 1);
-        if (this.currentPage === page) {
-          this.currentPage = this.pages.length > 0 ? this.pages[0] : 1;
-        }
-      }
-      this.pageToShowDelete = null;
-    },
-    onDocumentClick(event) {
-      if (!event.target.closest('.page-btn')) {
-        this.pageToShowDelete = null;
-      }
-    },
-  },
-  mounted() {
-    document.addEventListener('click', this.onDocumentClick);
-  },
-  beforeUnmount() {
-    document.removeEventListener('click', this.onDocumentClick);
-  },
-};
+import { useQueueStore } from '@/stores/queue';
+import type { QueueItem } from '@/types/QueueItem';
+
+interface Machine {
+  machineID: string;
+  name: string;
+}
+
+
+
+const queueStore = useQueueStore();
+
+// NOTE: ถ้าต้องการโหลดข้อมูลทันทีที่เข้าหน้านี้ ให้ un-comment ด้านล่าง
+onMounted(() => {
+
+});
+
+// State
+const showAddDialog = ref(false);
+const selectedDate = ref('1/1/2025');
+const startTime = ref('08:00');
+const endTime = ref('17:00');
+
+const machines = ref<Machine[]>([
+  { machineID: 'MC1', name: 'เครื่องเป่าขวด' },
+  { machineID: 'MC2', name: 'เครื่องเป่าขวด2' },
+  { machineID: 'MC3', name: 'เครื่องสวมฉลาก' },
+  { machineID: 'MC4', name: 'เครื่องบรรจุ+แพ็ค' },
+]);
+
+// ดึง ref ของ QueueItem[] จาก Store
+const Queues = computed(() => queueStore.Queues.value);
+
+// Drag/Drop & Resize
+const draggingQueue = ref<QueueItem | null>(null);
+const dragOffset = ref(0);
+const resizingQueue = ref<QueueItem | null>(null);
+const resizeDirection = ref<string | null>(null);
+
+const ghostQueue = ref<QueueItem | null>(null);
+const ghostStyle = reactive({
+  position: 'fixed',
+  top: '0px',
+  left: '0px',
+  display: 'none',
+  width: 'auto',
+  height: '40px',
+  lineHeight: '40px',
+  padding: '0 10px',
+  borderRadius: '10px',
+  pointerEvents: 'none',
+  backgroundColor: '#4caf50',
+  color: '#fff',
+  zIndex: 9999,
+});
+
+// Pagination & Dialog
+const pages = ref<number[]>([1, 2]);
+const currentPage = ref(1);
+const pageToShowDelete = ref<number | null>(null);
+const selectedQueueItem = ref<QueueItem | null>(null);
+
+
+watch(() => queueStore.Queues.value, (newVal) => {
+  console.log("🔄 Queues updated in GanttChart.vue:", newVal);
+}, { deep: true });
+
+
+// Computed
+const hours = computed(() => {
+  const startHour = parseInt(startTime.value.split(':')[0]);
+  const endHour = parseInt(endTime.value.split(':')[0]);
+  return Array.from({ length: endHour - startHour + 1 }, (_, i) => startHour + i);
+});
+
+// Methods
+function handleUpdateQueue(newQueue: QueueItem[]) {
+  console.log("Received new queue:", newQueue);
+  // อัปเดตลงใน store
+  Queues.value = newQueue;
+}
+
+function openQueueDialog(item: QueueItem) {
+  selectedQueueItem.value = { ...item };
+}
+
+function closeQueueDialog() {
+  selectedQueueItem.value = null;
+}
+
+function openAddQueueDialog() {
+  selectedQueueItem.value = null;
+  showAddDialog.value = true;
+}
+
+function deleteQueueItem(item: QueueItem) {
+  // ลบคิวใน store
+  Queues.value = Queues.value.filter(q => q.queueID !== item.queueID);
+  closeQueueDialog();
+}
+
+function openAddQueueDialogForEdit(queueItem: QueueItem) {
+  selectedQueueItem.value = { ...queueItem };
+  showAddDialog.value = true;
+}
+
+function closeAddQueueDialog() {
+  showAddDialog.value = false;
+  selectedQueueItem.value = null;
+}
+
+function handleAddQueue(newQueueItem: Omit<QueueItem, 'queueID'>) {
+  const newQueueID = Queues.value.length + 1;
+  Queues.value.push({ queueID: newQueueID, ...newQueueItem });
+  showAddDialog.value = false;
+}
+
+function handleEditQueue(updatedQueueItem: QueueItem) {
+  const index = Queues.value.findIndex(q => q.queueID === updatedQueueItem.queueID);
+  if (index !== -1) {
+    Queues.value.splice(index, 1, { ...updatedQueueItem });
+  }
+  selectedQueueItem.value = null;
+  showAddDialog.value = false;
+}
+
+// Utility Functions
+function formatHour(hour: number): string {
+  return (hour < 10 ? '0' + hour : hour) + ':00';
+}
+
+function getDateString(dateTimeStr: string): string {
+  return dateTimeStr.split(' ')[0];
+}
+
+function getTimeString(dateTimeStr: string): string {
+  return dateTimeStr.split(' ')[1];
+}
+
+function filteredQueue(machineID: string) {
+  if (!queueStore.Queues?.values || typeof queueStore.Queues.values !== "function") {
+    console.warn("queueStore.Queues.values is not a function or is undefined");
+    return [];
+  }
+
+  return queueStore.Queues.filter(q => {
+    const queueDate = getDateString(q.startTime);
+    console.log(queueDate)
+    return (
+      q.machineID === machineID &&
+      q.pageNumber === currentPage.value &&
+      queueDate === selectedDate.value
+    );
+  });
+}
+
+
+
+
+const colorMap: Record<string, string> = {}; // Map เก็บสีของแต่ละ orderID
+
+function getQueueColor(orderID: string | number): string {
+  const key = String(orderID);
+
+  // 🔴 ถ้าเป็น "ผลิตเผื่อ" → ใช้สีแดงพาสเทล
+  if (key === "ผลิตเผื่อ") {
+    return "#FFC1C1"; // Light Pastel Red
+  }
+
+  // 💜 ถ้าเป็น "เปลี่ยนขนาด" → ใช้สีม่วงชมพูพาสเทล
+  if (key === "เปลี่ยนขนาด") {
+    return "#E1BEE7"; // Light Pastel Pink-Purple (Lavender)
+  }
+
+  // ✅ ถ้ามีสีอยู่แล้ว ให้ใช้สีเดิม
+  if (colorMap[key]) return colorMap[key];
+
+  // 🌊 ถ้าเป็นคิวปกติ → ใช้สีธีมน้ำ
+  const newColor = generateWaterPastel();
+  colorMap[key] = newColor;
+  return newColor;
+}
+
+function generateWaterPastel(): string {
+  // สุ่มเฉพาะสีโทนน้ำทะเล (ฟ้า, น้ำเงิน, เขียวมิ้นต์)
+  const waterHues = [180, 190, 200, 210, 220, 230, 240];
+  const hue = waterHues[Math.floor(Math.random() * waterHues.length)];
+  return `hsl(${hue}, 60%, 80%)`;
+}
+
+function getQueueStyle(item: QueueItem) {
+  const start = getTimeString(item.startTime);
+  const end = getTimeString(item.finishTime);
+  const startDecimal = timeToDecimal(start);
+  const endDecimal = timeToDecimal(end);
+  const timelineStart = timeToDecimal(startTime.value);
+  const timelineEnd = timeToDecimal(endTime.value);
+
+  const ratioStart = Math.max(0, Math.min(1, (startDecimal - timelineStart) / (timelineEnd - timelineStart)));
+  const ratioEnd = Math.max(0, Math.min(1, (endDecimal - timelineStart) / (timelineEnd - timelineStart)));
+
+  const backgroundColor = getQueueColor(item.orderID); // ใช้ฟังก์ชันที่แก้ไขแล้ว
+
+  console.log(`Queue ${item.queueID}: orderID=${item.orderID}, color=${backgroundColor}`);
+
+  return {
+    left: ratioStart * 100 + '%',
+    width: (ratioEnd - ratioStart) * 100 + '%',
+    backgroundColor: backgroundColor, // ใช้สีแดงพาสเทลหรือสีธีมน้ำ
+    color: '#333',
+    borderRadius: '10px',
+    textAlign: 'center',
+    display: 'flex',
+    alignItems: 'center',
+    justifyContent: 'center',
+    padding: '5px',
+    fontSize: '14px',
+    fontWeight: 'bold',
+    boxShadow: '0px 4px 6px rgba(0, 0, 0, 0.1)',
+  };
+}
+
+
+
+function getLineStyle(hour: number) {
+  const timelineStart = timeToDecimal(startTime.value);
+  const timelineEnd = timeToDecimal(endTime.value);
+  const ratio = (hour - timelineStart) / (timelineEnd - timelineStart);
+  return { left: ratio * 100 + '%' };
+}
+
+function timeToDecimal(timeStr: string): number {
+  const [hours, minutes] = timeStr.split(':').map(Number);
+  return hours + minutes / 60;
+}
+
+function decimalToTime(decimal: number): string {
+  const hours = Math.floor(decimal);
+  const minutes = Math.round((decimal - hours) * 60);
+  return (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes);
+}
+
+// Drag/Drop & Resize Functions
+function onDragStart(event: DragEvent, item: QueueItem) {
+  draggingQueue.value = item;
+  const target = event.target as HTMLElement;
+  const rect = target.getBoundingClientRect();
+  dragOffset.value = rect.width / 2;
+
+  const emptyImg = new Image();
+  emptyImg.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
+  event.dataTransfer?.setDragImage(emptyImg, 0, 0);
+
+  ghostQueue.value = { ...item };
+  ghostStyle.display = 'block';
+  ghostStyle.backgroundColor = getQueueColor(item.orderID);
+
+  document.addEventListener('dragover', onDragOverGlobal);
+  document.addEventListener('dragend', onDragEndGlobal);
+}
+
+function onDragOver(event: DragEvent) {
+  event.preventDefault();
+}
+
+function onDragOverGlobal(event: DragEvent) {
+  event.preventDefault();
+  const rowTimeline = document.querySelector('.row-timeline') as HTMLElement;
+  if (!rowTimeline) return;
+  const timelineRect = rowTimeline.getBoundingClientRect();
+  const timelineWidth = timelineRect.width;
+  const offsetX = event.clientX - timelineRect.left;
+
+  let ratio = offsetX / timelineWidth;
+  ratio = Math.min(Math.max(ratio, 0), 1);
+
+  const timelineStartDec = timeToDecimal(startTime.value);
+  const timelineEndDec = timeToDecimal(endTime.value);
+  if (!draggingQueue.value) return;
+  const startDecimal = timeToDecimal(getTimeString(draggingQueue.value.startTime));
+  const endDecimal = timeToDecimal(getTimeString(draggingQueue.value.finishTime));
+  const duration = endDecimal - startDecimal;
+
+  let newStartDecimal = timelineStartDec + ratio * (timelineEndDec - timelineStartDec);
+  newStartDecimal = Math.round(newStartDecimal * 2) / 2;
+  let newEndDecimal = newStartDecimal + duration;
+  if (newEndDecimal > timelineEndDec) {
+    newEndDecimal = timelineEndDec;
+    newStartDecimal = newEndDecimal - duration;
+  }
+
+  const datePart = getDateString(draggingQueue.value.startTime);
+  const newStartStr = datePart + ' ' + decimalToTime(newStartDecimal);
+  const newEndStr = datePart + ' ' + decimalToTime(newEndDecimal);
+
+  if (ghostQueue.value) {
+    ghostQueue.value.startTime = newStartStr;
+    ghostQueue.value.finishTime = newEndStr;
+  }
+
+  const snappedRatioStart = (newStartDecimal - timelineStartDec) / (timelineEndDec - timelineStartDec);
+  const snappedLeft = timelineRect.left + snappedRatioStart * timelineWidth;
+  const snappedRatioEnd = (newEndDecimal - timelineStartDec) / (timelineEndDec - timelineStartDec);
+  const snappedWidth = (snappedRatioEnd - snappedRatioStart) * timelineWidth;
+
+  const rows = document.querySelectorAll('.row');
+  let closestRow: HTMLElement | null = null;
+  let minDistance = Infinity;
+  rows.forEach((row) => {
+    const rect = (row as HTMLElement).getBoundingClientRect();
+    const distance = Math.abs(event.clientY - rect.top);
+    if (distance < minDistance) {
+      minDistance = distance;
+      closestRow = row as HTMLElement;
+    }
+  });
+
+  if (closestRow) {
+    const labelEl = closestRow.querySelector('.machine-label') as HTMLElement;
+    if (labelEl) {
+      ghostQueue.value!.machineID = labelEl.textContent?.trim() || ghostQueue.value!.machineID;
+    }
+    ghostStyle.top = closestRow.getBoundingClientRect().top + 'px';
+  }
+
+  ghostStyle.left = snappedLeft + 'px';
+  ghostStyle.width = snappedWidth + 'px';
+}
+
+function onDragEndGlobal() {
+  ghostQueue.value = null;
+  ghostStyle.display = 'none';
+  draggingQueue.value = null;
+  document.removeEventListener('dragend', onDragEndGlobal);
+}
+
+function onDragEnd(event: DragEvent, item: QueueItem) {
+  if (!ghostQueue.value) return;
+  item.startTime = ghostQueue.value.startTime;
+  item.finishTime = ghostQueue.value.finishTime;
+  item.machineID = ghostQueue.value.machineID;
+  document.removeEventListener('dragover', onDragOverGlobal);
+  ghostQueue.value = null;
+  ghostStyle.display = 'none';
+  draggingQueue.value = null;
+}
+
+function onDrop(event: DragEvent, newMachine: string) {
+  event.preventDefault();
+  if (draggingQueue.value && ghostQueue.value) {
+    draggingQueue.value.startTime = ghostQueue.value.startTime;
+    draggingQueue.value.finishTime = ghostQueue.value.finishTime;
+    draggingQueue.value.machineID = newMachine;
+  }
+  ghostQueue.value = null;
+  ghostStyle.display = 'none';
+  draggingQueue.value = null;
+}
+
+function onResizeStart(event: MouseEvent, item: QueueItem, direction: string) {
+  event.preventDefault();
+  resizingQueue.value = item;
+  resizeDirection.value = direction;
+  document.addEventListener('mousemove', onResizing);
+  document.addEventListener('mouseup', onResizeEnd);
+}
+
+function onResizing(event: MouseEvent) {
+  if (!resizingQueue.value) return;
+  const rowTimeline = document.querySelector('.row-timeline') as HTMLElement;
+  if (!rowTimeline) return;
+  const timelineRect = rowTimeline.getBoundingClientRect();
+  const timelineWidth = timelineRect.width;
+  const offsetX = event.clientX - timelineRect.left;
+
+  let ratio = offsetX / timelineWidth;
+  ratio = Math.min(Math.max(ratio, 0), 1);
+
+  const timelineStartDec = timeToDecimal(startTime.value);
+  const timelineEndDec = timeToDecimal(endTime.value);
+  const startDec = timeToDecimal(getTimeString(resizingQueue.value.startTime));
+  const endDec = timeToDecimal(getTimeString(resizingQueue.value.finishTime));
+  let newTimeDecimal = timelineStartDec + ratio * (timelineEndDec - timelineStartDec);
+  newTimeDecimal = Math.round(newTimeDecimal * 2) / 2;
+  const datePart = getDateString(resizingQueue.value.startTime);
+
+  if (resizeDirection.value === 'left') {
+    if (newTimeDecimal >= endDec) return;
+    const newStartStr = datePart + ' ' + decimalToTime(newTimeDecimal);
+    resizingQueue.value.startTime = newStartStr;
+  } else if (resizeDirection.value === 'right') {
+    if (newTimeDecimal <= startDec) return;
+    const newEndStr = datePart + ' ' + decimalToTime(newTimeDecimal);
+    resizingQueue.value.finishTime = newEndStr;
+  }
+}
+
+function onResizeEnd() {
+  resizingQueue.value = null;
+  resizeDirection.value = null;
+  document.removeEventListener('mousemove', onResizing);
+  document.removeEventListener('mouseup', onResizeEnd);
+}
+
+// Pagination Functions
+function addPage() {
+  if (pages.value.length < 10) {
+    const newPage = pages.value.length + 1;
+    pages.value.push(newPage);
+  } else {
+    alert("Maximum of 10 pages allowed.");
+  }
+}
+
+function onPageRightClick(page: number, event: MouseEvent) {
+  event.preventDefault();
+  pageToShowDelete.value = page;
+}
+
+function deletePage(page: number) {
+  const index = pages.value.indexOf(page);
+  if (index !== -1) {
+    pages.value.splice(index, 1);
+    if (currentPage.value === page) {
+      currentPage.value = pages.value.length > 0 ? pages.value[0] : 1;
+    }
+  }
+  pageToShowDelete.value = null;
+}
+
+function onDocumentClick(event: MouseEvent) {
+  const target = event.target as HTMLElement;
+  if (!target.closest('.page-btn')) {
+    pageToShowDelete.value = null;
+  }
+}
+
+// Lifecycle Hooks
+onMounted(() => {
+  document.addEventListener('click', onDocumentClick);
+});
+
+onBeforeUnmount(() => {
+  document.removeEventListener('click', onDocumentClick);
+});
 </script>
diff --git a/src/components/GanttChart/MakequeueBtn.vue b/src/components/GanttChart/MakequeueBtn.vue
index 33f5ad09d2955498684a3117c636e65afe081e52..36474d62b6b8f794809f05dc059e1640bf85c96e 100644
--- a/src/components/GanttChart/MakequeueBtn.vue
+++ b/src/components/GanttChart/MakequeueBtn.vue
@@ -1,50 +1,34 @@
 <template>
   <div>
-    <button @click="makeQueue">Make a queue</button>
+    <v-btn>Make a queue</v-btn>
   </div>
 </template>
 
-<script>
-import { scheduleAllOrders } from './scheduleCalculator.js';
+<script lang="ts" setup>
+import { defineEmits } from 'vue';
+import { useQueueStore } from '@/stores/queue.js';
+import LoadingDialog from '../LoadingDialog.vue';
+
 
-export default {
-  name: 'MakequeueBtn',
-  methods: {
-    makeQueue() {
-      const queueItems = scheduleAllOrders();
-      this.$emit('updateQueue', queueItems);
-    }
-  }
-}
 </script>
 
 <style scoped>
-button {
-  /* พื้นหลังสีน้ำเงิน */
-  background-color: #2196f3;
-  /* สีตัวอักษรเป็นสีขาว */
-  color: #fff;
-  /* ไม่มีขอบ */
-  border: none;
-  /* มุมโค้ง */
+.v-btn {
+  background-color: #333647;
+  color: #ffffff;
   border-radius: 8px;
-  /* ขนาดตัวอักษรใหญ่ขึ้น */
   font-size: 18px;
   font-weight: bold;
-  /* ปรับขนาดปุ่มให้กว้างขึ้น */
   width: 200px;
   height: 60px;
-  /* กึ่งกลางตัวอักษร */
   display: flex;
   align-items: center;
   justify-content: center;
-  /* เปลี่ยนเคอร์เซอร์เป็นแบบคลิกได้ */
   cursor: pointer;
   transition: background-color 0.2s ease;
 }
 
-/* เมื่อเอาเมาส์ไปชี้ */
-button:hover {
-  background-color: #1976d2;
+.v-btn:hover {
+  background-color: #7e9cd3;
 }
-</style>
+</style>
\ No newline at end of file
diff --git a/src/components/LoadingDialog.vue b/src/components/LoadingDialog.vue
index 81427c150c04e8e128a69c4118e835c0cdfc60c8..9ca9a362e3a9c846c2068e9d9b51857d90764938 100644
--- a/src/components/LoadingDialog.vue
+++ b/src/components/LoadingDialog.vue
@@ -16,31 +16,38 @@ const loadingStore = useLoadingStore()
   width: 40px;
   aspect-ratio: 1;
   --c: linear-gradient(#ffffff 0 0);
-  --r1: radial-gradient(farthest-side at bottom,#ffffff 93%,#ffffff);
-  --r2: radial-gradient(farthest-side at top   ,#ffffff 93%,#ffffff);
-  background: 
-    var(--c) ,var(--r1),var(--r2),
-    var(--c) ,var(--r1),var(--r2),
-    var(--c) ,var(--r1),var(--r2);
+  --r1: radial-gradient(farthest-side at bottom, #ffffff 93%, #ffffff);
+  --r2: radial-gradient(farthest-side at top, #ffffff 93%, #ffffff);
+  background:
+    var(--c), var(--r1), var(--r2),
+    var(--c), var(--r1), var(--r2),
+    var(--c), var(--r1), var(--r2);
   background-repeat: no-repeat;
   animation: l2 1s infinite alternate;
 }
+
 @keyframes l2 {
-  0%,25% {
-    background-size: 8px 0,8px 4px,8px 4px,8px 0,8px 4px,8px 4px,8px 0,8px 4px,8px 4px;
-    background-position: 0 50%,0 calc(50% - 2px),0 calc(50% + 2px),50% 50%,50% calc(50% - 2px),50% calc(50% + 2px),100% 50%,100% calc(50% - 2px),100% calc(50% + 2px);
- }
- 50% {
-    background-size: 8px 100%,8px 4px,8px 4px,8px 0,8px 4px,8px 4px,8px 0,8px 4px,8px 4px;
-    background-position: 0 50%,0 calc(0% - 2px),0 calc(100% + 2px),50% 50%,50% calc(50% - 2px),50% calc(50% + 2px),100% 50%,100% calc(50% - 2px),100% calc(50% + 2px);
- }
- 75% {
-    background-size: 8px 100%,8px 4px,8px 4px,8px 100%,8px 4px,8px 4px,8px 0,8px 4px,8px 4px;
-    background-position: 0 50%,0 calc(0% - 2px),0 calc(100% + 2px),50% 50%,50% calc(0% - 2px),50% calc(100% + 2px),100% 50%,100% calc(50% - 2px),100% calc(50% + 2px);
- }
- 95%,100% {
-    background-size: 8px 100%,8px 4px, 8px 4px,8px 100%,8px 4px,8px 4px,8px 100%,8px 4px,8px 4px;
-    background-position: 0 50%,0 calc(0% - 2px),0 calc(100% + 2px),50% 50%,50% calc(0% - 2px),50% calc(100% + 2px),100% 50%,100% calc(0% - 2px),100% calc(100% + 2px);
- }
+
+  0%,
+  25% {
+    background-size: 8px 0, 8px 4px, 8px 4px, 8px 0, 8px 4px, 8px 4px, 8px 0, 8px 4px, 8px 4px;
+    background-position: 0 50%, 0 calc(50% - 2px), 0 calc(50% + 2px), 50% 50%, 50% calc(50% - 2px), 50% calc(50% + 2px), 100% 50%, 100% calc(50% - 2px), 100% calc(50% + 2px);
+  }
+
+  50% {
+    background-size: 8px 100%, 8px 4px, 8px 4px, 8px 0, 8px 4px, 8px 4px, 8px 0, 8px 4px, 8px 4px;
+    background-position: 0 50%, 0 calc(0% - 2px), 0 calc(100% + 2px), 50% 50%, 50% calc(50% - 2px), 50% calc(50% + 2px), 100% 50%, 100% calc(50% - 2px), 100% calc(50% + 2px);
+  }
+
+  75% {
+    background-size: 8px 100%, 8px 4px, 8px 4px, 8px 100%, 8px 4px, 8px 4px, 8px 0, 8px 4px, 8px 4px;
+    background-position: 0 50%, 0 calc(0% - 2px), 0 calc(100% + 2px), 50% 50%, 50% calc(0% - 2px), 50% calc(100% + 2px), 100% 50%, 100% calc(50% - 2px), 100% calc(50% + 2px);
+  }
+
+  95%,
+  100% {
+    background-size: 8px 100%, 8px 4px, 8px 4px, 8px 100%, 8px 4px, 8px 4px, 8px 100%, 8px 4px, 8px 4px;
+    background-position: 0 50%, 0 calc(0% - 2px), 0 calc(100% + 2px), 50% 50%, 50% calc(0% - 2px), 50% calc(100% + 2px), 100% 50%, 100% calc(0% - 2px), 100% calc(100% + 2px);
+  }
 }
 </style>
diff --git a/src/components/Navbar/MainAppBar.vue b/src/components/Navbar/MainAppBar.vue
index a1138f1d65b8c962640387687634cc17cca8d53c..de3f0f3b557c1695c67fc4e9ea2535c63ed30cc5 100644
--- a/src/components/Navbar/MainAppBar.vue
+++ b/src/components/Navbar/MainAppBar.vue
@@ -18,6 +18,9 @@ watchEffect(() => {
   if (route.name === 'pq') {
     icon.value = 'mdi-text-box'
     title.value = ' คิวการผลิต'
+  } else if (route.name === 'pq-aof') {
+    icon.value = 'mdi-package-variant'
+    title.value = 'คิวการผลิตออฟ'
   } else if (route.name === 'stocks') {
     icon.value = 'mdi-package-variant'
     title.value = 'Stock Management'
@@ -96,22 +99,22 @@ watchEffect(() => {
   } else if (route.name === 'receipt') {
     icon.value = 'mdi-receipt'
     title.value = 'Receipt Management'
-  }  else if (route.name === 'se') {
+  } else if (route.name === 'se') {
     icon.value = 'mdi-cash-plus'
     title.value = 'Store Expenses Bill'
-  }  else if (route.name === 'sereport') {
+  } else if (route.name === 'sereport') {
     icon.value = 'mdi-file-chart'
     title.value = 'Store Expenses Report'
   } else if (route.name === 'sechart') {
     icon.value = 'mdi-file-chart'
     title.value = 'Store Expenses Chart'
-  }  else if (route.name === 'branch') {
+  } else if (route.name === 'branch') {
     icon.value = 'mdi-store'
     title.value = 'Branch Management'
   } else if (route.name === 'product') {
     icon.value = 'mdi-food-fork-drink'
     title.value = 'Product Management'
-  }else {
+  } else {
     icon.value = ''
     title.value = ''
   }
diff --git a/src/components/Navbar/MainMenu.vue b/src/components/Navbar/MainMenu.vue
index 3fec98d961ad205eccc9842b4f85fb3161403ec7..a2f1af9b5762bdd9a17ae35c15eea99ad5726299 100644
--- a/src/components/Navbar/MainMenu.vue
+++ b/src/components/Navbar/MainMenu.vue
@@ -9,73 +9,73 @@ const authStore = useAuthStore()
 </script>
 
 <template>
-  <v-navigation-drawer expand-on-hover
-  rail style="background-color: #2B2E3F; color:white;">
+  <v-navigation-drawer expand-on-hover rail style="background-color: #2B2E3F; color:white;">
     <!-- profile -->
     <v-list>
       <v-list-item
-    :prepend-avatar="`http://localhost:4000/images/users/${authStore.getCurrentUser()?.image || 'default.jpg'}`">
-    <template #title>
-      <span style="font-size: 20px; font-weight: bold">
-        {{ authStore.getCurrentUser()?.name || 'Unknown User' }}
-      </span>
-    </template>
-    <template #subtitle>
-      <span style="font-size: 17px">
-        {{ authStore.getCurrentUser()?.role?.name || 'No Role' }}
-      </span>
-    </template>
-  </v-list-item>
+        :prepend-avatar="`http://localhost:4000/images/users/${authStore.getCurrentUser()?.image || 'default.jpg'}`">
+        <template #title>
+          <span style="font-size: 20px; font-weight: bold">
+            {{ authStore.getCurrentUser()?.name || 'Unknown User' }}
+          </span>
+        </template>
+        <template #subtitle>
+          <span style="font-size: 17px">
+            {{ authStore.getCurrentUser()?.role?.name || 'No Role' }}
+          </span>
+        </template>
+      </v-list-item>
     </v-list>
     <!-- nav -->
     <v-list density="compact" nav>
       <!---->
       <v-list-item prepend-icon="mdi-chart-areaspline" title="แดชบอร์ด" value="dashboard"
-          :to="{ path: '/dashboard' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/dashboard' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-cart-outline" title="จัดการคำสั่งซื้อ" value="management"
-          :to="{ path: '/management' }"></v-list-item>
-        <!---->
-        <v-list-item prepend-icon="mdi-text-box" title="คิวการผลิต" value="pos" :to="{ name: 'pq' }"></v-list-item>
-        <!---->
-        <!---->
+        :to="{ path: '/management' }"></v-list-item>
+      <!---->
+      <v-list-item prepend-icon="mdi-text-box" title="คิวการผลิต" value="pos" :to="{ name: 'pq' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-car" title="คิวการขนส่ง" value="transport-queue"
-          :to="{ path: '/transport-queue' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/transport-queue' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-cube-outline" title="จัดการวัตถุดิบ" value="manage-materials"
-          :to="{ path: '/manage-materials' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/manage-materials' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-archive" title="จัดการสินค้า" value="manage-products"
-          :to="{ path: '/manage-products' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/manage-products' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-account-multiple" title="จัดการลูกค้า" value="manage-customers"
-          :to="{ path: '/manage-customers' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/manage-customers' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-clipboard-account" title="จัดการพนักงาน" value="manage-employees"
-          :to="{ path: '/manage-employees' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/manage-employees' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-factory" title="จัดการเครื่องจักร" value="manage-machines"
-          :to="{ path: '/manage-machines' }"></v-list-item>
-        <!---->
-          <!---->
+        :to="{ path: '/manage-machines' }"></v-list-item>
+      <!---->
+      <!---->
       <v-list-item prepend-icon="mdi-truck-delivery" title="จัดการรถขนส่ง" value="manage-transportation-cars"
-          :to="{ path: '/manage-transportation-cars' }"></v-list-item>
-        <!---->
-        <v-list-item prepend-icon="mdi-account-tie" title="จัดการผู้ใช้งาน" value="user"
-          :to="{ path: '/user' }"></v-list-item>
-        <!---->
+        :to="{ path: '/manage-transportation-cars' }"></v-list-item>
+      <!---->
+      <v-list-item prepend-icon="mdi-account-tie" title="จัดการผู้ใช้งาน" value="user"
+        :to="{ path: '/user' }"></v-list-item>
+      <!---->
     </v-list>
     <v-list density="compact" nav style="position: absolute; bottom: 0; width: 100%;">
       <v-divider></v-divider>
-              <v-list-item prepend-icon="mdi-cog" title="ตั้งค่า" value="setting" ></v-list-item>
-              <v-list-item prepend-icon="mdi-logout" title="ออกจากระบบ" value="logout" @click="authStore.logout()"></v-list-item>
+      <v-list-item prepend-icon="mdi-cog" title="ตั้งค่า" value="setting"></v-list-item>
+      <v-list-item prepend-icon="mdi-logout" title="ออกจากระบบ" value="logout"
+        @click="authStore.logout()"></v-list-item>
     </v-list>
-    
+
   </v-navigation-drawer>
 </template>
\ No newline at end of file
diff --git a/src/services/queue.ts b/src/services/queue.ts
index 93461466ea6cebac4030a99be93ed12b102e26bf..710d5cac468d1c9a2f9cec246f4bc17bd043d522 100644
--- a/src/services/queue.ts
+++ b/src/services/queue.ts
@@ -1,4 +1,45 @@
-import type { Queue } from '@/types/Queue'
+import axios from 'axios';
+import type { QueueItem } from '@/types/QueueItem';
+
+const makeQueue = async (): Promise<QueueItem[] | undefined> => {
+  try {
+    // เรียก API
+    const response = await axios.post('http://127.0.0.1:9000/run-simulation');
+    console.log('📌 Response:', response);
+
+    const queueData = response.data.production_log;
+    console.log('this is queueData queueservice', queueData);
+
+    if (!Array.isArray(queueData)) {
+      console.error('❌ Error: Invalid queue data format');
+      return undefined;
+    }
+
+    // ✅ แปลงข้อมูลเป็น JSON String แล้ว Parse กลับมาเป็น Object ใหม่
+    const queueItems: QueueItem[] = JSON.parse(
+      JSON.stringify(queueData.map(q => ({
+        queueID: q.queueID,
+        machineID: q.machineID,
+        orderID: q.orderID,
+        pageNumber: q.pageNumber ?? 1, // ถ้าไม่มี ให้ใช้ค่า default เป็น 1
+        startTime: q.startTime,
+        finishTime: q.finishTime,
+        status: q.status,
+        bottleSize: q.bottleSize,
+        producedQuantity: q.producedQuantity,
+      })))
+    );
+
+    return queueItems; // ✅ คืนค่าเป็น `QueueItem[]`
+  } catch (error: any) {
+    console.error('❌ Error:', error.message || error);
+    return undefined;
+  }
+};
+
+export default { makeQueue };
+
+
 
 export class QueueService {
   private queue: Queue[] = [];
@@ -47,4 +88,5 @@ export class QueueService {
     }
     return null;
   }
+
 }
diff --git a/src/stores/queue.ts b/src/stores/queue.ts
new file mode 100644
index 0000000000000000000000000000000000000000..370d79ca1fcce60b8b3be85eef722a02a6f274ad
--- /dev/null
+++ b/src/stores/queue.ts
@@ -0,0 +1,41 @@
+import { defineStore } from 'pinia';
+import QueueService from '@/services/queue';
+import type { QueueItem } from '@/types/QueueItem'
+import { ref } from 'vue';
+import { useLoadingStore } from './loading';
+
+// ฟังก์ชัน Sleep ให้รอจริง ๆ
+function sleep(ms: number) {
+  return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+export const useQueueStore = defineStore('queue', () => {
+  const Queues = ref<QueueItem[]>([]);
+  const loadingStore = useLoadingStore();
+
+  const makeQueue = async () => {
+    try {
+      // ✅ รอ 3 วินาทีจริง ๆ ก่อนเริ่มโหลด
+      loadingStore.isLoading = true;
+      console.log("Waiting for 3 seconds...");
+      await sleep(3000);
+
+      console.log("Fetching queue data...");
+      const queueData = await QueueService.makeQueue(); // ✅ รอ API
+
+      if (queueData && Array.isArray(queueData)) {
+        console.log("Appending data to Queues...");
+        Queues.value = [...queueData]; // ✅ ใช้ spread แทน forEach()
+      } else {
+        console.log("No queue data received.");
+      }
+
+      loadingStore.isLoading = false; // ✅ ปิด loading เมื่อโหลดเสร็จ
+    } catch (error) {
+      console.error('❌ Error fetching queue:', error);
+      loadingStore.isLoading = false; // ปิด loading ถ้า error
+    }
+  };
+
+  return { Queues, makeQueue };
+});
diff --git a/src/types/Queue.ts b/src/types/Queue.ts
index d213212600126150443b8ebf03ca3cf933c5c3a5..ca35bf679eb7c8dec528d95fdeb09c73c7fed160 100644
--- a/src/types/Queue.ts
+++ b/src/types/Queue.ts
@@ -1,11 +1,11 @@
 export type Queue = {
-  queueID: number; // PK - รหัส Queue
-  machineID: number; // FK - รหัสเครื่องจักรที่ใช้
-  orderID: number; // FK - รหัสออเดอร์ที่เกี่ยวข้อง
-  pageID: number; // FK - รหัสหน้าที่แสดงใน Gantt Chart
-  startTime: Date; // เวลาเริ่มต้น
-  finishTime: Date; // เวลาสิ้นสุด
-  status: 'pending' | 'in-progress' | 'completed' | 'canceled'; // สถานะของคิว
-  bottleSize: string; // ขนาดขวดที่ผลิต
-  producedQuantity: number; // จำนวนที่ผลิตได้
-};
+  queueID: number | string;
+  machineID: number | string;
+  orderID: number | string;
+  pageID: number;
+  startTime: Date;
+  finishTime: Date;
+  status: 'pending' | 'in-progress' | 'completed' | 'canceled';
+  bottleSize: string;
+  producedQuantity: number;
+};
\ No newline at end of file
diff --git a/src/types/QueueItem.ts b/src/types/QueueItem.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b156202566bdb31c059624a31a339890de072e9d
--- /dev/null
+++ b/src/types/QueueItem.ts
@@ -0,0 +1,11 @@
+export type QueueItem = {
+  queueID: number;
+  machineID: string;
+  orderID: number;
+  pageNumber: number;
+  startTime: string;
+  finishTime: string;
+  status: string;
+  bottleSize: string;
+  producedQuantity: number;
+}
\ No newline at end of file
diff --git a/src/views/ProductQueueViewAof.vue b/src/views/ProductQueueViewAof.vue
new file mode 100644
index 0000000000000000000000000000000000000000..78c78c38318fb2156662bb1e642716d7be62b5af
--- /dev/null
+++ b/src/views/ProductQueueViewAof.vue
@@ -0,0 +1,90 @@
+<script setup>
+import { ref } from 'vue'
+import GanttChart from '@/components/GanttChartAof/GanttChart.vue'
+import EmployeeSector from '@/components/EmployeeSector.vue'
+
+
+const employees = Array.from({ length: 10 }, (_, i) => `EM${i + 1}`)
+const orders = ref([
+  { id: 1, name: 'ORDER1' },
+  { id: 2, name: 'ORDER2' },
+  { id: 3, name: 'ORDER3' }
+])
+
+// Drag and drop functionality
+const draggedOrder = ref(null)
+
+const handleDragStart = (order) => {
+  draggedOrder.value = order
+}
+
+const handleDragOver = (event) => {
+  event.preventDefault()
+}
+
+const handleDrop = (targetOrder) => {
+  if (!draggedOrder.value || draggedOrder.value === targetOrder) return
+
+  // Find the indices of the dragged and target orders
+  const draggedIndex = orders.value.findIndex((o) => o.id === draggedOrder.value.id)
+  const targetIndex = orders.value.findIndex((o) => o.id === targetOrder.id)
+
+  // Remove the dragged order from its original position
+  const [removed] = orders.value.splice(draggedIndex, 1)
+
+  // Insert the dragged order at the target position
+  orders.value.splice(targetIndex, 0, removed)
+
+  // Reset the dragged order
+  draggedOrder.value = null
+}
+</script>
+
+<template>
+  <v-container class="pa-0">
+    <!-- Gantt chart -->
+    <v-sheet class="pa-1 mb-3"
+      style="border-radius: 15px; max-width: 98%; margin-left: auto; margin-right: auto; min-height: 460px;">
+      <!-- Gantt Chart -->
+      <GanttChart />
+    </v-sheet>
+
+    <!-- Bottom Section -->
+    <v-row class="mt-1" style="max-width: 100%; margin-left: auto; margin-right: auto;">
+      <!-- Employee Selection -->
+      <v-col cols="6">
+        <v-card class="pa-4" style="background-color: white; border-radius: 15px; min-height: 280px;">
+          <!-- เลือกพนักงานวางทับตรงนี้ -->
+          <EmployeeSector :employees="employees" />
+        </v-card>
+      </v-col>
+
+      <!-- Order Priority -->
+      <v-col cols="6">
+        <v-card class="pa-5" style="background-color: white; border-radius: 15px; min-height: 280px">
+          <p class="text-center font-weight-bold mb-4 text-black" style="font-size: 20px;">ลำดับความสำคัญ</p>
+          <div v-for="order in orders" :key="order.id" class="order-item" draggable="true"
+            @dragstart="() => handleDragStart(order)" @dragover="handleDragOver" @drop="() => handleDrop(order)">
+            {{ order.name }}
+          </div>
+        </v-card>
+      </v-col>
+    </v-row>
+  </v-container>
+</template>
+<!-- ส่วน UI ของปุ่ม Order1--2 -->
+<style scoped>
+.order-item {
+  background-color: #2b2e3f;
+  color: white;
+  padding: 7px;
+  margin-bottom: 8px;
+  text-align: center;
+  cursor: move;
+  user-select: none;
+}
+
+.order-item:hover {
+  opacity: 0.9;
+}
+</style>