new design and added class function

This commit is contained in:
2025-01-28 06:19:12 +01:00
parent b3d6c7c75b
commit 8e0d7c9e8d
5 changed files with 255 additions and 100 deletions

100
Calendar.js Normal file
View File

@@ -0,0 +1,100 @@
import {getDaysInMonth, getFirstDayInMonth, getWeekdaysForLocale} from "./utils.js";
class Calendar {
constructor(calendarDiv, options = {locale: 'en-GB', firstDayInWeek: 'Sunday'}) {
this.calendarDiv = calendarDiv
this.options = options
this.date = new Date(Date.now())
// this.date = new Date(2021, 5, 12)
console.log(this.date)
this.visiableDays = 42
this.locale = this.options.locale
this.firstDayInWeek = this.options.firstDayInWeek
this.weekdays = getWeekdaysForLocale(this.locale, 'long', this.firstDayInWeek)
this.randomImgUrl = 'https://picsum.photos/1920/1080'
}
init() {
const body = document.querySelector('body')
if (body) {
body.style.backgroundImage = 'url(' + this.randomImgUrl + ')'
body.style.backgroundSize = 'cover'
body.style.backgroundRepeat = 'no-repeat'
body.style.backgroundPosition = 'center center'
}
}
render() {
const calendarHeader = this.calendarDiv.querySelector('#calendar__header')
if (calendarHeader) {
const yearDiv = calendarHeader.querySelector('#year')
const monthDiv = calendarHeader.querySelector('#month')
if (yearDiv) {
yearDiv.innerText = Intl.DateTimeFormat(this.locale, {year: 'numeric'}).format(this.date)
}
if (monthDiv) {
monthDiv.innerText = Intl.DateTimeFormat(this.locale, {month: 'long'}).format(this.date)
}
}
const calendarBody = this.calendarDiv.querySelector('#calendar__body')
if (calendarBody) {
// Weekdays
for (let i = 0; i < 7; i++) {
const weekday = document.createElement('div')
weekday.classList.add('day', 'weekday')
weekday.textContent = this.weekdays[i]
calendarBody.appendChild(weekday)
}
// Days
const currentMonthDays = getDaysInMonth(this.date.getMonth(), this.date.getFullYear())
const lastMonthDays = getDaysInMonth(this.date.getMonth() - 1, this.date.getFullYear())
const nextMonthDays = getDaysInMonth(this.date.getMonth() + 1, this.date.getFullYear())
const firstDayInMonth = getFirstDayInMonth(this.date.getMonth(), this.date.getFullYear())
let daysAtEndOfMonth = this.visiableDays - currentMonthDays - firstDayInMonth + 1
let daysAtStartOfMonth = this.visiableDays - daysAtEndOfMonth - currentMonthDays
if (daysAtStartOfMonth < 0) {
daysAtStartOfMonth = daysAtStartOfMonth + 7
daysAtEndOfMonth = daysAtEndOfMonth - 7
}
console.log(daysAtStartOfMonth, daysAtEndOfMonth)
for (let i = 0; i < this.visiableDays; i++) {
const day = document.createElement('div')
const dateSpan = document.createElement('span')
dateSpan.id = 'date'
day.classList.add('day', 'monthday')
let visibleDate = i - daysAtStartOfMonth + 1
// last month date
if (i < daysAtStartOfMonth) {
visibleDate = lastMonthDays + visibleDate
day.classList.add('dim')
}
// next month date
if (this.visiableDays - i - 1 < daysAtEndOfMonth) {
visibleDate = visibleDate - currentMonthDays
day.classList.add('dim')
}
dateSpan.innerText = visibleDate.toString()
const dayId = `${this.date.getFullYear()}${this.date.getMonth()}${this.date.getDay()}`
day.classList.add('day-' + dayId)
day.appendChild(dateSpan)
calendarBody.appendChild(day)
}
}
}
}
export default Calendar;

View File

@@ -8,19 +8,19 @@
<title>Calendar</title>
<link href="style.css" rel="stylesheet">
<link href="./style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="calendar">
<div id="calendar">
<div id="calendar__header">
<div class="year">2025</div>
<div class="year" id="year">2024</div>
<div class="actions">
<button>-</button>
<button> <</button>
<button>Today</button>
<button>+</button>
<button> ></button>
</div>
<div class="month">September</div>
<div class="month" id="month">September</div>
</div>
<div id="calendar__body">
@@ -28,6 +28,23 @@
</div>
</div>
<script src="script.js"></script>
<footer>
<div>
&copy; 2025 VikingOwl
</div>
<div style="margin: 0 .5rem">&mdash;</div>
<a href="https://somegit.dev/vikingowl/Calendar">Gitea</a>
</footer>
<script type="module">
import Calendar from "./Calendar.js";
const calendarDiv = document.querySelector("#calendar");
if (calendarDiv) {
const calendar = new Calendar(calendarDiv, {locale: 'de-DE', firstDayInWeek: 'Monday'})
calendar.init()
calendar.render()
}
</script>
</body>
</html>

View File

