app/components/advanced/MilestonesPanel.vue

96 lines
2.8 KiB
Vue

<template>
<UCard>
<template #header>
<div class="flex items-center justify-between">
<h4 class="font-medium">Milestones</h4>
<UButton
size="xs"
variant="ghost"
icon="i-heroicons-plus"
@click="showAddForm = true">
Add
</UButton>
</div>
</template>
<div class="space-y-3">
<div
v-if="milestoneStatuses.length === 0"
class="text-sm text-neutral-500 italic py-2">
No milestones set. Add key dates to track progress.
</div>
<div
v-for="milestone in milestoneStatuses"
:key="milestone.id"
class="flex items-center justify-between p-2 border border-neutral-200 rounded">
<div class="flex items-center gap-2">
<UIcon
:name="
milestone.willReach
? 'i-heroicons-check-circle'
: 'i-heroicons-exclamation-triangle'
"
:class="milestone.willReach ? 'text-green-500' : 'text-amber-500'"
class="w-4 h-4" />
<div>
<div class="text-sm font-medium">{{ milestone.label }}</div>
<div class="text-xs text-neutral-500">
{{ formatDate(milestone.date) }}
</div>
</div>
</div>
<UButton
size="xs"
variant="ghost"
color="red"
icon="i-heroicons-trash"
@click="removeMilestone(milestone.id)" />
</div>
</div>
<!-- Add milestone modal -->
<UModal v-model="showAddForm">
<div class="p-4">
<h3 class="text-lg font-semibold mb-4">Add Milestone</h3>
<div class="space-y-3">
<UInput
v-model="newMilestone.label"
placeholder="Milestone name (e.g., 'Product launch')" />
<UInput v-model="newMilestone.date" type="date" />
<div class="flex gap-2">
<UButton @click="saveMilestone">Save</UButton>
<UButton variant="ghost" @click="cancelAdd">Cancel</UButton>
</div>
</div>
</div>
</UModal>
</UCard>
</template>
<script setup lang="ts">
const { milestoneStatus, addMilestone, removeMilestone } = useCoopBuilder();
const showAddForm = ref(false);
const newMilestone = ref({ label: "", date: "" });
const milestoneStatuses = computed(() => milestoneStatus());
function formatDate(dateString: string): string {
const date = new Date(dateString);
return date.toLocaleDateString("en-US", { month: "short", year: "numeric" });
}
function saveMilestone() {
if (newMilestone.value.label && newMilestone.value.date) {
addMilestone(newMilestone.value.label, newMilestone.value.date);
newMilestone.value = { label: "", date: "" };
showAddForm.value = false;
}
}
function cancelAdd() {
newMilestone.value = { label: "", date: "" };
showAddForm.value = false;
}
</script>