feat: add initial application structure with configuration, UI components, and state management
This commit is contained in:
parent
fadf94002c
commit
0af6b17792
56 changed files with 6137 additions and 129 deletions
180
pages/glossary.vue
Normal file
180
pages/glossary.vue
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<section class="py-8 space-y-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-2xl font-semibold">Glossary</h2>
|
||||
<UInput
|
||||
v-model="searchQuery"
|
||||
placeholder="Search definitions..."
|
||||
icon="i-heroicons-magnifying-glass"
|
||||
class="w-64"
|
||||
:ui="{ icon: { trailing: { pointer: '' } } }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UCard>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
<div v-for="letter in alphabeticalGroups" :key="letter.letter" class="space-y-4">
|
||||
<h3 class="text-lg font-semibold text-primary-600 border-b border-gray-200 pb-2">
|
||||
{{ letter.letter }}
|
||||
</h3>
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
v-for="term in letter.terms"
|
||||
:key="term.id"
|
||||
:id="term.id"
|
||||
class="scroll-mt-20"
|
||||
>
|
||||
<dt class="font-medium text-gray-900 mb-1">
|
||||
{{ term.term }}
|
||||
</dt>
|
||||
<dd class="text-gray-600 text-sm leading-relaxed">
|
||||
{{ term.definition }}
|
||||
<span v-if="term.example" class="block mt-1 text-gray-500 italic">
|
||||
Example: {{ term.example }}
|
||||
</span>
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</UCard>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Glossary terms based on CLAUDE.md definitions
|
||||
const glossaryTerms = ref([
|
||||
{
|
||||
id: 'budget',
|
||||
term: 'Budget',
|
||||
definition: 'Month-by-month plan of money in and money out. Not exact dates.',
|
||||
example: 'January budget shows €12,000 revenue and €9,900 costs'
|
||||
},
|
||||
{
|
||||
id: 'cash-flow',
|
||||
term: 'Cash Flow',
|
||||
definition: 'The actual dates money moves. Shows timing risk.',
|
||||
example: 'Client pays Net 30, so January work arrives in February'
|
||||
},
|
||||
{
|
||||
id: 'concentration',
|
||||
term: 'Concentration',
|
||||
definition: 'Dependence on few revenue sources. UI shows top source percentage.',
|
||||
example: 'If 65% comes from one client, concentration is high risk'
|
||||
},
|
||||
{
|
||||
id: 'coverage',
|
||||
term: 'Coverage',
|
||||
definition: 'Funded paid hours divided by target hours across all members.',
|
||||
example: '208 funded hours ÷ 320 target hours = 65% coverage'
|
||||
},
|
||||
{
|
||||
id: 'deferred-pay',
|
||||
term: 'Deferred Pay',
|
||||
definition: 'Unpaid hours the co-op owes later at the same wage.',
|
||||
example: 'Alex worked 40 hours unpaid in January, owed €800 later'
|
||||
},
|
||||
{
|
||||
id: 'equal-wage',
|
||||
term: 'Equal Wage',
|
||||
definition: 'Same hourly rate for all paid hours.',
|
||||
example: 'Everyone gets €20/hour for paid work, regardless of role'
|
||||
},
|
||||
{
|
||||
id: 'minimum-cash-cushion',
|
||||
term: 'Minimum Cash Cushion',
|
||||
definition: 'Lowest operating balance we agree not to breach.',
|
||||
example: '€3,000 minimum means never go below this amount'
|
||||
},
|
||||
{
|
||||
id: 'on-costs',
|
||||
term: 'On-costs',
|
||||
definition: 'Employer taxes, benefits, and payroll fees on top of wages.',
|
||||
example: '€6,400 wages + 25% on-costs = €8,000 total payroll'
|
||||
},
|
||||
{
|
||||
id: 'patronage',
|
||||
term: 'Patronage',
|
||||
definition: 'A way to share surplus based on recorded contributions.',
|
||||
example: 'Extra profits shared based on hours worked or value added'
|
||||
},
|
||||
{
|
||||
id: 'payout-delay',
|
||||
term: 'Payout Delay',
|
||||
definition: 'Time between earning money and receiving it.',
|
||||
example: 'Platform sales have 14-day delay, grants have 45-day delay'
|
||||
},
|
||||
{
|
||||
id: 'restricted-funds',
|
||||
term: 'Restricted Funds',
|
||||
definition: 'Money that can only be used for approved purposes.',
|
||||
example: 'Grant money restricted to development costs only'
|
||||
},
|
||||
{
|
||||
id: 'revenue-share',
|
||||
term: 'Revenue Share',
|
||||
definition: 'Percentage of earnings paid to platform or partner.',
|
||||
example: 'App store takes 30% revenue share on sales'
|
||||
},
|
||||
{
|
||||
id: 'runway',
|
||||
term: 'Runway',
|
||||
definition: 'Months until cash plus savings run out under the current plan.',
|
||||
example: '€13,000 available ÷ €4,600 monthly burn = 2.8 months runway'
|
||||
},
|
||||
{
|
||||
id: 'savings-target',
|
||||
term: 'Savings Target',
|
||||
definition: 'Money held for stability. Aim to reach before ramping hours.',
|
||||
example: '3 months target = €13,800 for 3 months of expenses'
|
||||
},
|
||||
{
|
||||
id: 'surplus',
|
||||
term: 'Surplus',
|
||||
definition: 'Money left over after all costs are paid.',
|
||||
example: '€12,000 revenue - €9,900 costs = €2,100 surplus'
|
||||
},
|
||||
{
|
||||
id: 'value-accounting',
|
||||
term: 'Value Accounting',
|
||||
definition: 'Monthly process to review contributions and distribute surplus.',
|
||||
example: 'January session: review work, repay deferred pay, fund training'
|
||||
}
|
||||
])
|
||||
|
||||
// Filter terms based on search
|
||||
const filteredTerms = computed(() => {
|
||||
if (!searchQuery.value) return glossaryTerms.value
|
||||
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
return glossaryTerms.value.filter(term =>
|
||||
term.term.toLowerCase().includes(query) ||
|
||||
term.definition.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
|
||||
// Group terms alphabetically
|
||||
const alphabeticalGroups = computed(() => {
|
||||
const groups = new Map()
|
||||
|
||||
filteredTerms.value
|
||||
.sort((a, b) => a.term.localeCompare(b.term))
|
||||
.forEach(term => {
|
||||
const letter = term.term[0].toUpperCase()
|
||||
if (!groups.has(letter)) {
|
||||
groups.set(letter, { letter, terms: [] })
|
||||
}
|
||||
groups.get(letter).terms.push(term)
|
||||
})
|
||||
|
||||
return Array.from(groups.values()).sort((a, b) => a.letter.localeCompare(b.letter))
|
||||
})
|
||||
|
||||
// SEO and accessibility
|
||||
useSeoMeta({
|
||||
title: 'Glossary - Plain English Definitions',
|
||||
description: 'Plain English definitions of co-op financial terms. No jargon.',
|
||||
})
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue