Skip to content

Commit

Permalink
code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ewrogers committed Sep 27, 2023
1 parent 5927506 commit 7a06d1e
Show file tree
Hide file tree
Showing 15 changed files with 66 additions and 71 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ bun run seed
bun run dev
```

Then you can view the application at [http://localhost:3000](http://localhost:3000).

**NOTE**: You only need to run `bun seed` once, as it will create the database and seed it with some example data.

## Why this stack?
Expand Down
6 changes: 3 additions & 3 deletions src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ interface SiteData {

const DEFAULT_TITLE = 'Hyper Calendar'

const Layout: FC<SiteData> = (props) => {
const Layout: FC<SiteData> = ({ title, children }) => {
return (
<html>
<head>
<title>{props.title ?? DEFAULT_TITLE}</title>
<title>{title ?? DEFAULT_TITLE}</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="stylesheet" href="/styles/global.css" />
<link rel="stylesheet" href="/styles/calendar.css" />
Expand All @@ -26,7 +26,7 @@ const Layout: FC<SiteData> = (props) => {
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body hx-boost="true">
<main>{props.children}</main>
<main>{children}</main>
<script src="js/htmx.min.js"></script>
<script src="js/hyperscript.min.js"></script>
</body>
Expand Down
14 changes: 1 addition & 13 deletions src/components/calendar/EventCard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC } from 'hono/jsx'
import { CalendarEvent } from '@/models/event'
import { formatTime } from '@/utils/dates'

export interface EventCardProps {
event: CalendarEvent
Expand Down Expand Up @@ -27,16 +28,3 @@ const EventCard: FC<EventCardProps> = ({ event }) => {
}

export default EventCard

function formatTime(hour?: number, minute?: number) {
hour = hour ?? 0
minute = minute ?? 0

const hourString = hour != 12 ? (hour % 12).toString() : '12'
const minuteString = minute.toString().padStart(2, '0')
const amPm = hour < 12 ? 'AM' : 'PM'

return minute > 0
? `${hourString}:${minuteString} ${amPm}`
: `${hourString} ${amPm}`
}
19 changes: 2 additions & 17 deletions src/components/calendar/WeekCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CalendarEvent } from '@/models/event'
import WeekNavigation from '@/components/calendar/WeekNavigation'
import DayCalendar from '@/components/calendar/DayCalendar'
import { mapRange } from '@/utils/arrays'
import { formatHour } from '@/utils/dates'

export interface WeekCalendarProps {
startDate: Date
Expand Down Expand Up @@ -62,9 +63,7 @@ const WeekCalendar: FC<WeekCalendarProps> = ({ startDate, events }) => {
mapRange(24, (hour) => {
return (
<div class="time-legend-cell">
<label class="time-legend-label">
{formatHourString(hour)}
</label>
<label class="time-legend-label">{formatHour(hour)}</label>
</div>
)
})
Expand Down Expand Up @@ -105,17 +104,3 @@ const WeekCalendar: FC<WeekCalendarProps> = ({ startDate, events }) => {
}

export default WeekCalendar

function formatHourString(hour: number) {
hour %= 24

if (hour === 0) {
return '12 AM'
} else if (hour < 12) {
return `${hour} AM`
} else if (hour === 12) {
return 'Noon'
} else {
return `${hour - 12} PM`
}
}
6 changes: 3 additions & 3 deletions src/components/calendar/WeekNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ export interface WeekNavigationProps {
nextWeek: Date
}

const WeekNavigation: FC<WeekNavigationProps> = (props) => {
const WeekNavigation: FC<WeekNavigationProps> = ({ prevWeek, nextWeek }) => {
return (
<div class="toolbar">
<button
id="prev-week-btn"
class="toolbar-button"
hx-get={`/events?date=${format(props.prevWeek, 'yyyy-MM-dd')}`}
hx-get={`/events?date=${format(prevWeek, 'yyyy-MM-dd')}`}
hx-target="#calendar"
hx-push-url="true"
>
Expand All @@ -34,7 +34,7 @@ const WeekNavigation: FC<WeekNavigationProps> = (props) => {
<button
id="next-week-btn"
class="toolbar-button"
hx-get={`/events?date=${format(props.nextWeek, 'yyyy-MM-dd')}`}
hx-get={`/events?date=${format(nextWeek, 'yyyy-MM-dd')}`}
hx-target="#calendar"
hx-push-url="true"
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/forms/AddEventForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export interface AddEventProps {
initialDate?: Date
}

const AddEventForm: FC<AddEventProps> = (props) => {
const initialDate = props.initialDate ?? new Date()
const AddEventForm: FC<AddEventProps> = ({ initialDate }) => {
initialDate ??= new Date()

const initialDayString = format(initialDate, 'yyyy-MM-dd')
const initialHour = initialDate.getHours() % 12
Expand Down
15 changes: 8 additions & 7 deletions src/components/forms/EditEventForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ export interface EditEventProps {
event: CalendarEvent
}

const EditEventForm: FC<EditEventProps> = (props) => {
const dayString = format(props.event.startDay, 'yyyy-MM-dd')
const { startHour, startMinute, duration, color } = props.event
const EditEventForm: FC<EditEventProps> = ({ event }) => {
const { startDay, startHour, startMinute, duration, color } = event

const dayString = format(startDay, 'yyyy-MM-dd')
const hour12 = startHour % 12

return (
Expand All @@ -26,7 +27,7 @@ const EditEventForm: FC<EditEventProps> = (props) => {
placeholder="Event Name"
required
autofocus
value={props.event.name}
value={event.name}
_="on load call me.select()"
/>
</section>
Expand Down Expand Up @@ -138,7 +139,7 @@ const EditEventForm: FC<EditEventProps> = (props) => {
id="all-day"
name="allDay"
type="checkbox"
checked={props.event.allDay}
checked={event.allDay}
_="on load or change
if me.checked
repeat in [#start-hour, #start-minute, #am-pm, #duration]
Expand Down Expand Up @@ -215,7 +216,7 @@ const EditEventForm: FC<EditEventProps> = (props) => {
<button
id="edit-btn"
type="submit"
hx-put={`/events/${props.event.id}`}
hx-put={`/events/${event.id}`}
_="on click toggle @disabled and #delete-btn.disabled until htmx:afterRequest"
>
<span>Save Changes</span>
Expand All @@ -224,7 +225,7 @@ const EditEventForm: FC<EditEventProps> = (props) => {
<button
id="delete-btn"
class="form-delete-button"
hx-delete={`/events/${props.event.id}`}
hx-delete={`/events/${event.id}`}
_="on click
toggle @disabled and #edit-btn.disabled until htmx:afterRequest"
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/modals/DialogModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FC } from 'hono/jsx'

const DialogModal: FC<{}> = (props) => {
const DialogModal: FC<{}> = ({ children }) => {
return (
<div
id="modal"
Expand All @@ -10,7 +10,7 @@ const DialogModal: FC<{}> = (props) => {
class="modal-underlay"
_="on click or keyup[key=='Escape'] from window trigger closeModal"
/>
<div class="modal-content">{props.children}</div>
<div class="modal-content">{children}</div>
</div>
)
}
Expand Down
14 changes: 6 additions & 8 deletions src/handlers/create-event.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { HandlerContext } from '@/types'
import { UpsertCalendarEvent } from '@/models/event'
import { parseShortDate } from '@/utils/dates'
import { CalendarEventChanges } from '@/models/event'
import EventCard from '@/components/calendar/EventCard'

const TRUE_REGEX = /^(true|1|on|yes)$/i
const PM_REGEX = /^(pm|p)$/i
import { parseShortDate } from '@/utils/dates'
import { isPmString, isTrueString } from '@/utils/strings'

export default async function createEvent(c: HandlerContext) {
const body = await c.req.formData()

const allDay = TRUE_REGEX.test(body.get('allDay') as string)
const allDay = isTrueString(body.get('allDay') as string)

const props: UpsertCalendarEvent = {
const props: CalendarEventChanges = {
name: body.get('name') as string,
startDay: parseShortDate(body.get('startDay') as string)!,
startHour: allDay ? 0 : Number(body.get('startHour')),
Expand All @@ -21,7 +19,7 @@ export default async function createEvent(c: HandlerContext) {
color: body.get('color') as string,
}

const isPastMeridiem = PM_REGEX.test(body.get('amPm') as string)
const isPastMeridiem = isPmString(body.get('amPm') as string)
if (isPastMeridiem && props.startHour < 12) {
props.startHour += 12
}
Expand Down
2 changes: 0 additions & 2 deletions src/handlers/get-events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ export default async function getEvents(c: HandlerContext) {
const { eventService } = c.var
const events = await eventService.findBetween(startDate, endDate)

console.log(`RESULTS> Count = ${events.length}`)

// Triggered by htmx, only return the updated calendar view
if (trigger) {
return c.html(<WeekCalendar startDate={startDate} events={events} />)
Expand Down
12 changes: 5 additions & 7 deletions src/handlers/update-event.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { HandlerContext } from '@/types'
import { UpsertCalendarEvent } from '@/models/event'
import { CalendarEventChanges } from '@/models/event'
import { parseShortDate } from '@/utils/dates'

const TRUE_REGEX = /^(true|1|on|yes)$/i
const PM_REGEX = /^(pm|p)$/i
import { isPmString, isTrueString } from '@/utils/strings'

export default async function updateEvent(c: HandlerContext) {
const eventId = Number(c.req.param('id'))
Expand All @@ -12,9 +10,9 @@ export default async function updateEvent(c: HandlerContext) {
}

const body = await c.req.formData()
const allDay = TRUE_REGEX.test(body.get('allDay') as string)
const allDay = isTrueString(body.get('allDay') as string)

const props: UpsertCalendarEvent = {
const props: CalendarEventChanges = {
name: body.get('name') as string,
startDay: parseShortDate(body.get('startDay') as string)!,
startHour: allDay ? 0 : Number(body.get('startHour')),
Expand All @@ -24,7 +22,7 @@ export default async function updateEvent(c: HandlerContext) {
color: body.get('color') as string,
}

const isPastMeridiem = PM_REGEX.test(body.get('amPm') as string)
const isPastMeridiem = isPmString(body.get('amPm') as string)
if (isPastMeridiem && props.startHour && props.startHour < 12) {
props.startHour += 12
}
Expand Down
2 changes: 1 addition & 1 deletion src/models/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type CalendarEvent = {
updatedAt: Date
}

export type UpsertCalendarEvent = Omit<
export type CalendarEventChanges = Omit<
CalendarEvent,
'id' | 'createdAt' | 'updatedAt'
>
14 changes: 8 additions & 6 deletions src/services/event-service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Database } from 'bun:sqlite'
import format from 'date-fns/format'
import { CalendarEvent, UpsertCalendarEvent } from '@/models/event'
import { CalendarEvent, CalendarEventChanges } from '@/models/event'
import { parseShortDate } from '@/utils/dates'

export interface IEventService {
findById(id: number): Promise<CalendarEvent | null>
findBetween(startDate: Date, endDate: Date): Promise<CalendarEvent[]>
create(event: UpsertCalendarEvent): Promise<CalendarEvent>
update(id: number, event: UpsertCalendarEvent): Promise<boolean>
create(event: CalendarEventChanges): Promise<CalendarEvent>
update(id: number, event: CalendarEventChanges): Promise<boolean>
delete(id: number): Promise<boolean>
}

Expand All @@ -20,10 +20,10 @@ export class SqlEventService implements IEventService {

findById(id: number): Promise<CalendarEvent | null> {
const query = this._db.query(`SELECT * FROM events WHERE id = $id`)

const result: any = query.get({ $id: id })

logQuery(query)
console.log(`RESULTS> Count = ${result ? '1' : '0'}`)

if (!result) {
return Promise.resolve(null)
Expand All @@ -49,10 +49,12 @@ export class SqlEventService implements IEventService {
// @ts-ignore
const events = results.map(mapToCalendarEvent)

console.log(`RESULTS> Count = ${events.length}`)

return Promise.resolve(events)
}

create(event: UpsertCalendarEvent): Promise<CalendarEvent> {
create(event: CalendarEventChanges): Promise<CalendarEvent> {
const query = this._db.query(
`
INSERT INTO events (
Expand Down Expand Up @@ -104,7 +106,7 @@ export class SqlEventService implements IEventService {
})
}

update(id: number, event: UpsertCalendarEvent): Promise<boolean> {
update(id: number, event: CalendarEventChanges): Promise<boolean> {
const query = this._db.query(
`
UPDATE events SET
Expand Down
13 changes: 13 additions & 0 deletions src/utils/dates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,16 @@ export function formatHour(hour: number): string {
return `${hour - 12} PM`
}
}

export function formatTime(hour?: number, minute?: number) {
hour = hour ?? 0
minute = minute ?? 0

const hourString = hour != 12 ? (hour % 12).toString() : '12'
const minuteString = minute.toString().padStart(2, '0')
const amPm = hour < 12 ? 'AM' : 'PM'

return minute > 0
? `${hourString}:${minuteString} ${amPm}`
: `${hourString} ${amPm}`
}
10 changes: 10 additions & 0 deletions src/utils/strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const TRUE_REGEX = /^(true|1|on|yes)$/i
const PM_REGEX = /^(pm|p)$/i

export function isTrueString(value?: string): boolean {
return value != null && TRUE_REGEX.test(value)
}

export function isPmString(value?: string): boolean {
return value != null && PM_REGEX.test(value)
}

0 comments on commit 7a06d1e

Please sign in to comment.