Browse Source

added appointment datepicker

liontix 10 months ago
parent
commit
32609a51fd
3 changed files with 167 additions and 1 deletions
  1. 128 0
      src/lib/modules/DatePicker.svelte
  2. 2 1
      src/routes/+layout.svelte
  3. 37 0
      src/routes/appointment/+page.svelte

+ 128 - 0
src/lib/modules/DatePicker.svelte

@@ -0,0 +1,128 @@
+<script lang="ts">
+    import { onMount } from 'svelte';
+  
+    let currentDate: Date = new Date();
+    let days: Array<{ day: number; isActive: boolean, isAvailable: boolean }> = [];
+    let currentMonth: string = '';
+  
+    /**
+     * Updates the calendar display by calculating the days of the current month.
+     */
+    const renderCalendar = (): void => {
+      const year: number = currentDate.getFullYear();
+      const month: number = currentDate.getMonth();
+      currentMonth = currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
+  
+      const firstDayOfMonth: Date = new Date(year, month, 1);
+      const lastDayOfMonth: Date = new Date(year, month + 1, 0);
+      const firstDayIndex: number = firstDayOfMonth.getDay();
+      const daysInMonth: number = lastDayOfMonth.getDate();
+  
+      // Reset days array
+      days = [];
+  
+      // Add empty cells for days before the first of the month
+      for (let i = 0; i < firstDayIndex; i++) {
+        days.push({ day: 0, isActive: false, isAvailable: false });
+      }
+  
+      // Add days of the month
+      for (let day = 1; day <= daysInMonth; day++) {
+        days.push({ day, isActive: day === 20, isAvailable: day / 2 == 5.5 }); // Example: Make day 20 active
+      }
+    };
+  
+    /**
+     * Changes the current month by a given offset and re-renders the calendar.
+     * @param offset - The number of months to move forward or backward.
+     */
+    const changeMonth = (offset: number): void => {
+      currentDate.setMonth(currentDate.getMonth() + offset);
+      renderCalendar();
+    };
+  
+    onMount(() => {
+      renderCalendar();
+    });
+  
+    /**
+     * Handles the selection of a day in the calendar.
+     * @param selectedDay - The day number that was clicked.
+     */
+    const selectDay = (selectedDay: number): void => {
+      days = days.map((d) => ({ ...d, isActive: d.day === selectedDay}));
+    };
+  </script>
+  
+  <style>
+    .date-picker {
+      border: 1px solid var(--border-color);
+      border-radius: var(--border-radius);
+      padding: 1rem;
+      max-width: 600px;
+      background: var(--background);
+      box-shadow: var(--shadow);
+    }
+    .date-picker-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 1rem;
+    }
+    .date-picker-grid {
+      display: grid;
+      grid-template-columns: repeat(7, 1fr);
+      gap: 0.5rem;
+      text-align: center;
+    }
+    .date-picker-day {
+      font-weight: bold;
+      color: var(--secondary);
+    }
+    .date-picker-cell {
+      padding: 0.5rem;
+      border-radius: var(--border-radius);
+      cursor: pointer;
+      user-select: none;
+    }
+    .date-picker-cell:hover {
+      background-color: var(--hover-background);
+    }
+    .date-picker-cell.active {
+        background-color: var(--primary);
+        color: var(--background);
+    }
+    .empty {
+      pointer-events: none;
+      visibility: hidden;
+    }
+  </style>
+  
+
+<div class="date-picker border center">
+    <div class="date-picker-header">
+        <button class="button square secondary medium" on:click={() => changeMonth(-1)}>&lt;</button>
+        <h4 id="currentMonth" class="small wrap center-align">{currentMonth}</h4>
+        <button class="button square secondary medium" on:click={() => changeMonth(1)}>&gt;</button>
+    </div>
+    <div class="date-picker-grid">
+        <!-- Days of the week -->
+        <div class="date-picker-day">Sun</div>
+        <div class="date-picker-day">Mon</div>
+        <div class="date-picker-day">Tue</div>
+        <div class="date-picker-day">Wed</div>
+        <div class="date-picker-day">Thu</div>
+        <div class="date-picker-day">Fri</div>
+        <div class="date-picker-day">Sat</div>
+
+        <!-- Render days -->
+        {#each days as { day, isActive, isAvailable }, index}
+        <div
+            class="date-picker-cell {isAvailable && !isActive ? 'secondary': ''} {isActive ? 'active' : ''} {day === 0 ? 'empty' : ''}"
+            on:click={() => day && selectDay(day)}
+        >
+            {day || ''}
+        </div>
+        {/each}
+    </div>
+</div>

+ 2 - 1
src/routes/+layout.svelte

@@ -1,8 +1,9 @@
 <main class="responsive max">
     <nav>
         <h5 class="max center-align">Booker</h5>
-    </nav>
 
+    </nav>
+    <hr>
     <slot/>
 
     <nav class="bottom no-space tabbed medium">

+ 37 - 0
src/routes/appointment/+page.svelte

@@ -0,0 +1,37 @@
+<script lang="ts">
+    import DatePicker from '$lib/modules/DatePicker.svelte';
+</script>
+  
+<style>
+    .w-80 {
+        max-width: 600px;
+    }
+
+    .inline-margin {
+        margin-inline: auto;
+    }
+</style>
+
+<DatePicker />
+
+<div class="top-margin w-80 inline-margin border"> 
+    <article class="bottom-margin">
+        <h5>Title</h5>
+        <p><i>pin_drop</i> Location</p>
+        <p><i>description</i> Description</p>
+    </article>  
+    <hr>
+    <h4>Times</h4>
+    <article>
+        <a class="row wave center-align">15:00</a>
+        <hr>
+        <a class="row wave center-align">15:15</a>
+        <hr>
+        <a class="row wave center-align">15:30</a>
+        <hr>
+        <a class="row wave center-align">17:00</a>
+        <hr>
+        <a class="row wave center-align">17:15</a>
+    </article>
+    <button class="button">Test</button>
+</div>