Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions app/components/event/Tile.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<script setup lang="ts">
import { computed } from 'vue'

defineEmits(['add'])
defineProps<{
title: string
const props = defineProps<{
title?: string
subtitle?: string
buttonType?: 'plus' | 'arrow'
eventId?: string
}>()

const iconName = computed(
() => props.buttonType === 'arrow' ? 'i-heroicons-arrow-right-20-solid' : 'i-heroicons-plus'
)
</script>
<template>
<div
Expand All @@ -24,13 +32,13 @@ defineProps<{
</p>
</div>

<!-- Plus button -->
<!-- Action button -->
<button
class="grid place-items-center rounded-xl h-9 w-9 border border-gray-800/70 dark:border-gray-700/60
hover:bg-gray-100/70 dark:hover:bg-gray-800/70 transition"
@click="$emit('add')"
@click="$emit('add', props.eventId)"
>
<UIcon name="i-heroicons-plus" class="w-5 h-5" />
<UIcon :name="iconName" class="w-5 h-5" />
</button>
</div>
</template>
31 changes: 24 additions & 7 deletions app/pages/events/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const loading = ref(true)
const notFound = ref(false)

const isEditMode = ref(false)
const editForm = ref({})
const editForm = ref({ mobileClinic: false })

//placeholder until we implement auth
const admin = true;
Expand All @@ -26,7 +26,7 @@ onMounted(async () => {
// Fetch event from your backend API
event.value = await $fetch(`/api/events/${eventId}`)

editForm.value = { ...event.value }
editForm.value = { ...event.value, mobileClinic: Boolean(event.value?.mobileClinicId) }

console.log('✅ Event loaded:', event.value)
loading.value = false
Expand Down Expand Up @@ -71,7 +71,7 @@ const zoom = 15
function toggleEditMode() {
if (isEditMode.value) {
// Cancel editing - reset form to original event data
editForm.value = { ...event.value }
editForm.value = { ...event.value, mobileClinic: Boolean(event.value?.mobileClinicId) }
}
isEditMode.value = !isEditMode.value
}
Expand All @@ -82,7 +82,7 @@ async function saveChanges() {
console.log('💾 Saving changes...')

// Update event via API
await $fetch(`/api/events/${event.value.id}`, {
const updatedEvent = await $fetch(`/api/events/${event.value.id}`, {
method: 'PATCH',
body: {
title: editForm.value.title,
Expand All @@ -92,7 +92,8 @@ async function saveChanges() {
startTime: new Date(editForm.value.startTime).toISOString(),
endTime: new Date(editForm.value.endTime).toISOString(),
allowVolunteers: editForm.value.allowVolunteers,
allowAttendees: editForm.value.allowAttendees
allowAttendees: editForm.value.allowAttendees,
mobileClinic: editForm.value.mobileClinic
}
})

Expand Down Expand Up @@ -439,7 +440,7 @@ const backNavigate = computed(() => {
<UIcon name="i-lucide-users" class="w-5 h-5 text-brand4" />
<div>
<p class="font-medium text-gray-900">Volunteer Sign-ups</p>
<p class="text-sm text-gray-500">Allow people to volunteer for this event</p>
<p class="text-sm text-gray-500">Allow people to volunteer for this event?</p>
</div>
</div>
<label class="flex items-center gap-2 cursor-pointer">
Expand All @@ -452,7 +453,7 @@ const backNavigate = computed(() => {
<UIcon name="i-lucide-ticket" class="w-5 h-5 text-brand4" />
<div>
<p class="font-medium text-gray-900">Attendee Registration</p>
<p class="text-sm text-gray-500">Allow people to register as attendees</p>
<p class="text-sm text-gray-500">Allow people to register as attendees?</p>
</div>
</div>
<label v-if="isEditMode" class="flex items-center gap-2 cursor-pointer">
Expand All @@ -462,6 +463,22 @@ const backNavigate = computed(() => {
<UCheckbox :model-value="event.allowAttendees" color="brand4" disabled />
</label>
</div>

<div class="flex items-center justify-between p-4 bg-gray-50 rounded-xl">
<div class="flex items-center gap-3">
<UIcon name="i-lucide-ticket" class="w-5 h-5 text-brand4" />
<div>
<p class="font-medium text-gray-900">Mobile Clinic</p>
<p class="text-sm text-gray-500">Will this event have a mobile clinic?</p>
</div>
</div>
<label v-if="isEditMode" class="flex items-center gap-2 cursor-pointer">
<UCheckbox v-model="editForm.mobileClinic" color="brand4" />
</label>
<label v-else class="flex items-center gap-2">
<UCheckbox :model-value="Boolean(event.mobileClinicId)" color="brand4" disabled />
</label>
</div>
</div>
</div>

Expand Down
37 changes: 31 additions & 6 deletions app/pages/events/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ const tz = getLocalTimeZone()

const value = ref<DateValue>(new CalendarDate(2022, 2, 3))

const eventClick = () => {
navigateTo('/events/event1')
const eventClick = (id?: string) => {
if (!id) return
navigateTo(`/events/${id}`)
}

const isDateDisabled = (d: DateValue) =>
Expand Down Expand Up @@ -39,10 +40,34 @@ const isDateDisabled = (d: DateValue) =>


<div class="space-y-4">
<EventTile :onclick="eventClick"/>
<EventTile />
<EventTile />
<EventTile />
<EventTile
title="Community Health Fair"
subtitle="Tap to view details"
buttonType="arrow"
eventId="event1"
@add="eventClick"
/>
<EventTile
title="Support Workshop"
subtitle="Tap to view details"
buttonType="arrow"
eventId="event2"
@add="eventClick"
/>
<EventTile
title="Family Clinic"
subtitle="Tap to view details"
buttonType="arrow"
eventId="event3"
@add="eventClick"
/>
<EventTile
title="Wellness Check"
subtitle="Tap to view details"
buttonType="arrow"
eventId="event4"
@add="eventClick"
/>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/pages/events/manage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function getEventDate(event) {

<div class="flex flex-col text-left pointer-events-none">
<p class="text-gray-800 font-semibold">{{ event.title }}</p>
<p class="text-gray-500 text-sm">{{ event.location }}</p>
<p class="text-gray-500 text-sm">{{ event.location.address }}</p>
<p class="text-gray-400 text-xs">{{ getEventDate(event) }}</p>
</div>
</button>
Expand Down
114 changes: 78 additions & 36 deletions app/pages/mobileClinic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,26 @@
:snap-points="snapPoints"
>
<template #content>
<EventTile
v-if ="pastEvents.length === 0"
class="w-11/12 mx-auto my-4 cursor-pointer"
title="No past events"
subtitle="Check back later for updates!"

/>
<EventTile
v-for="event in pastEvents"
v-else
:key="event.id"
class="w-11/12 mx-auto my-4 cursor-pointer"
:title="event.title"
:subtitle="new Date(event.startTime).toLocaleString()"
@click="() => mapAdjust(event)"
/>
<div class="max-h-[55vh] overflow-y-auto space-y-2 px-2 pb-4">
<EventTile
v-if="upcomingEvents.length === 0"
class="w-11/12 mx-auto my-4 cursor-pointer"
title="No upcoming events"
subtitle="Check back later for updates!"
/>
<EventTile
v-for="event in upcomingEvents"
v-else
:key="event.id"
class="w-11/12 mx-auto my-4 cursor-pointer"
:title="event.title"
:subtitle="new Date(event.startTime).toLocaleString()"
button-type="arrow"
:eventId="event.eventId"
@add="eventClick"
@click="handleTileClick(event)"
/>
</div>
</template>
</UDrawer>
</div>
Expand All @@ -49,48 +53,86 @@ const zoom = ref(15)
// Pixel values
const snapPoints = ["230", "340", "450"]

const pastEvents = ref([])
const upcomingEvents = ref([])

// Load all events from API on mount

// Load both events and mobile clinic schedule on mount
onMounted(async () => {
console.log('✅ Page mounted - Loading events from API')
console.log('✅ Page mounted - Loading events and mobile clinic schedule')
await loadEvents()
await loadMobileClinicSchedule()
})

const eventClick = (id) => {
if (!id) return
navigateTo(`/events/${id}`)
}

const handleTileClick = (event) => {
if (!event?.location) return
mapAdjust(event.location)
}

const setUpcomingItems = (items) => {
upcomingEvents.value = items
.map((item) => ({
...item,
subtitle: item.subtitle ?? new Date(item.startTime).toLocaleString(),
}))
.sort((a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime())
}

async function loadMobileClinicSchedule() {
try {
const schedule = await $fetch('/api/mobile-clinic/schedule')
console.log('✅ Loaded mobile clinic schedule:', schedule)

const scheduleItems = schedule.map((item) => ({
...item,
title: `Mobile Clinic`,
eventId: null,
}))

setUpcomingItems([...upcomingEvents.value, ...scheduleItems])
console.log('📅 Combined schedule items:', scheduleItems.length)
} catch (error) {
console.error('❌ Error loading mobile clinic schedule:', error)
}
}


async function loadEvents() {
try {
const allEvents = await $fetch('/api/events')
console.log('✅ Loaded events from API:', allEvents)

const now = new Date()

pastEvents.value = allEvents.filter(event => {
const endTime = new Date(event.endTime)
return endTime < now
})

upcomingEvents.value = allEvents.filter(event => {
const endTime = new Date(event.endTime)
return endTime >= now
})

console.log('📅 Past events:', pastEvents.value.length)
console.log('📅 Upcoming events:', upcomingEvents.value.length)
const eventItems = allEvents
.filter((event) => event.mobileClinicId !== null)
.filter((event) => new Date(event.endTime) >= now)
.map((event) => ({
...event,
eventId: event.id,
}))

setUpcomingItems([...upcomingEvents.value, ...eventItems])
console.log('📅 Upcoming events:', eventItems.length)

} catch (error) {
console.error('❌ Error loading events:', error)
}
}


async function mapAdjust() {

const lng = -96.749788
const lat = 32.985141
async function mapAdjust(location) {

const lng = location.longitude
const lat = location.latitude

console.log(`📍 Adjusting map to event location: [${lng}, ${lat}]`)
center.value = [lng, lat]
zoom.value = 17
}


</script>
3 changes: 2 additions & 1 deletion prisma/schema/mobileClinic.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ model Mobile_Clinic_Schedule {
mobileClinicId String
location Location @relation(fields: [locationId], references: [id])
locationId String
datetime DateTime
startTime DateTime @unique
endTime DateTime @unique

@@map("schedule")
}
Expand Down
15 changes: 15 additions & 0 deletions prisma/seed/schedule.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"mobileClinic": {
"id": "mobile_clinic_1"
},
"location":{
"longitude": -97.302784,
"latitude": 32.707596,
"address": "3001 S Riverside Dr, Fort Worth, TX 76119"
},
"startTime": "2026-05-01T14:00:00.000Z",
"endTime": "2026-05-01T22:00:00.000Z"
}

]
Loading