@@ -1,63 +0,0 @@
const WEEKDAYS = Object.freeze({
MONDAY: 0,
TUESDAY: 1,
WEDNESDAY: 2,
THURSDAY: 3,
FRIDAY: 4,
SATURDAY: 5,
SUNDAY: 6
});
const MONTHS = Object.freeze({
JANUARY: 0,
FEBRUARY: 1,
MARCH: 2,
APRIL: 3,
MAY: 4,
JUNE: 5,
JULY: 6,
AUGUST: 7,
SEPTEMBER: 8,
OCTOBER: 9,
NOVEMBER: 10,
DEZEMBER: 11
})
function generateDays() {
const visibleDays = 42 // 7 col, 5 row
const calendarBody = document.getElementById('calendar__body')
if (calendarBody) {
for (let i = 0; i < visibleDays; i++) {
const day = document.createElement('div')
day.classList.add('day')
if (i < Object.keys(WEEKDAYS).length) {
day.classList.add('weekday')
day.textContent = Object.keys(WEEKDAYS)[i]
} else {
const dayId = i % 7 + 1
day.classList.add('day-' + dayId)
}
calendarBody.appendChild(day)
}
}
}
function addCalendarDays() {
const date = new Date()
console.log(date.getMonth())
}
function setHeaderInfo(month, year) {
const yearDOM = document.querySelector('#calendar__header .year')
const monthDOM = document.querySelector('#calendar__header .month')
if (month) {
month.textContent = month
}
}
document.addEventListener('DOMContentLoaded', () => {
generateDays()
addCalendarDays()
})

127
style.css
View File

@@ -3,47 +3,65 @@
margin: 0;
padding: 0;
font-family: 'Poppins', sans-serif;
--footer-height: 3rem;
--calendar-header-height: 4rem;
}
body {
background: #000;
}
footer {
height: var(--footer-height);
background: rgba(0, 0, 0, 0.4);
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
footer a {
color: #76d714;
text-decoration: none;
}
footer a:hover {
color: #609926;
}
.container {
width: 100%;
height: 100dvh;
height: calc(100vh - var(--footer-height));
display: flex;
justify-content: center;
align-items: center;
flex: 0 1 auto;
border-radius: .4rem;
}
.calendar {
width: 900px;
height: 650px;
background: floralwhite;
border: 1px solid black;
#calendar {
width: 1080px;
height: 910px;
/* From https://css.glass */
background: rgba(62, 31, 31, 0.2);
border-radius: .4rem;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
/* ===== HEADER ===== */
#calendar__header {
background: aliceblue;
background: rgba(0, 0, 0, 0.3);
color: #fff;
display: flex;
justify-content: space-between;
height: 3rem;
}
#calendar__body {
width: 100%;
height: calc(100% - 3rem);
padding: 0.5rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: auto 1fr 1fr 1fr 1fr 1fr;
gap: 0.5rem 0.5rem;
grid-template-areas:
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . .";
height: var(--calendar-header-height);
border-radius: .4rem .4rem 0 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
#calendar__header * {
@@ -53,6 +71,10 @@
display: flex;
align-items: center;
font-size: 1.2rem;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
user-select: none;
}
#calendar__header .year {
@@ -67,7 +89,7 @@
display: flex;
justify-content: center;
align-items: center;
gap: .5rem;
gap: 1rem;
}
#calendar__header .actions button {
@@ -75,15 +97,60 @@
justify-content: center;
align-items: center;
padding: 1rem;
background: none;
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 5px;
}
.day {
background: burlywood;
/* ===== BODY ===== */
#calendar__body {
width: 100%;
height: calc(100% - var(--calendar-header-height));
padding: 1rem;
border-radius: 10px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: auto 1fr 1fr 1fr 1fr 1fr 1fr;
gap: 0.5rem 0.5rem;
grid-template-areas:
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . ."
". . . . . . .";
}
.weekday {
#calendar__body .day {
background: rgba(255, 255, 255, 0.7);
border-radius: 0.2rem;
cursor: pointer;
}
#calendar__body .dim {
background: rgba(192, 192, 192, 0.7);
}
#calendar__body .weekday {
height: 2.5rem;
display: flex;
justify-content: center;
align-items: center;
user-select: none;
cursor: initial;
text-transform: uppercase;
}
#calendar__body .monthday {
display: flex;
border: 1px solid rgba(255, 255, 255, 0.3);
}
#calendar__body .monthday #date {
margin-top: .3rem;
margin-left: .5rem;
}

34
utils.js Normal file
View File

@@ -0,0 +1,34 @@
export function getWeekdaysForLocale(localeName = 'en-GB', weekday = 'long', firstDayInWeek = 'Sunday') {
const {format} = new Intl.DateTimeFormat(localeName, {weekday})
const year = firstDayInWeek === 'Sunday' ? 2023 : firstDayInWeek === 'Monday' ? 2022 : 2023
const month = firstDayInWeek === 'Sunday' ? 4 : firstDayInWeek === 'Monday' ? 1 : 4
return [...Array(7).keys()]
.map((day) => format(new Date(Date.UTC(year, month, day))))
}
export function getFirstDayInMonth(month = 0, year = 2025) {
if (month === -1) {
month = 11
year--
}
if (month === 12) {
month = 0
year++
}
return new Date(year, month, 1).getDay()
}
export function getDaysInMonth(month = 0, year = 2025) {
month++
if (month === -1) {
month = 11
year--
}
if (month === 12) {
month = 0
year++
}
return new Date(year, month, 0).getDate()
}