Enhance application structure: Add runtime configuration for environment variables, integrate new dependencies for Cloudinary and UI components, and refactor member management features including improved forms and member dashboard. Update styles and layout for better user experience.
This commit is contained in:
parent
6e7e27ac4e
commit
e4a0a9ab0f
61 changed files with 7902 additions and 950 deletions
101
app/pages/admin/members-simple.vue
Normal file
101
app/pages/admin/members-simple.vue
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold mb-6">Members</h1>
|
||||
|
||||
<div v-if="pending" class="text-center">Loading...</div>
|
||||
|
||||
<div v-else-if="error" class="text-red-600">
|
||||
Error loading members: {{ error }}
|
||||
</div>
|
||||
|
||||
<div v-else class="space-y-4">
|
||||
<div class="bg-white rounded-lg border p-4">
|
||||
<h3 class="font-semibold mb-2">Total Members: {{ members?.length || 0 }}</h3>
|
||||
|
||||
<div v-for="member in members" :key="member._id" class="border-b pb-2 mb-2 last:border-b-0">
|
||||
<div class="flex justify-between items-center">
|
||||
<div>
|
||||
<p class="font-medium">{{ member.name }}</p>
|
||||
<p class="text-gray-600 text-sm">{{ member.email }}</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<span class="inline-block px-2 py-1 text-xs rounded bg-blue-100 text-blue-800">
|
||||
{{ member.circle }}
|
||||
</span>
|
||||
<p class="text-sm text-gray-500">${{ member.contributionTier }}/month</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Simple Add Member Form -->
|
||||
<div class="bg-white rounded-lg border p-4">
|
||||
<h3 class="font-semibold mb-4">Add Member</h3>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<input v-model="newMember.name" placeholder="Name" class="border rounded p-2" />
|
||||
<input v-model="newMember.email" placeholder="Email" class="border rounded p-2" />
|
||||
<select v-model="newMember.circle" class="border rounded p-2">
|
||||
<option value="community">Community</option>
|
||||
<option value="founder">Founder</option>
|
||||
<option value="practitioner">Practitioner</option>
|
||||
</select>
|
||||
<select v-model="newMember.contributionTier" class="border rounded p-2">
|
||||
<option value="0">$0/month</option>
|
||||
<option value="5">$5/month</option>
|
||||
<option value="15">$15/month</option>
|
||||
<option value="30">$30/month</option>
|
||||
<option value="50">$50/month</option>
|
||||
</select>
|
||||
</div>
|
||||
<button @click="createMember" :disabled="creating" class="mt-4 bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50">
|
||||
{{ creating ? 'Adding...' : 'Add Member' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
definePageMeta({
|
||||
layout: 'admin'
|
||||
})
|
||||
|
||||
const { data: members, pending, error, refresh } = await useFetch("/api/admin/members")
|
||||
const creating = ref(false)
|
||||
|
||||
const newMember = reactive({
|
||||
name: '',
|
||||
email: '',
|
||||
circle: 'community',
|
||||
contributionTier: '0'
|
||||
})
|
||||
|
||||
const createMember = async () => {
|
||||
if (!newMember.name || !newMember.email) {
|
||||
alert('Please fill in name and email')
|
||||
return
|
||||
}
|
||||
|
||||
creating.value = true
|
||||
try {
|
||||
await $fetch('/api/admin/members', {
|
||||
method: 'POST',
|
||||
body: newMember
|
||||
})
|
||||
|
||||
Object.assign(newMember, {
|
||||
name: '',
|
||||
email: '',
|
||||
circle: 'community',
|
||||
contributionTier: '0'
|
||||
})
|
||||
|
||||
await refresh()
|
||||
alert('Member added successfully!')
|
||||
} catch (error) {
|
||||
alert('Failed to add member: ' + error.message)
|
||||
} finally {
|
||||
creating.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue