vnshed/frontend/src/lib/components/calendar.svelte

276 lines
No EOL
6 KiB
Svelte

<script lang="ts">
var dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
let headers: Array<string> = [];
let now = new Date();
let year = now.getFullYear(); // this is the month & year displayed
let month = now.getMonth();
var days: Array<Object> = []; // The days to display in each box
$: month,year,initContent();
// choose what date/day gets displayed in each date box.
function initContent() {
headers = dayNames;
initMonth();
}
function initMonth() {
days = [];
// find the last Monday of the previous month
var firstDay = new Date(year, month, 1).getDay();
//console.log('fd='+firstDay+' '+dayNames[firstDay]);
var daysInThisMonth = new Date(year, month+1, 0).getDate();
var daysInLastMonth = new Date(year, month, 0).getDate();
var prevMonth = month==0 ? 11 : month-1;
// show the days before the start of this month (disabled) - always less than 7
for (let i=daysInLastMonth-firstDay;i<daysInLastMonth;i++) {
let d = new Date(prevMonth==11?year-1:year,prevMonth,i+1);
days.push({name:''+(i+1),enabled:false,date:d,});
}
// show the days in this month (enabled) - always 28 - 31
for (let i=0;i<daysInThisMonth;i++) {
let d = new Date(year,month,i+1);
if (i==0) days.push({name:(i+1),enabled:true,date:d,});
else days.push({name:''+(i+1),enabled:true,date:d,});
//console.log('i='+i+' dt is '+d+' date() is '+d.getDate());
}
// show any days to fill up the last row (disabled) - always less than 7
for (let i=0;days.length%7;i++) {
let d = new Date((month==11?year+1:year),(month+1)%12,i+1);
if (i==0) days.push({name:(i+1),enabled:false,date:d,});
else days.push({name:''+(i+1),enabled:false,date:d,});
}
}
function next() {
month++;
if (month == 12) {
year++;
month=0;
}
}
function prev() {
if (month==0) {
month=11;
year--;
} else {
month--;
}
}
let selected: Object;
function isCurrent(date: Date) {
if (now.getDate() == date.getDate() &&
now.getMonth() == date.getMonth() &&
now.getFullYear() == date.getFullYear())
return true;
return false;
}
function set_day(day: Object) {
selected = day;
return null;
}
</script>
<div class="calendar input rounded">
<div class="month">
<ul>
<button class="prev" onclick={prev}>&#10094;</button>
<button class="next" onclick={next}>&#10095;</button>
<li>{monthNames[month]} {year}</li>
</ul>
</div>
<ul class="weekdays">
{#each headers as weekday}
<li>{weekday}</li>
{/each}
</ul>
<ul class="days">
{#each days as day}
<li>
{#if selected == day}
<button class="active {isCurrent(day.date) ? "current":""}">{day.name}</button>
{:else}
<button class="nonactive {isCurrent(day.date) ? "current":""}" onclick={() => set_day(day)}>{day.name}</button>
{/if}
</li>
{/each}
</ul>
</div>
<style>
ul {list-style-type: none;}
.calendar {
padding: 0;
}
.calendar * {
margin: 0;
}
.month {
width: 100%;
text-align: center;
align-content: center;
}
.month ul {
padding: 0;
margin: 0;
}
.month ul li {
text-transform: uppercase;
letter-spacing: 3px;
padding: 0.5rem;
}
.month ul button {
padding: 0.5rem;
}
.month .prev {
float: inline-start;
cursor: pointer;
background: none;
}
.month .next {
float: inline-end;
cursor: pointer;
background: none;
}
.weekdays {
padding: 10px 0 0 0;
}
.weekdays li {
display: inline-block;
width: 14.2%;
text-align: center;
}
.days {
padding: 10px 0;
margin: 0;
}
.days li {
list-style-type: none;
display: inline-block;
width: 14.2%;
text-align: center;
margin-bottom: 5px;
font-size: smaller;
cursor: pointer;
}
.days li .current {
height: 2em;
padding: 5px;
aspect-ratio: 1/1;
border-radius: 30%;
}
.days li .active {
height: 2em;
padding: 5px;
border-radius: 30%;
aspect-ratio: 1/1;
}
.days li .nonactive {
height: 2em;
padding: 5px;
background: none;
aspect-ratio: 1/1;
}
@media (prefers-color-scheme: light) {
.month {
background: #5C8DC0;
}
.month ul button {
color: white;
}
.month ul li {
color: white;
}
.weekdays {
background-color: #F4F4F4;
}
.weekdays li {
color: black;
}
.days {
background: #F4F4F4;
}
.days li button {
color: black;
}
.days li .active {
color: white !important;
background: #5C8DC0 !important;
}
.days li .current {
color: white !important;
background: red;
}
}
@media (prefers-color-scheme: dark) {
.month {
background: #2791FF;
}
.month ul button {
color: white;
}
.month ul li {
color: white;
}
.weekdays {
background-color: #192431;
}
.weekdays li {
color: white;
}
.days {
background: #192431;
}
.days li button {
color: white;
}
.days li .active {
color: white !important;
background: #2791FF !important;
}
.days li .current {
color: white !important;
background: red;
}
}
</style>