- Backend: FastAPI + SQLAlchemy + Celery (Python 3.11+) - Frontend: Vue 3 + TypeScript + Pinia + Tailwind - Admin Frontend: separate Vue 3 app for management - Docker Compose: 9 services orchestration - Specs: design prototypes, memory system PRD, product roadmap Cleanup performed: - Removed temporary debug scripts from backend root - Removed deprecated admin_app.py (embedded UI) - Removed duplicate docs from admin-frontend - Updated .gitignore for Vite cache and egg-info
46 lines
1.0 KiB
Vue
46 lines
1.0 KiB
Vue
<script setup lang="ts">
|
|
import type { Component } from 'vue'
|
|
import BaseButton from './BaseButton.vue'
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
icon: Component
|
|
title: string
|
|
description: string
|
|
actionText?: string
|
|
actionTo?: string
|
|
}>(),
|
|
{
|
|
actionText: '',
|
|
actionTo: '',
|
|
},
|
|
)
|
|
|
|
const emit = defineEmits<{ action: [] }>()
|
|
|
|
function handleAction() {
|
|
if (!props.actionTo) emit('action')
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col items-center justify-center text-center py-12">
|
|
<component :is="props.icon" class="h-14 w-14 text-purple-400" aria-hidden="true" />
|
|
<h3 class="mt-4 text-xl font-semibold text-gray-800">
|
|
{{ props.title }}
|
|
</h3>
|
|
<p class="mt-2 text-sm text-gray-500">
|
|
{{ props.description }}
|
|
</p>
|
|
<BaseButton
|
|
v-if="props.actionText"
|
|
:as="props.actionTo ? 'router-link' : 'button'"
|
|
:to="props.actionTo || undefined"
|
|
class="mt-6"
|
|
@click="handleAction"
|
|
>
|
|
{{ props.actionText }}
|
|
</BaseButton>
|
|
</div>
|
|
</template>
|