diff options
Diffstat (limited to 'desk/web/calendar/month.hoon')
-rw-r--r-- | desk/web/calendar/month.hoon | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/desk/web/calendar/month.hoon b/desk/web/calendar/month.hoon new file mode 100644 index 0000000..6a7d4a1 --- /dev/null +++ b/desk/web/calendar/month.hoon @@ -0,0 +1,326 @@ +/+ sr=sortug +|_ =bowl:gall +++ css ^~ %- trip +''' +body { + font-family: system-ui, -apple-system, BlinkMacSystemFont, avenir next, avenir, + segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, + sans-serif; + margin: 10vh auto; + max-width: 120ch; + background: #fffff4; + color: #140; +} + +h1 { + font-size: 1.2rem; + font-weight: bold; +} + +input, +button { + border: none; + color: inherit; + font: inherit; +} +input { + background: none; +} +input:focus-visible { + outline: solid 1px #140; +} +button { + background: #261; + color: white; + font-weight: bold; + border-radius: 0.25rem; +} +button:hover, +button:focus-visible { + background: #483; +} + +.month-control { + display: flex; +} +.month-control h2 { + font-size: 1rem; + font-weight: bold; + margin: 0; + margin-inline-end: auto; +} +.month-control a { + flex: 0 1 6ch; + text-align: end; + font-weight: bold; + color: inherit; +} + +table { + padding: 0; + width: 100%; + height: 100%; + & th{ + opacity: 0.6; + text-align: center; + padding: 0.5rem 0; + } + & td{ + border-top: solid 1px currentColor; + min-width: 0; + min-height: 8rem; + height: 4rem; + + } +} + + +.day-weekend { + color: #c88; +} +.day-past { + color: #2423; +} + +.date { + height: 100%; + display: flex; + flex-direction: column; +} +.date ul { + padding: 0; + list-style: none; +} + +.date-num { + aspect-ratio: 1; + border-radius: 100rem; + background: #fffff4; + position: absolute; + z-index: 1; +} +.day-today .date-num { + padding: 0 0.125em; + background: #220; + color: white; +} + +.create-event-form { + flex: 1 1 auto; + margin: 0; +} +.create-event { + background: none; + color: transparent; + width: 100%; + height: 100%; + cursor: crosshair; +} +.create-event:hover, +.create-event:focus-visible { + background: #efe4; +} +.create-event:focus-visible { + color: #140; +} + +.event { + margin: 0.25rem 0.5rem; +} +.event:first-child { + margin-top: 0.5rem; +} + +.event > form { + display: flex; + margin: 0; +} + +.event-button { + position: relative; + flex: 1 1 auto; + padding: 0.25rem; + background: white; + color: #000b; + border-radius: 0.25rem; + text-wrap: nowrap; + text-overflow: ellipsis; + overflow: hidden; + text-align: start; + font-size: 0.8rem; + font-weight: bold; + text-decoration: none; +} +.event-button::after { + content: ""; + position: absolute; + inset: 0; +} +.event-button:hover::after, +.event-button:focus-visible::after { + background: #fff4; +} +.day-past .event:not(:focus-within):not(:has(dialog[open])) .event-button { + opacity: 0.4; +} + +.event dialog { + inset: unset; + margin-top: 0.3rem; + padding: 0.75rem; + background: white; + border: solid 1px #ceb; + box-shadow: 0 0.25rem 0.5rem #0301, 0 0rem 2rem #0301; + z-index: 9999; +} +.event dialog::after { + content: ''; + position: absolute; + left: 0.4rem; + top: calc(-0.3rem - 2px); + width: 0.6rem; + height: 0.6rem; + transform: rotate(45deg); + background: inherit; + border: inherit; + border-right: none; + border-bottom: none; +} + +.event dialog form { + margin: 0; + display: flex; + flex-direction: column; + gap: 0.5rem; +} +.event-dialog-row { + display: flex; + gap: 0.5rem; +} + +.event input[type="text"] { + border-bottom: solid 1px currentColor; + max-width: 15ch; +} + +.delete-button { + background: #820; +} +.delete-button:hover, +.delete-button:focus-visible { + background: #a42; +} +''' +++ html +|= time=@da ^- manx +=, chrono:userlib +=/ dat (yore time) +=+ [[a y] m [d h mm s f]]=dat +=/ mon %+ snag (dec m) mon:yu +=/ nmon %+ snag m mon:yu +=/ pmon =/ ind ?: .=(1 m) 11 (sub m 2) + %+ snag ind mon:yu +=/ year (scow:parsing:sr %ud y) +=/ nyear (scow:parsing:sr %ud +(y)) +=/ pyear (scow:parsing:sr %ud (dec y)) +=/ weekday %+ snag (daws dat) wik:yu +:: =/ weeknames (snoc +.wik:yu -.wik:yu) +=/ weeknames wik:yu +=/ first-of-month dat(d.t 1) +=/ month-starts-at (daws first-of-month) +;html +;head; +;body +;style: {css} + ;div#month.month + ;div.month-control + ;h2.current-month:"{mon} {year}" + ;a/"":"<- {pmon}" + ;a/"":"{nmon} ->" + == + ;table + ;tr + ;* %+ turn weeknames |= t=tape ;th.wday-name:"{t}" + == + ;* %+ turn (get-nums time) |= l=(list date) + ;tr + ;* %+ turn l cell + == + == + == +== +== ++$ row (list date) +++ get-nums +|= =time ^- (list row) +=, chrono:userlib + =/ =date (yore time) + =+ [[a y] m [d h mm s f]]=date + =/ first-of-month date(d.t 1) + =/ first-day (year first-of-month) + =/ month-start (daws first-of-month) + ~& month-start=month-start + =| l=(list row) + =| i=@ud + |- + =/ dat + ?: (gth month-start i) + =/ diff (sub month-start i) + =/ back (sub first-day (mul ~d1 diff)) + (yore back) + + =/ curr (sub i month-start) + (yore (add first-day (mul ~d1 curr))) + :: =/ nm m.added + :: =/ to-next-month (gth nm m) + :: ?: to-next-month added curr + + ?~ l $(l [~[dat] l], i +(i)) + + ?. .=(0 (mod i 7)) + =. i.l [dat i.l] + $(i +(i)) + + =. i.l (flop i.l) + =/ curr (sub i month-start) + =/ added (yore (add first-day (mul ~d1 curr))) + =/ nm m.added + =/ to-next-month (gth nm m) + ?: to-next-month (flop l) + =/ nrow ~[added] + + $(l [nrow l], i +(i)) + :: exit-condition + +++ cell +|= =date ^- manx + =/ [faded=? today=?] [.n .n] + =/ nums (scow %ud d.t.date) + ?: faded + :: + ;td.faded + ;div:"{nums}" + == + ?: today + ;td.today + ;div:"{nums}" + == + :: + ;td + ;div:"{nums}" + == + :: +++ get-num +|= [feira=@ud =time] ^- @ud +=, chrono:userlib + =/ date (yore time) + =/ first-of-month date(d.t 1) + =/ month-starts-at (daws first-of-month) + ?: (lth feira month-starts-at) + =/ diff (sub month-starts-at feira) + =/ back (sub time (mul ~d1 diff)) + d.t:(yore back) + :: e.g. month starts in day 3 (thu) and we're in day 4 (fri) + =/ diff (sub feira month-starts-at) + +(diff) +-- |