refactor: replace Wizard with CoopBuilder in navigation, enhance budget store structure, and streamline template components for improved user experience

This commit is contained in:
Jennie Robinson Faber 2025-08-17 17:25:04 +01:00
parent eede87a273
commit f67b138d95
33 changed files with 4970 additions and 2451 deletions

View file

@ -1,132 +1,137 @@
<template>
<div class="max-w-4xl mx-auto space-y-6">
<!-- Section Header with Export Controls -->
<div class="flex items-center justify-between mb-8">
<div>
<h3 class="text-2xl font-black text-black mb-2">
Where will your money come from?
</h3>
<p class="text-neutral-600">
Add sources like client work, grants, product sales, or donations.
</p>
</div>
<div class="flex items-center gap-3">
<UButton
variant="outline"
color="gray"
size="sm"
@click="exportStreams">
<UIcon name="i-heroicons-arrow-down-tray" class="mr-1" />
Export
</UButton>
<UButton
v-if="streams.length > 0"
@click="addRevenueStream"
size="sm"
variant="solid"
color="success"
:ui="{
base: 'cursor-pointer hover:scale-105 transition-transform',
leadingIcon: 'hover:rotate-90 transition-transform',
}">
<UIcon name="i-heroicons-plus" class="mr-1" />
Add stream
</UButton>
</div>
<!-- Section Header -->
<div class="mb-8">
<h3 class="text-2xl font-black text-black mb-2">
Where will your money come from?
</h3>
<p class="text-neutral-600">
Add sources like client work, grants, product sales, or donations.
</p>
</div>
<div class="space-y-3">
<div
v-if="streams.length === 0"
class="text-center py-12 border-4 border-dashed border-black rounded-xl bg-white shadow-lg">
<h4 class="font-medium text-neutral-900 mb-2">
No revenue streams yet
</h4>
<p class="text-sm text-neutral-500 mb-4">
Get started by adding your first revenue source.
</p>
<UButton
@click="addRevenueStream"
size="lg"
variant="solid"
color="primary">
<UIcon name="i-heroicons-plus" class="mr-2" />
Add your first revenue stream
</UButton>
</div>
<!-- Removed Tab Navigation - showing streams directly -->
<div class="space-y-6">
<!-- Export Controls -->
<div class="flex justify-end">
<UButton
variant="outline"
color="gray"
size="sm"
@click="exportStreams">
<UIcon name="i-heroicons-arrow-down-tray" class="mr-1" />
Export
</UButton>
</div>
<div
v-for="stream in streams"
:key="stream.id"
class="p-6 border-3 border-black rounded-xl bg-white shadow-md">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<UFormField label="Category" required>
<USelect
v-model="stream.category"
:items="categoryOptions"
size="xl"
class="text-xl font-bold w-full"
@update:model-value="saveStream(stream)" />
</UFormField>
<div class="space-y-3">
<div
v-if="streams.length === 0"
class="text-center py-12 border-4 border-dashed border-black rounded-xl bg-white shadow-lg">
<h4 class="font-medium text-neutral-900 mb-2">
No revenue streams yet
</h4>
<p class="text-sm text-neutral-500 mb-4">
Get started by adding your first revenue source.
</p>
<UButton
@click="addRevenueStream"
size="lg"
variant="solid"
color="primary">
<UIcon name="i-heroicons-plus" class="mr-2" />
Add your first revenue stream
</UButton>
</div>
<UFormField label="Revenue source name" required>
<USelectMenu
v-model="stream.name"
:items="nameOptionsByCategory[stream.category] || []"
placeholder="Select or type a source name"
creatable
searchable
size="xl"
class="text-xl font-bold w-full"
@update:model-value="saveStream(stream)" />
</UFormField>
<div
v-for="stream in streams"
:key="stream.id"
class="p-6 border-3 border-black rounded-xl bg-white shadow-md">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<UFormField label="Category" required>
<USelect
v-model="stream.category"
:items="categoryOptions"
size="xl"
class="text-xl font-bold w-full"
@update:model-value="saveStream(stream)" />
</UFormField>
<UFormField label="Monthly amount" required>
<UInput
v-model="stream.targetMonthlyAmount"
type="text"
placeholder="5000"
size="xl"
class="text-xl font-black w-full"
@update:model-value="validateAndSaveAmount($event, stream)"
@blur="saveStream(stream)">
<template #leading>
<span class="text-neutral-500 text-xl">$</span>
</template>
</UInput>
</UFormField>
<UFormField label="Revenue source name" required>
<USelectMenu
v-model="stream.name"
:items="nameOptionsByCategory[stream.category] || []"
placeholder="Select or type a source name"
creatable
searchable
size="xl"
class="text-xl font-bold w-full"
@update:model-value="saveStream(stream)" />
</UFormField>
<UFormField label="Monthly amount" required>
<UInput
v-model="stream.targetMonthlyAmount"
type="text"
placeholder="5000"
size="xl"
class="text-xl font-black w-full"
@update:model-value="validateAndSaveAmount($event, stream)"
@blur="saveStream(stream)">
<template #leading>
<span class="text-neutral-500 text-xl">$</span>
</template>
</UInput>
</UFormField>
</div>
<div class="flex justify-end mt-6 pt-6 border-t-3 border-black">
<UButton
size="xs"
variant="solid"
color="error"
@click="removeStream(stream.id)"
:ui="{
base: 'cursor-pointer hover:opacity-90 transition-opacity',
}">
<UIcon name="i-heroicons-trash" class="w-4 h-4" />
</UButton>
</div>
</div>
<!-- Add Stream Button (when items exist) -->
<div v-if="streams.length > 0" class="flex justify-center">
<UButton
@click="addRevenueStream"
size="lg"
variant="solid"
color="success"
:ui="{
base: 'cursor-pointer hover:scale-105 transition-transform',
leadingIcon: 'hover:rotate-90 transition-transform',
}">
<UIcon name="i-heroicons-plus" class="mr-2" />
Add another stream
</UButton>
</div>
<div v-if="streams.length > 0" class="flex items-center gap-3 justify-end">
<UButton
@click="addRevenueStream"
size="sm"
variant="solid"
color="success"
:ui="{
base: 'cursor-pointer hover:scale-105 transition-transform',
leadingIcon: 'hover:rotate-90 transition-transform',
}">
<UIcon name="i-heroicons-plus" class="mr-1" />
Add stream
</UButton>
</div>
</div>
</div>
<div class="flex justify-end mt-6 pt-6 border-t-3 border-black">
<UButton
size="xs"
variant="solid"
color="error"
@click="removeStream(stream.id)"
:ui="{
base: 'cursor-pointer hover:opacity-90 transition-opacity',
}">
<UIcon name="i-heroicons-trash" class="w-4 h-4" />
</UButton>
</div>
</div>
<!-- Add Stream Button (when items exist) -->
<div v-if="streams.length > 0" class="flex justify-center">
<UButton
@click="addRevenueStream"
size="lg"
variant="solid"
color="success"
:ui="{
base: 'cursor-pointer hover:scale-105 transition-transform',
leadingIcon: 'hover:rotate-90 transition-transform',
}">
<UIcon name="i-heroicons-plus" class="mr-2" />
Add another stream
</UButton>
</div>
</div>
</div>
</template>