Skip to content

Commit

Permalink
Merge pull request #43 from manuelsanchezweb/feature/addEditLogic
Browse files Browse the repository at this point in the history
Add edit functionality
  • Loading branch information
manuelsanchez2 authored Jun 4, 2024
2 parents 6e33031 + 4f68fff commit 7d07d01
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 64 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "collabender",
"version": "0.7.6",
"version": "0.8.2",
"description": "App with Routing built-in (recommended)",
"engines": {
"node": ">=20.0.0"
Expand Down
66 changes: 51 additions & 15 deletions src/components/appointment-modal/add-appointment-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,59 @@
import { $, type Signal, component$, useOn } from '@builder.io/qwik'
import {
$,
type Signal,
component$,
useOn,
useSignal,
useVisibleTask$,
} from '@builder.io/qwik'
import { Form } from '@builder.io/qwik-city'
import { APP_CATEGORIES } from '~/config'
import { useAddAppointment } from '~/global'

export function getDayFromUrl() {
const url = new URL(window.location.href)
const day = url.searchParams.get('day')

return day ? day : new Date().toISOString().split('T')[0]
}

export const AddAppointmentModal = component$(
({
isAddAppointmentModalOpen,

}: {
isAddAppointmentModalOpen: Signal<boolean>

}) => {
const action = useAddAppointment()
// Default date for the date input comes form ?day on the url or today
const url = new URL(window.location.href)
const day = url.searchParams.get('day')
const defaultOptionForDate = useSignal<string>()

// eslint-disable-next-line qwik/no-use-visible-task
useVisibleTask$(() => {
defaultOptionForDate.value = getDayFromUrl()
})

const fullDayRef = useSignal<HTMLInputElement>()
// eslint-disable-next-line qwik/no-use-visible-task
useVisibleTask$(({ track }) => {
track(() =>
fullDayRef.value?.addEventListener('change', () => {
const timeStart = document.getElementById(
'time_start'
) as HTMLInputElement
const timeEnd = document.getElementById(
'time_end'
) as HTMLInputElement

const defaultOptionForDate = day
? day
: new Date().toISOString().split('T')[0]
if (fullDayRef.value?.checked) {
// make the inputs disabled
timeStart.disabled = true
timeEnd.disabled = true
} else {
timeStart.disabled = false
timeEnd.disabled = false
}
})
)
})

useOn(
'click',
Expand Down Expand Up @@ -64,7 +99,7 @@ export const AddAppointmentModal = component$(
</label>
<input
placeholder="Meeting with John Doe"
value={ ''}
value={''}
required
name="title"
id="title"
Expand All @@ -87,7 +122,7 @@ export const AddAppointmentModal = component$(
id="date"
type="date"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
defaultValue={defaultOptionForDate }
defaultValue={defaultOptionForDate.value}
/>
</div>

Expand All @@ -101,11 +136,11 @@ export const AddAppointmentModal = component$(
Starts at
</label>
<input
value={'8:00' }
value={'8:00'}
name="time_start"
id="time_start"
type="text"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2 disabled:opacity-85 disabled:cursor-not-allowed disabled:text-grayBrand"
/>
</div>
<div class="flex flex-col gap-2 mt-2 md:mt-8 flex-1">
Expand All @@ -116,11 +151,11 @@ export const AddAppointmentModal = component$(
Ends at
</label>
<input
value={'9:00' }
value={'9:00'}
name="time_end"
id="time_end"
type="text"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2 disabled:opacity-85 disabled:cursor-not-allowed disabled:text-grayBrand"
/>
</div>
</div>
Expand All @@ -131,6 +166,7 @@ export const AddAppointmentModal = component$(
Is it a full day event?
</label>
<input
ref={fullDayRef}
name="full_day"
id="full_day"
type="checkbox"
Expand Down
84 changes: 67 additions & 17 deletions src/components/appointment-modal/edit-appointment-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,56 @@
import { $, type Signal, component$, useOn } from '@builder.io/qwik'
import {
$,
type Signal,
component$,
useOn,
useSignal,
useVisibleTask$,
} from '@builder.io/qwik'
import { Form } from '@builder.io/qwik-city'
import { APP_CATEGORIES } from '~/config'
import { useAddAppointment } from '~/global'
import { useEditAppointment } from '~/global'
import { IconManager } from '~/icons/icon-manager'
import { type IAppointment } from '~/types/types'

export const EditAppointmentModal = component$(
({
isEditAppointmentModalOpen,
editModalData,

}: {
isEditAppointmentModalOpen: Signal<boolean>
editModalData: any
editModalData: IAppointment
}) => {
const action = useAddAppointment()
const action = useEditAppointment()
const fullDayRef = useSignal<HTMLInputElement>()
// eslint-disable-next-line qwik/no-use-visible-task
useVisibleTask$(({ track }) => {
const timeStart = document.getElementById(
'time_start'
) as HTMLInputElement
const timeEnd = document.getElementById('time_end') as HTMLInputElement

if (fullDayRef.value?.checked) {
// make the inputs disabled
timeStart.disabled = true
timeEnd.disabled = true
} else {
timeStart.disabled = false
timeEnd.disabled = false
}

track(() =>
fullDayRef.value?.addEventListener('change', () => {
if (fullDayRef.value?.checked) {
// make the inputs disabled
timeStart.disabled = true
timeEnd.disabled = true
} else {
timeStart.disabled = false
timeEnd.disabled = false
}
})
)
})

useOn(
'click',
Expand All @@ -32,6 +70,9 @@ export const EditAppointmentModal = component$(
$(() => {
isEditAppointmentModalOpen.value = false
document.body.style.overflow = 'auto'
// make a fake push window to the same url we are in
// TODO: had to make it reload the page to get the last changes
window.location.reload()
})
)

Expand Down Expand Up @@ -81,7 +122,7 @@ export const EditAppointmentModal = component$(
id="date"
type="date"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
value={editModalData.date }
value={editModalData.date}
/>
</div>

Expand All @@ -95,11 +136,11 @@ export const EditAppointmentModal = component$(
Starts at
</label>
<input
value={editModalData.start}
value={editModalData.time_start}
name="time_start"
id="time_start"
type="text"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2 disabled:opacity-85 disabled:cursor-not-allowed disabled:text-grayBrand"
/>
</div>
<div class="flex flex-col gap-2 mt-2 md:mt-8 flex-1">
Expand All @@ -110,11 +151,11 @@ export const EditAppointmentModal = component$(
Ends at
</label>
<input
value={editModalData.end}
value={editModalData.time_end}
name="time_end"
id="time_end"
type="text"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2"
class="w-full border border-grayBrandMedium rounded-md px-4 py-2 disabled:opacity-85 disabled:cursor-not-allowed disabled:text-grayBrand"
/>
</div>
</div>
Expand All @@ -125,10 +166,11 @@ export const EditAppointmentModal = component$(
Is it a full day event?
</label>
<input
ref={fullDayRef}
name="full_day"
id="full_day"
type="checkbox"
checked={editModalData.fullDay}
checked={editModalData.full_day === 1}
class="w-3 h-3 accent-primary"
/>
</div>
Expand Down Expand Up @@ -156,14 +198,22 @@ export const EditAppointmentModal = component$(
</select>
</div>

<input
hidden
type="number"
id="id"
name="id"
value={editModalData.id}
/>

<footer class="mt-5">
<div class="flex justify-between gap-4 items-center">
<button
class="btn flex justify-center items-center gap-2 bg-grayBrandLight text-black mt-2 md:mt-8"

>

Delete Event
<button class="btn flex justify-center items-center gap-2 bg-grayBrandLight text-black mt-2 md:mt-8 group">
<IconManager
icon="remove"
classCustom="w-6 h-auto text-primary group-hover:text-white group-focus:text-white"
/>
<span>Delete Event</span>
</button>
<button
class="btn bg-grayBrandLight text-black mt-2 md:mt-8"
Expand Down
4 changes: 2 additions & 2 deletions src/components/views/list-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ export const ListView = component$(
appointments,
users,
isEditAppointmentModalOpen,
editModalData
editModalData,
}: {
appointments: Array<IAppointment>
users: Array<IUser>
isEditAppointmentModalOpen: Signal<boolean>
editModalData: any
editModalData: IAppointment
}) => {
const futureAppointments = useComputed$(() => {
if (appointments.length === 0) return []
Expand Down
24 changes: 14 additions & 10 deletions src/components/views/task-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,20 @@ export default component$((props: IProps) => {
</div>

{props.showEdit ? (
<button class="flex justify-end"
onClick$={$(() =>{props.isEditAppointmentModalOpen.value = true
props.editModalData.id = props.id
props.editModalData.title = props.title
props.editModalData.date = props.date
props.editModalData.start = props.time_start
props.editModalData.end = props.time_end
props.editModalData.fullDay = props.full_day
props.editModalData.category = props.category
}) }>
<button
class="flex justify-end"
onClick$={$(() => {
// TODO: // make this more beautiful
props.isEditAppointmentModalOpen.value = true
props.editModalData.id = props.id
props.editModalData.title = props.title
props.editModalData.date = props.date
props.editModalData.time_start = props.time_start
props.editModalData.time_end = props.time_end
props.editModalData.full_day = props.full_day
props.editModalData.category = props.category
})}
>
<IconManager icon="edit" classCustom="h-12 w-12" />
</button>
) : (
Expand Down
10 changes: 10 additions & 0 deletions src/db/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,13 @@ export async function createAppointment(data: InsertAppointment) {
export async function deleteAppointment(id: number) {
await db.delete(appointmentsTable).where(eq(appointmentsTable.id, id))
}

/**
* Update an appointment by its ID
*/
export async function updateAppointment(id: number, data: InsertAppointment) {
await db
.update(appointmentsTable)
.set(data)
.where(eq(appointmentsTable.id, id))
}
35 changes: 29 additions & 6 deletions src/global/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { globalAction$, } from '@builder.io/qwik-city'
import { globalAction$ } from '@builder.io/qwik-city'
import { APP_USERS } from '~/config'

import { db } from '~/db/db'
import * as schema from '~/db/schema'
import { createAppointment, updateAppointment } from '~/db/queries'
import { type IUser } from '~/types/types'
import { getIdByAuthorName, getListAvailablePasswords } from '~/utils/functions'

Expand Down Expand Up @@ -49,7 +48,6 @@ export const useSubmitPassword = globalAction$(async (data, { cookie }) => {
export const useAddAppointment = globalAction$(async (data, { cookie }) => {
const isFullDay = data['full_day'] === 'on' ? 1 : 0


const authorName = cookie.get('collabender-user')?.value
const authorId = getIdByAuthorName(authorName as string, APP_USERS)

Expand All @@ -64,9 +62,34 @@ export const useAddAppointment = globalAction$(async (data, { cookie }) => {
created_by: authorId,
}


await db.insert(schema.appointmentsTable).values(appointment)
await createAppointment(appointment)

return {
success: true,
}
})

/**
* Action to add an appointment
*/
export const useEditAppointment = globalAction$(async (data, { cookie }) => {
const isFullDay = data['full_day'] === 'on' ? 1 : 0

const authorName = cookie.get('collabender-user')?.value
const authorId = getIdByAuthorName(authorName as string, APP_USERS)

// TODO: Add validation for the date and time with zod
const newAppointment = {
title: data['title'] as string,
date: data['date'] as string,
time_start: data['time_start'] as string,
time_end: data['time_end'] as string,
full_day: isFullDay,
category: data['category'] as string,
created_by: authorId,
}

await updateAppointment(data['id'] as number, newAppointment)
return {
success: true,
}
Expand Down
Loading

0 comments on commit 7d07d01

Please sign in to comment.