calendar

A HTML/PHP project for a self-hosted (family)-calendar.
Log | Files | Refs | README

index.html (9759B)


      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4   <meta charset="utf-8">
      5   <meta name="viewport" content="width=device-width, initial-scale=1.0">
      6   <link rel="preconnect" href="https://fonts.googleapis.com">
      7   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      8   <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=EB+Garamond:ital,wght@0,400;0,600;1,400&display=swap" rel="stylesheet">
      9   <link rel="stylesheet" href="/static/style.css">
     10   <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📅</text></svg>">
     11   <title>Calendar &mdash; Piribauer</title>
     12 </head>
     13 <body>
     14 
     15   <nav class="topbar">
     16     <div class="topbar-inner">
     17       <div class="topbar-left">
     18         <a href="/" class="topbar-name">Calendar</a>
     19         <a href="https://hub.piribauer.ch" class="topbar-back">Hub</a>
     20       </div>
     21       <div class="topbar-right">
     22         <span class="nav-link" id="username-display"></span>
     23         <a href="https://auth.piribauer.ch/if/user/" class="nav-link" target="_blank" rel="noopener" data-i18n="account">Account</a>
     24         <a href="/outpost.goauthentik.io/sign_out" class="nav-link signout" data-i18n="sign-out">Sign out</a>
     25         <div class="lang-switcher">
     26           <button class="lang-opt lang-active" data-lang="en" onclick="setLang('en')">EN</button>
     27           <button class="lang-opt" data-lang="de" onclick="setLang('de')">DE</button>
     28         </div>
     29         <a href="https://hub.piribauer.ch" class="topbar-home" aria-label="Hub">
     30           <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
     31             <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25" />
     32           </svg>
     33         </a>
     34       </div>
     35     </div>
     36   </nav>
     37 
     38   <div class="app-body">
     39 
     40     <!-- Sidebar -->
     41     <aside class="sidebar">
     42       <div id="upcoming-section" class="upcoming-section"></div>
     43       <div class="sidebar-divider"></div>
     44       <div class="sidebar-header" data-i18n="sidebar-calendars">Calendars</div>
     45       <div class="calendar-list" id="calendar-list"></div>
     46       <div class="sidebar-actions">
     47         <button class="btn-new-cal" id="btn-new-cal">
     48           <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
     49             <path d="M12 5v14M5 12h14" stroke-linecap="round"/>
     50           </svg>
     51           <span data-i18n="new-calendar">New calendar</span>
     52         </button>
     53       </div>
     54     </aside>
     55 
     56     <!-- Calendar main -->
     57     <div class="calendar-main">
     58 
     59       <!-- Monthly view -->
     60       <section class="monthly-view">
     61         <div class="monthly-header">
     62           <div class="monthly-header-left">
     63             <button class="btn-sidebar-toggle" id="btn-sidebar-toggle" data-i18n-title="toggle-sidebar" title="Toggle sidebar">
     64               <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
     65                 <path d="M3 6h18M3 12h18M3 18h18" stroke-linecap="round"/>
     66               </svg>
     67             </button>
     68             <h2 class="monthly-title" id="month-title"></h2>
     69           </div>
     70           <div class="nav-btns">
     71             <button class="nav-btn" id="prev-month" data-i18n-title="prev-month" title="Previous month">
     72               <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
     73                 <path d="M15 19l-7-7 7-7" stroke-linecap="round" stroke-linejoin="round"/>
     74               </svg>
     75             </button>
     76             <button class="nav-btn" id="next-month" data-i18n-title="next-month" title="Next month">
     77               <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
     78                 <path d="M9 5l7 7-7 7" stroke-linecap="round" stroke-linejoin="round"/>
     79               </svg>
     80             </button>
     81           </div>
     82         </div>
     83 
     84         <div class="weekday-row">
     85           <div class="weekday-label" data-i18n="weekday-mon">Mon</div>
     86           <div class="weekday-label" data-i18n="weekday-tue">Tue</div>
     87           <div class="weekday-label" data-i18n="weekday-wed">Wed</div>
     88           <div class="weekday-label" data-i18n="weekday-thu">Thu</div>
     89           <div class="weekday-label" data-i18n="weekday-fri">Fri</div>
     90           <div class="weekday-label" data-i18n="weekday-sat">Sat</div>
     91           <div class="weekday-label" data-i18n="weekday-sun">Sun</div>
     92         </div>
     93 
     94         <div class="day-grid" id="day-grid"></div>
     95       </section>
     96 
     97       <!-- Daily view -->
     98       <section class="daily-view" id="daily-view">
     99         <div class="daily-header">
    100           <h3 class="daily-title" id="daily-title"></h3>
    101           <div class="daily-header-right">
    102             <button class="btn-add-event" id="btn-add-event" data-i18n="add-event">+ Add event</button>
    103             <button class="btn-close" id="btn-close-daily" data-i18n-title="close" title="Close">
    104               <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
    105                 <path d="M18 6L6 18M6 6l12 12" stroke-linecap="round"/>
    106               </svg>
    107             </button>
    108           </div>
    109         </div>
    110         <div class="allday-section" id="allday-section" style="display:none">
    111           <div class="allday-label" data-i18n="all-day-label">all day</div>
    112           <div class="allday-events" id="allday-events"></div>
    113         </div>
    114         <div class="time-grid" id="time-grid"></div>
    115       </section>
    116 
    117     </div>
    118   </div>
    119 
    120   <!-- Context menu -->
    121   <div class="ctx-menu" id="ctx-menu"></div>
    122 
    123   <!-- Calendar modal (create / edit / invite) -->
    124   <div class="modal-overlay" id="modal-overlay">
    125     <div class="modal" id="modal">
    126       <h2></h2>
    127       <div class="modal-body"></div>
    128       <div class="modal-actions">
    129         <button class="btn" id="modal-cancel" data-i18n="cancel">Cancel</button>
    130         <button class="btn btn-primary" id="modal-submit" data-i18n="save">Save</button>
    131       </div>
    132     </div>
    133   </div>
    134 
    135   <!-- Manage calendar members -->
    136   <div class="modal-overlay" id="modal-members-overlay">
    137     <div class="modal modal-wide">
    138       <h2 id="modal-members-title"></h2>
    139       <div id="cal-members-list"></div>
    140       <div class="members-invite-section" id="cal-members-invite">
    141         <p class="form-label" style="margin-bottom:0.6rem;margin-top:1.25rem" data-i18n="add-by-username">Add by username</p>
    142         <div class="invite-row">
    143           <input class="form-input" id="cal-invite-username" type="text" data-i18n-placeholder="username-ph" placeholder="username">
    144           <button class="btn btn-primary" id="btn-members-add" data-i18n="invite-btn">Add</button>
    145         </div>
    146       </div>
    147       <div class="modal-actions">
    148         <button class="btn btn-primary" id="btn-members-close" data-i18n="done">Done</button>
    149       </div>
    150     </div>
    151   </div>
    152 
    153   <!-- Event modal -->
    154   <div class="modal-overlay" id="event-modal-overlay">
    155     <div class="modal event-modal" id="event-modal">
    156       <h2 data-i18n="new-event">New event</h2>
    157 
    158       <div class="form-group">
    159         <label class="form-label" data-i18n="form-title">Title</label>
    160         <input class="form-input" id="ev-title" type="text" data-i18n-placeholder="event-title-ph" placeholder="Event title">
    161       </div>
    162 
    163       <div class="form-group">
    164         <label class="form-label" data-i18n="form-calendar">Calendar</label>
    165         <select class="form-input" id="ev-calendar"></select>
    166       </div>
    167 
    168       <div class="form-group toggle-row">
    169         <label class="form-label" data-i18n="form-all-day">All day</label>
    170         <label class="toggle-switch">
    171           <input type="checkbox" id="ev-all-day">
    172           <span class="toggle-slider"></span>
    173         </label>
    174       </div>
    175 
    176       <div class="form-row">
    177         <div class="form-group">
    178           <label class="form-label" data-i18n="form-start-date">Start date</label>
    179           <input class="form-input" id="ev-start-date" type="date">
    180         </div>
    181         <div class="form-group" id="ev-start-time-grp">
    182           <label class="form-label" data-i18n="form-start-time">Start time</label>
    183           <input class="form-input" id="ev-start-time" type="time">
    184         </div>
    185       </div>
    186 
    187       <div class="form-row">
    188         <div class="form-group">
    189           <label class="form-label" data-i18n="form-end-date">End date</label>
    190           <input class="form-input" id="ev-end-date" type="date">
    191         </div>
    192         <div class="form-group" id="ev-end-time-grp">
    193           <label class="form-label" data-i18n="form-end-time">End time</label>
    194           <input class="form-input" id="ev-end-time" type="time">
    195         </div>
    196       </div>
    197 
    198       <div class="form-group">
    199         <label class="form-label" data-i18n="form-notes">Notes</label>
    200         <textarea class="form-input" id="ev-description" data-i18n-placeholder="notes-ph" placeholder="Optional notes…"></textarea>
    201       </div>
    202 
    203       <div class="form-group" id="ev-attendees-group" style="display:none">
    204         <label class="form-label" data-i18n="form-attendees">Attendees</label>
    205         <div id="ev-attendees"></div>
    206       </div>
    207 
    208       <div class="modal-actions">
    209         <button class="btn btn-danger" id="ev-delete-btn" style="display:none;margin-right:auto" data-i18n="delete">Delete</button>
    210         <button class="btn" id="event-modal-cancel" data-i18n="cancel">Cancel</button>
    211         <button class="btn btn-primary" id="event-modal-submit" data-i18n="save">Save</button>
    212       </div>
    213     </div>
    214   </div>
    215 
    216   <script src="/static/i18n.js"></script>
    217   <script src="/static/app.js"></script>
    218 </body>
    219 </html>