Files
chrono/src/components/editors/EventEditorLocations.vue
T
2026-02-10 20:08:03 -05:00

175 lines
5.4 KiB
Vue

<script setup lang="ts">
interface Props {
mode: 'edit' | 'view'
locationsPhysical: Record<string, any>
locationsVirtual: Record<string, any>
}
const props = defineProps<Props>()
const emit = defineEmits<{
'add-location-physical': []
'remove-location-physical': [key: string]
'add-location-virtual': []
'remove-location-virtual': [key: string]
}>()
const hasLocations = () => {
return Object.keys(props.locationsPhysical || {}).length > 0 ||
Object.keys(props.locationsVirtual || {}).length > 0
}
</script>
<template>
<div v-if="hasLocations() || mode === 'edit'" class="event-editor-section">
<div class="text-subtitle-1 mb-2">Locations</div>
<!-- Physical Locations -->
<div v-if="Object.keys(locationsPhysical || {}).length > 0 || mode === 'edit'" class="mb-4">
<div class="d-flex align-center justify-space-between mb-2">
<div class="text-subtitle-2">Physical Locations</div>
<v-btn v-if="mode === 'edit'"
size="small"
variant="outlined"
@click="$emit('add-location-physical')">
<v-icon left>mdi-plus</v-icon>
Add
</v-btn>
</div>
<!-- Read-only view -->
<div v-if="mode === 'view'">
<div v-for="(location, key) in locationsPhysical" :key="key" class="mb-2 pa-2 border rounded">
<div class="mb-1"><strong>{{ location.label || 'Location' }}</strong></div>
<div v-if="location.timeZone" class="text-caption text-grey">Time Zone: {{ location.timeZone }}</div>
<div v-if="location.description" class="text-caption">{{ location.description }}</div>
</div>
</div>
<!-- Edit view -->
<div v-else>
<div v-for="(location, key) in locationsPhysical" :key="key" class="mb-3 pa-3 border rounded">
<div class="d-flex align-center justify-space-between mb-2">
<strong>{{ location.label || 'Physical Location' }}</strong>
<v-btn
icon="mdi-delete"
size="small"
color="error"
variant="text"
@click="$emit('remove-location-physical', key)">
</v-btn>
</div>
<v-row dense>
<v-col cols="12" md="6">
<v-text-field
v-model="location.label"
label="Label"
variant="outlined"
density="compact"
/>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="location.timeZone"
label="Time Zone"
variant="outlined"
density="compact"
/>
</v-col>
</v-row>
<v-textarea
v-model="location.description"
label="Description"
variant="outlined"
density="compact"
rows="2"
/>
<v-select
v-model="location.relation"
:items="['start', 'end']"
label="Relation"
variant="outlined"
density="compact"
clearable
/>
</div>
</div>
</div>
<!-- Virtual Locations -->
<div v-if="Object.keys(locationsVirtual || {}).length > 0 || mode === 'edit'">
<div class="d-flex align-center justify-space-between mb-2">
<div class="text-subtitle-2">Virtual Locations</div>
<v-btn v-if="mode === 'edit'"
size="small"
variant="outlined"
@click="$emit('add-location-virtual')">
<v-icon left>mdi-plus</v-icon>
Add
</v-btn>
</div>
<!-- Read-only view -->
<div v-if="mode === 'view'">
<div v-for="(location, key) in locationsVirtual" :key="key" class="mb-2 pa-2 border rounded">
<div class="mb-1"><strong>{{ location.label || 'Virtual Location' }}</strong></div>
<div class="text-caption">
<a :href="location.location" target="_blank" class="text-primary">{{ location.location }}</a>
</div>
<div v-if="location.description" class="text-caption text-grey mt-1">{{ location.description }}</div>
</div>
</div>
<!-- Edit view -->
<div v-else>
<div v-for="(location, key) in locationsVirtual" :key="key" class="mb-3 pa-3 border rounded">
<div class="d-flex align-center justify-space-between mb-2">
<strong>{{ location.label || 'Virtual Location' }}</strong>
<v-btn
icon="mdi-delete"
size="small"
color="error"
variant="text"
@click="$emit('remove-location-virtual', key)">
</v-btn>
</div>
<v-text-field
v-model="location.label"
label="Label"
variant="outlined"
density="compact"
class="mb-2"
/>
<v-text-field
v-model="location.location"
label="URL"
variant="outlined"
density="compact"
class="mb-2"
:rules="[v => !!v || 'URL is required']"
/>
<v-textarea
v-model="location.description"
label="Description"
variant="outlined"
density="compact"
rows="2"
/>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.event-editor-section {
margin-bottom: 1.5rem;
}
</style>