Index: ReserveNGo-frontend/src/components/Project/Customer/EditReservationModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/EditReservationModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
+++ ReserveNGo-frontend/src/components/Project/Customer/EditReservationModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -0,0 +1,174 @@
+<script setup>
+import { ref, computed, watch, onMounted } from 'vue'
+import BaseModal from '@/components/Project/Utility/GeneralModal.vue'
+import { useTables } from '@/repository/Tables.ts'
+import { useReservations } from '@/repository/Reservations.ts'
+import { useToasts } from '@/composables/useToast.js'
+
+const props = defineProps({
+  showModal: Boolean,
+  reservation: {
+    type: Object,
+    default: null,
+  },
+})
+
+const emit = defineEmits(['closeModal', 'edited'])
+
+const { showToast } = useToasts()
+
+const reservationId = computed(() => props.reservation?.id ?? props.reservation?.reservationId)
+const timeOfReservation = ref('')
+const status = ref('')
+const localId = ref(null)
+const availableTables = ref([])
+const selectedTableId = ref(null)
+const loading = ref(false)
+const loadingTables = ref(false)
+const submitting = ref(false)
+
+function normalizeDateTime(dt) {
+  if (!dt) return ''
+  return dt.length === 16 ? dt + ':00' : dt
+}
+
+const canSubmit = computed(() => {
+  return !!reservationId.value && !!timeOfReservation.value && selectedTableId.value !== null && !!status.value
+})
+
+async function loadEditInfo() {
+  if (!reservationId.value) return
+  try {
+    loading.value = true
+    // Attempt to get richer info for editing
+    const info = await useReservations.getEditReservationInfo(reservationId.value)
+    // Expecting structure with localId, tableId, timeOfReservation, status (fallbacks below)
+    localId.value = info?.localId ?? props.reservation?.localId ?? null
+    status.value = info?.status ?? props.reservation?.status ?? 'PENDING'
+    const iso = (info?.timeOfReservation ?? props.reservation?.timeOfReservation ?? '')
+    // Convert possible ISO "YYYY-MM-DDTHH:mm:ss" to input-compatible "YYYY-MM-DDTHH:mm"
+    const dt = iso ? iso.substring(0, 16) : ''
+    timeOfReservation.value = dt
+    selectedTableId.value = info?.tableId ?? props.reservation?.tableId ?? null
+
+    if (localId.value && timeOfReservation.value) {
+      await loadTables()
+    }
+  } catch (err) {
+    console.error(err)
+    // Fallback populate from props if possible
+    localId.value = props.reservation?.localId ?? null
+    status.value = props.reservation?.status ?? 'PENDING'
+    const iso = props.reservation?.timeOfReservation ?? ''
+    timeOfReservation.value = iso ? iso.substring(0, 16) : ''
+    selectedTableId.value = props.reservation?.tableId ?? null
+  } finally {
+    loading.value = false
+  }
+}
+
+async function loadTables() {
+  if (!localId.value || !timeOfReservation.value) return
+  try {
+    loadingTables.value = true
+    const tables = await useTables.getAvailableTables(localId.value, normalizeDateTime(timeOfReservation.value))
+    availableTables.value = Array.isArray(tables) ? tables : []
+    // If current table still available, keep it selected; else reset
+    if (selectedTableId.value && !availableTables.value.some(t => String(t.id) === String(selectedTableId.value))) {
+      selectedTableId.value = null
+    }
+  } catch (err) {
+    console.error(err)
+    availableTables.value = []
+  } finally {
+    loadingTables.value = false
+  }
+}
+
+watch(timeOfReservation, async (newVal) => {
+  if (!newVal || !localId.value) return
+  await loadTables()
+})
+
+onMounted(loadEditInfo)
+
+async function submitEdit() {
+  if (!canSubmit.value || submitting.value) return
+  try {
+    submitting.value = true
+    const payload = {
+      timeOfReservation: normalizeDateTime(timeOfReservation.value),
+      tableId: String(selectedTableId.value),
+      status: String(status.value).toUpperCase(),
+    }
+    const res = await useReservations.editReservation(reservationId.value, payload)
+    showToast('Reservation updated successfully.', 'success')
+    emit('edited', res)
+    emit('closeModal')
+  } catch (err) {
+    console.error(err)
+    const message = err?.response?.message || 'Failed to update reservation.'
+    showToast(message, 'error')
+  } finally {
+    submitting.value = false
+  }
+}
+</script>
+
+<template>
+  <BaseModal :show="props.showModal" @close="emit('closeModal')">
+    <h2 style="margin-bottom: 1rem;">Edit reservation</h2>
+
+    <div v-if="loading">Loading...</div>
+    <div v-else class="form-grid">
+      <label class="form-row">
+        <span>Date and time</span>
+        <input type="datetime-local" v-model="timeOfReservation" />
+      </label>
+
+      <label class="form-row">
+        <span>Status</span>
+        <select v-model="status">
+          <option value="PENDING">PENDING</option>
+          <option value="CONFIRMED">CONFIRMED</option>
+          <option value="CANCELLED">CANCELLED</option>
+        </select>
+      </label>
+
+      <div class="form-row">
+        <span>Available tables</span>
+        <div v-if="loadingTables">Loading tables...</div>
+        <div v-else>
+          <select v-model="selectedTableId">
+            <option :value="null" disabled>Select a table</option>
+            <option v-for="t in availableTables" :key="t.id" :value="t.id">
+              Table #{{ t.tableNumber ?? t.number ?? t.id }} (cap: {{ t.capacity ?? '-' }})
+            </option>
+          </select>
+          <div v-if="!loadingTables && availableTables.length === 0 && timeOfReservation" class="hint">
+            No tables for the chosen time.
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="actions">
+      <button class="btn-outline" @click="emit('closeModal')">Close</button>
+      <button class="btn-primary" :disabled="!canSubmit || submitting" @click="submitEdit">
+        {{ submitting ? 'Saving...' : 'Save changes' }}
+      </button>
+    </div>
+  </BaseModal>
+
+</template>
+
+<style scoped>
+.form-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
+.form-row { display: flex; flex-direction: column; gap: 0.35rem; }
+.actions { display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 1rem; }
+.btn-primary { background: #2b6cb0; color: #fff; border: none; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; }
+.btn-primary:disabled { opacity: .6; cursor: not-allowed; }
+.btn-outline { background: transparent; color: #333; border: 1px solid #ccc; padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; }
+.hint { color: #b45309; font-size: 0.9rem; }
+select, input[type='datetime-local'] { padding: .45rem .5rem; border: 1px solid #cbd5e1; border-radius: 6px; }
+</style>
Index: ReserveNGo-frontend/src/components/Project/Customer/makeReservationModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/makeReservationModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
+++ ReserveNGo-frontend/src/components/Project/Customer/makeReservationModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -0,0 +1,186 @@
+<script setup>
+import { ref, computed, watch } from 'vue'
+import BaseModal from '@/components/Project/Utility/GeneralModal.vue'
+import { useTables } from '@/repository/Tables.ts'
+import { useReservations } from '@/repository/Reservations.ts'
+import { useToasts } from '@/composables/useToast.js'
+
+const props = defineProps({
+  showModal: Boolean,
+  localId: [Number, String, Object],
+})
+
+const emit = defineEmits(['closeModal', 'openModal', 'reservationMade'])
+
+// Toasts
+const { showToast } = useToasts()
+
+// Form state
+const reservationDateTime = ref('')
+const capacity = ref(null)
+const availableTables = ref([])
+const selectedTableId = ref(null)
+const loadingTables = ref(false)
+const submitting = ref(false)
+const loadError = ref(null)
+
+function normalizeDateTime(dt) {
+  if (!dt) return ''
+  // if format is YYYY-MM-DDTHH:mm, append :00 seconds
+  return dt.length === 16 ? dt + ':00' : dt
+}
+
+const canSubmit = computed(() => {
+  return !!props.localId && !!reservationDateTime.value && selectedTableId.value !== null
+})
+
+// Fetch tables when date-time changes
+watch(reservationDateTime, async (newVal) => {
+  availableTables.value = []
+  selectedTableId.value = null
+  loadError.value = null
+  console.log("NEW VALUE", props.localId)
+  if (!newVal || !props.localId) return
+  try {
+    console.log("DOES IT GET HERE.")
+    loadingTables.value = true
+    // Use the raw datetime-local string for LocalDateTime parsing on backend
+    const tables = await useTables.getAvailableTables(props.localId, normalizeDateTime(newVal))
+    availableTables.value = Array.isArray(tables) ? tables : []
+    if (availableTables.value.length === 0) {
+      showToast('No tables available for the selected time.', 'error')
+    }
+  } catch (err) {
+    console.error(err)
+    loadError.value = err?.response?.message || 'Failed to load available tables.'
+    showToast(loadError.value, 'error')
+  } finally {
+    loadingTables.value = false
+  }
+})
+
+async function submitReservation() {
+  if (!canSubmit.value || submitting.value) return
+  try {
+    submitting.value = true
+    const selected = availableTables.value.find(t => String(t.id) === String(selectedTableId.value))
+    const payload = {
+      localId: props.localId,
+      timeOfReservation: normalizeDateTime(reservationDateTime.value),
+      tableId: String(selectedTableId.value || ''),
+      tableNumber: selected?.tableNumber,
+      capacity: capacity.value ?? selected?.capacity,
+    }
+    const res = await useReservations.makeReservation(payload)
+    showToast('Reservation created successfully.', 'success')
+    emit('reservationMade', res)
+    emit('closeModal')
+    resetForm()
+  } catch (err) {
+    console.error(err)
+    const message = err?.response?.message || 'Failed to create reservation.'
+    showToast(message, 'error')
+  } finally {
+    submitting.value = false
+  }
+}
+
+function resetForm() {
+  reservationDateTime.value = ''
+  capacity.value = null
+  availableTables.value = []
+  selectedTableId.value = null
+  loadError.value = null
+}
+</script>
+
+<template>
+  <BaseModal :show="props.showModal" @close="emit('closeModal')">
+    <h2 style="margin-bottom: 1rem;">Make a Reservation</h2>
+
+    <div class="form-grid">
+      <label class="form-row">
+        <span>Date and time</span>
+        <input
+          type="datetime-local"
+          v-model="reservationDateTime"
+          :max="''"
+          required
+        />
+      </label>
+
+      <label class="form-row">
+        <span>Capacity (optional)</span>
+        <input type="number" min="1" v-model.number="capacity" placeholder="e.g. 4" />
+      </label>
+
+      <div class="form-row">
+        <span>Available tables</span>
+        <div v-if="loadingTables">Loading tables...</div>
+        <div v-else>
+          <select v-model="selectedTableId">
+            <option :value="null" disabled>Select a table</option>
+            <option v-for="t in availableTables" :key="t.id" :value="t.id">
+              Table #{{ t.tableNumber ?? t.number ?? t.id }} (cap: {{ t.capacity ?? '-' }})
+            </option>
+          </select>
+          <div v-if="!loadingTables && availableTables.length === 0 && reservationDateTime" class="hint">
+            No tables for the chosen time.
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="actions">
+      <button class="btn-outline" @click="emit('closeModal')">Cancel</button>
+      <button class="btn-primary" :disabled="!canSubmit || submitting" @click="submitReservation">
+        {{ submitting ? 'Submitting...' : 'Reserve' }}
+      </button>
+    </div>
+  </BaseModal>
+</template>
+
+<style scoped>
+.form-grid {
+  display: grid;
+  grid-template-columns: 1fr;
+  gap: 1rem;
+}
+.form-row {
+  display: flex;
+  flex-direction: column;
+  gap: 0.35rem;
+}
+.actions {
+  display: flex;
+  justify-content: flex-end;
+  gap: 0.75rem;
+  margin-top: 1rem;
+}
+.btn-primary {
+  background: #2b6cb0;
+  color: #fff;
+  border: none;
+  padding: 0.5rem 1rem;
+  border-radius: 6px;
+  cursor: pointer;
+}
+.btn-primary:disabled {
+  opacity: 0.6;
+  cursor: not-allowed;
+}
+.btn-outline {
+  background: transparent;
+  color: #333;
+  border: 1px solid #ccc;
+  padding: 0.5rem 1rem;
+  border-radius: 6px;
+  cursor: pointer;
+}
+.hint { color: #b45309; font-size: 0.9rem; }
+select, input[type='datetime-local'], input[type='number'] {
+  padding: 0.45rem 0.5rem;
+  border: 1px solid #cbd5e1;
+  border-radius: 6px;
+}
+</style>
Index: ReserveNGo-frontend/src/components/Project/Reservation/My_reservations.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Reservation/My_reservations.vue	(revision 0ee75ae5f82bb1a822daf60d3bce6cbf30a0fe62)
+++ ReserveNGo-frontend/src/components/Project/Reservation/My_reservations.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -1,20 +1,114 @@
-<script setup>
+<script>
+import ReservationCard from '@/components/Project/Reservation/reservation_.vue'
+import EditReservationModal from '@/components/Project/Customer/EditReservationModal.vue'
+import { useReservations } from '@/repository/Reservations.ts'
 
-import reservation_ from '@/components/Project/Reservation/reservation_.vue'
+export default {
+  name: 'MyReservationsPage',
+  components: { ReservationCard, EditReservationModal },
+  data() {
+    return {
+      reservations: [],
+      loading: false,
+      error: null,
+      cancellingId: null,
+      showEditModal: false,
+      targetReservation: null,
+    }
+  },
+  created() {
+    this.fetchReservations()
+  },
+  methods: {
+    async fetchReservations() {
+      this.loading = true
+      this.error = null
+      try {
+        const data = await useReservations.listMyReservations()
+        this.reservations = Array.isArray(data) ? data : []
+      } catch (err) {
+        console.error(err)
+        this.error = err?.response?.message || 'Failed to load reservations.'
+      } finally {
+        this.loading = false
+      }
+    },
+    async onCancelReservation(res) {
+      console.log("WHAT IS RESERVATION HERE", res)
+      if (!res) return
+      if (!confirm('Are you sure you want to cancel this reservation?')) return
+      try {
+        this.cancellingId = res.id ?? null
+        await useReservations.cancelReservation(res.id)
+        // Update local state: set status to CANCELLED
+        this.reservations = this.reservations.map((r) =>
+          r.id === res.id ? { ...r, status: 'CANCELLED' } : r,
+        )
+      } catch (err) {
+        console.error(err)
+        alert('Failed to cancel reservation. Please try again later.')
+      } finally {
+        this.cancellingId = null
+      }
+    },
+    onEditReservation(res) {
+      this.targetReservation = res
+      this.showEditModal = true
+    },
+    onEditedReservation(updated) {
+      // replace in list by id if present
+      const id = updated?.id
+      if (id != null) {
+        this.reservations = this.reservations.map(r => (r.id === id ? { ...r, ...updated } : r))
+      } else if (this.targetReservation) {
+        // fallback shallow merge
+        this.reservations = this.reservations.map(r => (r === this.targetReservation ? { ...r, ...updated } : r))
+      }
+      this.showEditModal = false
+      this.targetReservation = null
+    },
+  },
+}
 </script>
 
 <template>
+  <div class="container-xxl py-4">
+    <h2 class="mb-4">My reservations</h2>
 
-  <div id="container " class="border container-xxl">
+    <div v-if="loading" class="text-center py-5">
+      <div class="spinner-border text-primary" role="status">
+        <span class="visually-hidden">Loading...</span>
+      </div>
+    </div>
 
-    <reservation_/>
-    <reservation_/>
-    <reservation_/>
-    <reservation_/>
+    <div v-else>
+      <div v-if="error" class="alert alert-danger">{{ error }}</div>
 
+      <div v-if="reservations.length === 0" class="text-center text-muted py-5">
+        <i class="far fa-calendar-times fa-3x mb-3"></i>
+        <p class="mb-0">No active reservations.</p>
+      </div>
+
+      <div v-else>
+        <ReservationCard
+          v-for="r in reservations"
+          :key="r.id ?? `${r.localName}-${r.timeOfReservation}`"
+          :reservation="r"
+          :can-cancel="(r.status || '').toUpperCase() !== 'CANCELLED'"
+          @cancel="onCancelReservation"
+          @edit="onEditReservation"
+        />
+      </div>
+    </div>
+
+    <EditReservationModal
+      :show-modal="showEditModal"
+      :reservation="targetReservation"
+      @close-modal="showEditModal = false; targetReservation = null"
+      @edited="onEditedReservation"
+    />
   </div>
 </template>
 
 <style scoped>
-
 </style>
Index: ReserveNGo-frontend/src/components/Project/Reservation/reservation_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Reservation/reservation_.vue	(revision 0ee75ae5f82bb1a822daf60d3bce6cbf30a0fe62)
+++ ReserveNGo-frontend/src/components/Project/Reservation/reservation_.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -1,44 +1,95 @@
 <script>
-
+import { config } from '@/constants/Api_config'
 
 export default {
-
-  data(){
-    return {
-
-      reservation:{
-        id: "res_id",
-        time: "time_of_reservation",
+  name: 'ReservationCard',
+  props: {
+    reservation: {
+      type: Object,
+      required: true,
+    },
+    canCancel: {
+      type: Boolean,
+      default: true,
+    },
+    canEdit: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  emits: ['cancel', 'edit'],
+  computed: {
+    logoUrl() {
+      const path = this.reservation.localLogo
+      if (!path) return 'https://placehold.co/64x64?text=Logo'
+      try {
+        const url = new URL(path, config.API_BASE_URL)
+        return url.toString()
+      } catch {
+        return config.API_BASE_URL + path
       }
-
-    }
+    },
+    isCancelled() {
+      return (this.reservation.status || '').toString().toUpperCase() === 'CANCELLED'
+    },
+    isActive() {
+      return !this.isCancelled
+    },
+    formattedDateTime() {
+      try {
+        const d = new Date(this.reservation.timeOfReservation)
+        return d.toLocaleString()
+      } catch {
+        return this.reservation.timeOfReservation
+      }
+    },
+    statusBadgeClass() {
+      const status = (this.reservation.status || '').toString().toUpperCase()
+      if (status === 'CONFIRMED') return 'bg-success'
+      if (status === 'PENDING') return 'bg-warning text-dark'
+      if (status === 'CANCELLED') return 'bg-secondary'
+      return 'bg-info'
+    },
   },
-  props:[]
-
-
 }
-
-
-
 </script>
 
 <template>
 
-  <div id="container" class="border my-3 p-2">
-    <h3>{{reservation.id}}</h3>
-    <h5>{{reservation.time}}</h5>
-
+  <div class="card shadow-sm mb-3">
+    <div class="card-body d-flex align-items-center gap-3">
+      <img :src="logoUrl" alt="logo" class="rounded" style="width:64px;height:64px;object-fit:cover" />
+      <div class="flex-grow-1">
+        <div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
+          <h5 class="mb-0">{{ reservation.localName }}</h5>
+          <span class="badge" :class="statusBadgeClass">{{ reservation.status }}</span>
+        </div>
+        <div class="text-muted small mt-1">
+          <span class="me-3"><i class="far fa-clock me-1"></i>{{ formattedDateTime }}</span>
+          <span class="me-3"><i class="fas fa-chair me-1"></i>Table {{ reservation.tableNumber }}</span>
+          <span><i class="fas fa-users me-1"></i>{{ reservation.capacity }} seats</span>
+        </div>
+      </div>
+      <div class="ms-auto d-flex gap-2">
+        <button
+          v-if="canEdit && isActive"
+          class="btn btn-outline-primary btn-sm"
+          @click="$emit('edit', reservation)"
+        >
+          <i class="fas fa-edit me-1"></i> Edit
+        </button>
+        <button
+          v-if="canCancel && isActive"
+          class="btn btn-outline-danger btn-sm"
+          @click="$emit('cancel', reservation)"
+        >
+          <i class="fas fa-ban me-1"></i> Cancel
+        </button>
+      </div>
+    </div>
   </div>
 </template>
 
 <style scoped>
-
-#container{
-
-  height: 10vh;
-
-
-}
-
-
+/* No additional scoped styles needed; leveraging Bootstrap */
 </style>
Index: ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue	(revision 0ee75ae5f82bb1a822daf60d3bce6cbf30a0fe62)
+++ ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -16,7 +16,9 @@
 import { useLocales } from '@/repository/Locale'
 import { useCustomer } from '@/repository/Customer.ts'
+import makeReservationModal from '@/components/Project/Customer/makeReservationModal.vue'
 
 export default {
   components: {
+    makeReservationModal,
     LoadingIcon,
     events_carousel,
@@ -104,5 +106,7 @@
       ],
       // Holds text inputs per day during edit mode, e.g. "09:00:00-17:00:00" or "Closed"
-      workingHoursInputs: {}
+      workingHoursInputs: {},
+
+      modalOpen: false,
     }
 
@@ -628,7 +632,12 @@
             <div class="d-flex flex-wrap gap-2">
               <template v-if="userStore.data.role === 'ROLE_CUSTOMER'">
-                <button class="btn btn-dark">
+                <button @click="modalOpen=true" class="btn btn-dark">
                   <i class="fas fa-calendar-check me-1"></i> Reserve
                 </button>
+
+                <make-reservation-modal :localId="locale.id" :show-modal="modalOpen" @open-modal="modalOpen=true" @close-modal="modalOpen=false"></make-reservation-modal>
+
+
+
                 <button class="btn btn-outline-danger" @click="addToFavourites">
                   <i class="fas fa-heart me-1"></i> Add to Favourites
Index: ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue	(revision 0ee75ae5f82bb1a822daf60d3bce6cbf30a0fe62)
+++ ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -5,6 +5,8 @@
 import {config} from '@/constants/Api_config.js'
 import pankake from '@/components/ectd/easy-american-pancake-recipe.jpg'
+import MakeReservationModal from '@/components/Project/Customer/makeReservationModal.vue'
 
 export default {
+  components: { MakeReservationModal },
   props: {
     local: { type: Object, required: true },
@@ -19,5 +21,6 @@
       userStore_: userStore(),
       localeLogo: null,
-      pankake: pankake
+      pankake: pankake,
+      modalOpen: false,
     }
   },
@@ -35,5 +38,5 @@
       return url.toString();
     },
-    
+
     openStatus() {
       if (this.local && typeof this.local.open === 'boolean') {
@@ -123,7 +126,11 @@
             </router-link>
 
-            <button v-if="userStore_.data.role === 'ROLE_CUSTOMER' && mode==='all'" class="btn btn-dark">
+            <button @click="modalOpen=true" v-if="userStore_.data.role === 'ROLE_CUSTOMER' && mode==='all'" class="btn btn-dark">
               <i class="fas fa-calendar-check me-1"></i> Make reservation
             </button>
+
+            <make-reservation-modal :localId="local.id" :show-modal="modalOpen" @open-modal="modalOpen=true" @close-modal="modalOpen=false"></make-reservation-modal>
+
+
 
             <button class="btn btn-dark" v-if="mode==='favourites'" @click="addToFavorites">Remove favourite</button>
Index: ReserveNGo-frontend/src/components/Project/Utility/GeneralModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/GeneralModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
+++ ReserveNGo-frontend/src/components/Project/Utility/GeneralModal.vue	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -0,0 +1,105 @@
+<!-- components/BaseModal.vue -->
+<script lang="ts">
+export default {
+  name: 'BaseModal',
+  props: {
+    show: {
+      type: Boolean,
+      required: true,
+    },
+    closeOnBackdrop: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  emits: ['close'],
+  methods: {
+    close() {
+      this.$emit('close')
+    },
+    onBackdropClick() {
+      if (this.closeOnBackdrop) {
+        this.close()
+      }
+    },
+  },
+}
+</script>
+
+<template>
+  <Transition name="modal-fade">
+    <div v-if="show" class="modal-backdrop" @click="onBackdropClick">
+      <div class="modal-container" @click.stop>
+        <!-- Close Button -->
+        <button class="close-btn" @click="close">×</button>
+
+        <!-- Slot for ANY content -->
+        <div class="modal-content">
+          <slot />
+        </div>
+      </div>
+    </div>
+  </Transition>
+</template>
+
+<style scoped>
+.modal-backdrop {
+  position: fixed;
+  inset: 0;
+  background-color: rgba(0, 0, 0, 0.6);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1000;
+}
+
+.modal-container {
+  background: white;
+  border-radius: 12px;
+  width: 80%;
+  max-width: 900px;
+  max-height: 80%;
+  position: relative;
+  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
+  overflow: hidden;
+  display: flex;
+  flex-direction: column;
+}
+
+.modal-content {
+  padding: 1.5rem;
+  overflow: auto;
+}
+
+.close-btn {
+  position: absolute;
+  top: 10px;
+  right: 15px;
+  font-size: 2.5rem;
+  font-weight: bold;
+  background: none;
+  border: none;
+  cursor: pointer;
+  line-height: 1;
+  z-index: 10;
+}
+
+@media (max-width: 1000px) {
+  .modal-container {
+    width: 100%;
+    height: 100%;
+    max-height: 100%;
+    border-radius: 0;
+  }
+}
+
+.modal-fade-enter-active,
+.modal-fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.modal-fade-enter-from,
+.modal-fade-leave-to {
+  opacity: 0;
+}
+</style>
Index: ReserveNGo-frontend/src/repository/Reservations.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Reservations.ts	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
+++ ReserveNGo-frontend/src/repository/Reservations.ts	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -0,0 +1,79 @@
+import { config } from '@/constants/Api_config'
+import { HttpClient } from '@/Api_Classes/HttpClient'
+
+const BASE_API_URL = config.API_BASE_URL
+
+export type CreateReservationDTO = {
+  localId: number | string
+  timeOfReservation: string // ISO string
+  tableId: number | string
+  tableNumber?: number
+  capacity?: number
+}
+
+export type ReservationStatus =
+  | 'PENDING'
+  | 'CONFIRMED'
+  | 'CANCELLED'
+  | string
+
+export type DisplayReservationDTO = {
+  id?: number | string
+  localId?: number | string
+  localName: string
+  localLogo: string | null
+  timeOfReservation: string
+  tableNumber: number
+  capacity: number
+  status: ReservationStatus
+  tableId?: number | string
+}
+
+export type EditReservationDTO = {
+  timeOfReservation: string // ISO string
+  tableId: number | string
+  status: ReservationStatus
+}
+
+class ReservationsRepository {
+  private readonly httpClient: HttpClient
+
+  constructor(baseUrl: string) {
+    this.httpClient = new HttpClient(baseUrl)
+  }
+
+  // POST /api/reservations/make-reservation
+  makeReservation(dto: CreateReservationDTO): Promise<any> {
+    return this.httpClient.post('make-reservation', dto)
+  }
+
+  // GET /api/reservations
+  listMyReservations(): Promise<DisplayReservationDTO[]> {
+    return this.httpClient.get('')
+  }
+
+  // PUT /api/reservations/{id}/cancel
+  cancelReservation(reservationId: number | string): Promise<void> {
+    return this.httpClient.put(`${reservationId}/cancel`, null)
+  }
+
+  // GET /api/reservations/{id}
+  getReservationDetails(reservationId: number | string): Promise<DisplayReservationDTO> {
+    return this.httpClient.get(`${reservationId}`)
+  }
+
+  // PUT /api/reservations/{id}/edit
+  editReservation(
+    reservationId: number | string,
+    dto: EditReservationDTO,
+  ): Promise<DisplayReservationDTO> {
+    return this.httpClient.put(`${reservationId}/edit`, dto)
+  }
+
+  // GET /api/reservations/{id}/edit-info
+  getEditReservationInfo(reservationId: number | string): Promise<any> {
+    return this.httpClient.get(`${reservationId}/edit-info`)
+  }
+}
+
+export const useReservations = new ReservationsRepository(BASE_API_URL + '/api/reservations')
Index: ReserveNGo-frontend/src/repository/Tables.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Tables.ts	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
+++ ReserveNGo-frontend/src/repository/Tables.ts	(revision c12b19ceda30b5ac7865d35e8fbe42a2d9477119)
@@ -0,0 +1,24 @@
+import { config } from '@/constants/Api_config'
+import { HttpClient } from '@/Api_Classes/HttpClient'
+
+const BASE_API_URL = config.API_BASE_URL
+
+class TablesRepository {
+  private readonly httpClient: HttpClient
+
+  constructor(baseUrl: string) {
+    this.httpClient = new HttpClient(baseUrl)
+  }
+
+  // GET /api/tables?localId=...&reservationTime=...
+  getAvailableTables(localId: number | string, reservationTimeIso: string): Promise<any[]> {
+    return this.httpClient.get(undefined, {
+      queryParams: {
+        localId: String(localId),
+        reservationTime: reservationTimeIso,
+      },
+    })
+  }
+}
+
+export const useTables = new TablesRepository(BASE_API_URL + '/api/tables')
