diff --git a/README.md b/README.md index 7f452fe..47f6e0c 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,214 @@ -# Nuxt 3 Minimal Starter +# corradAF - Corrad Application Framework -Look at the [nuxt 3 documentation](https://v3.nuxtjs.org) to learn more. +Welcome to **corradAF**, a comprehensive Nuxt.js template designed for rapid application development. This framework provides a solid foundation with essential development tools, authentication system, and modern UI components. -## Setup +## 🚀 Features -Make sure to install the dependencies: +- **🔐 Complete Authentication System** - Login, Register, Password Recovery, Logout +- **👥 User Management** - User and role management with CRUD operations +- **🛠️ Development Tools Suite** - Comprehensive set of dev tools for rapid development +- **🎨 Modern UI Components** - Built with TailwindCSS and custom components +- **📱 Responsive Design** - Mobile-first approach with modern UX patterns +- **🔧 API Management** - Built-in API endpoint design and testing tools +- **📝 Content Management** - Dynamic content and template management +- **🎯 Menu Configuration** - Easy navigation structure management +- **💻 Code Playground** - In-browser code testing and prototyping +- **🗄️ ORM Integration** - Database schema management tools +- **⚙️ Configuration Management** - System settings and environment setup + +## 🛠️ Development Tools Included + +### User Management +- User CRUD operations +- Role-based access control +- Permission management + +### Menu Editor +- Dynamic navigation configuration +- Hierarchical menu structure +- Permission-based menu visibility + +### API Editor +- Design and test API endpoints +- Interactive API documentation +- Request/response testing + +### Content Editor +- Dynamic content management +- Template editing +- Content versioning + +### Code Playground +- Real-time code testing +- Multiple language support +- Instant preview + +### ORM Tools +- Database schema management +- Query builder interface +- Migration tools + +### Configuration +- Environment variable management +- System settings +- Feature toggles + +## 📋 Prerequisites + +- Node.js 18+ +- Yarn or npm +- Database (PostgreSQL/MySQL recommended) + +## 🚀 Quick Start + +### 1. Clone the Template ```bash -# yarn +git clone your-project-name +cd your-project-name +``` + +### 2. Install Dependencies + +```bash +# Using yarn (recommended) yarn install -# npm +# Or using npm npm install - -# pnpm -pnpm install --shamefully-hoist ``` -## Development Server - -Start the development server on http://localhost:3000 +### 3. Environment Setup ```bash -npm run dev +# Copy environment template +cp .env.example .env + +# Edit your environment variables +nano .env ``` -## Production +Configure your database connection and other environment variables in the `.env` file. -Build the application for production: +### 4. Database Setup ```bash -npm run build +# Run database migrations and generate Prisma client +yarn prisma + +# Or manually +npx prisma db pull && npx prisma generate ``` -Locally preview production build: +### 5. Start Development Server ```bash -npm run preview +yarn dev ``` -Checkout the [deployment documentation](https://v3.nuxtjs.org/guide/deploy/presets) for more information. -# corradAF +Your application will be available at `http://localhost:3000` -This is the base project for corradAF. +## 📁 Project Structure + +``` +├── assets/ # Static assets (images, styles) +├── components/ # Vue components +├── composables/ # Vue composables +├── layouts/ # Application layouts +├── middleware/ # Route middleware +├── navigation/ # Navigation configuration +├── pages/ # Application pages +│ ├── devtool/ # Development tools +│ ├── dashboard/ # Main dashboard +│ ├── login/ # Authentication pages +│ ├── register/ # User registration +│ └── ... +├── plugins/ # Nuxt plugins +├── prisma/ # Database schema and migrations +├── public/ # Public static files +├── server/ # Server-side API +├── stores/ # Pinia stores +└── templates/ # Template files +``` + +## 🔧 Configuration + +### Database +Configure your database connection in the `.env` file: + +```env +DATABASE_URL="postgresql://username:password@localhost:5432/database_name" +``` + +### Authentication +Set up JWT secrets and authentication settings: + +```env +JWT_SECRET="your-super-secret-jwt-key" +AUTH_ORIGIN="http://localhost:3000" +``` + +## 🎨 Customization + +### Theme Configuration +Customize colors, fonts, and spacing in: +- `tailwind.config.js` - TailwindCSS configuration +- `app.config.js` - Application-specific settings + +### Adding New Development Tools +1. Create a new page in `pages/devtool/your-tool/` +2. Add navigation entry in the navigation configuration +3. Implement your tool's functionality + +## 📖 Documentation + +- [Nuxt 3 Documentation](https://nuxt.com/docs) +- [TailwindCSS Documentation](https://tailwindcss.com/docs) +- [Prisma Documentation](https://www.prisma.io/docs) +- [FormKit Documentation](https://formkit.com/) + +## 🚀 Deployment + +### Build for Production + +```bash +yarn build +``` + +### Preview Production Build + +```bash +yarn preview +``` + +### Environment Variables for Production + +Ensure all environment variables are properly set in your production environment: + +- `DATABASE_URL` +- `JWT_SECRET` +- `AUTH_ORIGIN` +- `NUXT_SECRET_KEY` + +## 🤝 Contributing + +1. Fork the repository +2. Create your feature branch (`git checkout -b feature/amazing-feature`) +3. Commit your changes (`git commit -m 'Add some amazing feature'`) +4. Push to the branch (`git push origin feature/amazing-feature`) +5. Open a Pull Request + +## 📄 License + +This project is licensed under the MIT License - see the LICENSE file for details. + +## 🆘 Support + +For support and questions: +- Create an issue in the repository +- Check existing documentation +- Review the development tools included in the framework + +--- + +**Built with ❤️ using Nuxt 3, TailwindCSS, and modern web technologies.** diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..de85f20 --- /dev/null +++ b/SETUP.md @@ -0,0 +1,155 @@ +# corradAF Setup Guide + +This guide will help you set up the corradAF framework template for your new project. + +## 🚀 Quick Setup + +### 1. Environment Configuration + +Create a `.env` file in your project root with the following variables: + +```env +# Database Configuration +DATABASE_URL="postgresql://username:password@localhost:5432/database_name" + +# Authentication +JWT_SECRET="your-super-secret-jwt-key-change-this-in-production" +AUTH_ORIGIN="http://localhost:3000" + +# Application +NUXT_SECRET_KEY="your-nuxt-secret-key-for-session-encryption" +APP_NAME="Your Application Name" +APP_URL="http://localhost:3000" + +# Email Configuration (Optional) +MAIL_HOST="smtp.example.com" +MAIL_PORT="587" +MAIL_USERNAME="your-email@example.com" +MAIL_PASSWORD="your-email-password" +MAIL_FROM_ADDRESS="noreply@yourapp.com" +MAIL_FROM_NAME="Your App Name" + +# Development +NODE_ENV="development" +NUXT_HOST="localhost" +NUXT_PORT="3000" +``` + +### 2. Database Setup + +corradAF uses Prisma as the ORM. Follow these steps: + +1. **Configure your database URL** in the `.env` file +2. **Run database setup**: + ```bash + yarn prisma + # This runs: npx prisma db pull && npx prisma generate && nuxt dev + ``` + +### 3. First Run + +```bash +# Install dependencies +yarn install + +# Start development server +yarn dev +``` + +## 🔧 Development Tools Access + +After setup, you can access these development tools: + +- **User Management**: `/devtool/user-management/user` +- **Menu Editor**: `/devtool/menu-editor` +- **API Editor**: `/devtool/api-editor` +- **Content Editor**: `/devtool/content-editor` +- **Code Playground**: `/devtool/code-playground` +- **ORM Tools**: `/devtool/orm` +- **Configuration**: `/devtool/config` + +## 🎨 Customization + +### Update Branding + +1. **App Name**: Update in `.env` file (`APP_NAME`) +2. **Colors**: Modify `tailwind.config.js` +3. **Logo**: Replace files in `public/` directory +4. **Favicon**: Replace `public/favicon.ico` + +### Navigation Structure + +Edit the navigation configuration in `navigation/` directory to customize menus. + +### Authentication + +The authentication system is ready to use with: +- User registration at `/register` +- Login at `/login` +- Password recovery at `/forgot-password` + +## 📦 Production Deployment + +### Environment Variables + +Ensure these production environment variables are set: + +```env +NODE_ENV="production" +DATABASE_URL="your-production-database-url" +JWT_SECRET="your-production-jwt-secret" +AUTH_ORIGIN="https://yourdomain.com" +NUXT_SECRET_KEY="your-production-secret-key" +``` + +### Build Commands + +```bash +# Build for production +yarn build + +# Preview production build locally +yarn preview +``` + +## 🛠️ Extending the Framework + +### Adding New Development Tools + +1. Create new page in `pages/devtool/your-tool/` +2. Add navigation entry +3. Implement functionality + +### Custom Components + +Add your custom components in `components/` directory following the existing structure. + +### API Endpoints + +Create server routes in `server/api/` directory. + +## 🐛 Troubleshooting + +### Common Issues + +1. **Database Connection Issues**: Verify DATABASE_URL in `.env` +2. **Authentication Problems**: Check JWT_SECRET configuration +3. **Build Errors**: Ensure all dependencies are installed with `yarn install` +4. **Port Conflicts**: Change NUXT_PORT in `.env` file + +### Getting Help + +- Check the main README.md for detailed documentation +- Review existing development tools for implementation examples +- Create issues in the repository for bugs or feature requests + +## 📝 Next Steps + +After setup: + +1. Customize the dashboard welcome page with your project branding +2. Set up your project-specific features +3. Configure authentication and user roles +4. Start building your application features + +Happy coding with corradAF! 🚀 \ No newline at end of file diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000..ec619a3 --- /dev/null +++ b/llms.txt @@ -0,0 +1,589 @@ +# corradAF Framework - LLM Interaction Guide + +## Metadata +- **Framework Name**: corradAF (Corrad Application Framework) +- **Framework Version**: 1.0.0 +- **License**: MIT License +- **Base Technology**: Nuxt 3, Vue 3, TypeScript/JavaScript +- **UI Framework**: TailwindCSS with custom components +- **Database ORM**: Prisma +- **Supported Languages**: English (primary), multi-language ready +- **Input Format**: Text, Markdown, JSON for API specifications +- **Output Format**: Vue SFC components, TypeScript/JavaScript, JSON configurations + +## Framework Overview + +### Introduction: +corradAF is a comprehensive Nuxt.js template designed for rapid application development. It provides a complete development tools suite, authentication system, and modern UI components. This document defines interaction patterns for LLMs working with the corradAF framework. + +### Core Architecture: +- **Frontend**: Nuxt 3 with Vue 3 Composition API +- **Styling**: TailwindCSS with custom component library +- **State Management**: Pinia stores +- **Authentication**: JWT-based with middleware protection +- **Database**: Prisma ORM with PostgreSQL (configurable) +- **Development Tools**: Built-in suite for rapid development + +## Content Structure Guidelines + +### File Organization: +``` +├── pages/ # Route pages (Nuxt auto-routing) +├── components/ # Reusable Vue components +├── composables/ # Vue composables for shared logic +├── layouts/ # Application layouts +├── middleware/ # Route middleware (auth, permissions) +├── server/api/ # Server-side API endpoints +├── stores/ # Pinia state management +├── assets/ # Static assets and styles +├── public/ # Public static files +├── prisma/ # Database schema and migrations +└── devtool/ # Development tools pages +``` + +### Component Naming Conventions: +- **Pages**: Use kebab-case for file names (e.g., `user-management.vue`) +- **Components**: Use PascalCase for component names (e.g., `UserCard.vue`) +- **Composables**: Prefix with `use` (e.g., `useUserManagement.js`) +- **Stores**: Use camelCase with descriptive names (e.g., `userStore.js`) + +## Writing Guidelines for LLMs + +### Controlled Vocabulary: +- Use `navigateTo()` instead of `router.push()` for navigation (Nuxt 3 pattern) +- Use `definePageMeta()` for page configuration +- Use `ref()` and `reactive()` for Vue 3 Composition API +- Use `composables` instead of `mixins` for shared logic +- Use `middleware` for route protection and validation + +### Grammar Rules: +- **Sentence Length**: Maximum 20 words for code comments +- **Active Voice**: Prefer active voice in documentation +- **Function Names**: Use camelCase with descriptive verbs +- **Variable Names**: Use camelCase with clear, descriptive nouns + +### Code Style Guidelines: +- **Vue SFC Structure**: ` + + + + +``` + +### Page Component Template: +```vue + + + +``` + +### Development Tool Page Template: +```vue + + + +``` + +## API Endpoint Templates + +### Server API Route Template: +```typescript +export default defineEventHandler(async (event) => { + // Validate authentication + const user = await requireUserSession(event) + + // Handle different HTTP methods + const method = getMethod(event) + + if (method === 'GET') { + // GET logic + return { data: [] } + } + + if (method === 'POST') { + // POST logic + const body = await readBody(event) + + // Validate input + if (!body.name) { + throw createError({ + statusCode: 400, + statusMessage: 'Name is required' + }) + } + + // Process request + return { success: true, data: body } + } + + // Handle other methods + throw createError({ + statusCode: 405, + statusMessage: 'Method not allowed' + }) +}) +``` + +### API Response Format: +```json +{ + "success": true, + "data": {}, + "message": "Operation completed successfully", + "meta": { + "timestamp": "2024-01-01T00:00:00Z", + "version": "1.0.0" + } +} +``` + +### Error Response Format: +```json +{ + "success": false, + "error": { + "code": "VALIDATION_ERROR", + "message": "Invalid input provided", + "details": {} + }, + "meta": { + "timestamp": "2024-01-01T00:00:00Z", + "version": "1.0.0" + } +} +``` + +## Database Schema Patterns + +### Prisma Model Template: +```prisma +model User { + id String @id @default(cuid()) + email String @unique + name String? + role Role @default(USER) + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + profile UserProfile? + posts Post[] + + @@map("users") +} + +model UserProfile { + id String @id @default(cuid()) + userId String @unique + avatar String? + bio String? + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@map("user_profiles") +} + +enum Role { + USER + ADMIN + DEVELOPER +} +``` + +## TailwindCSS and Styling Guidelines + +### Component Styling Patterns: +- **Cards**: Use `rs-card` component or `bg-white rounded-lg shadow-sm border` +- **Buttons**: Use `rs-button` component with variants (primary, secondary, danger) +- **Forms**: Use FormKit components with TailwindCSS utilities +- **Grid Layouts**: Use `grid grid-cols-{n} gap-{size}` for responsive layouts +- **Spacing**: Use consistent spacing scale (4, 6, 8, 12, 16, 24) + +### Color Scheme: +- **Primary**: `text-primary`, `bg-primary` +- **Secondary**: `text-secondary`, `bg-secondary` +- **Success**: `text-green-600`, `bg-green-100` +- **Warning**: `text-yellow-600`, `bg-yellow-100` +- **Danger**: `text-red-600`, `bg-red-100` + +## Authentication and Security Patterns + +### Route Protection: +```javascript +// middleware/auth.js +export default defineNuxtRouteMiddleware((to, from) => { + const { $auth } = useNuxtApp() + + if (!$auth.user) { + return navigateTo('/login') + } +}) + +// middleware/dev-tools.js +export default defineNuxtRouteMiddleware((to, from) => { + const { $auth } = useNuxtApp() + + if (!$auth.user?.isDeveloper) { + throw createError({ + statusCode: 403, + statusMessage: 'Access forbidden' + }) + } +}) +``` + +### API Security: +```typescript +// server/utils/auth.ts +export async function requireUserSession(event) { + const token = getCookie(event, 'auth-token') || getHeader(event, 'authorization') + + if (!token) { + throw createError({ + statusCode: 401, + statusMessage: 'Authentication required' + }) + } + + try { + const user = await verifyJWT(token) + return user + } catch (error) { + throw createError({ + statusCode: 401, + statusMessage: 'Invalid token' + }) + } +} +``` + +## Development Tools Integration + +### Adding New Development Tools: +1. Create page in `pages/devtool/tool-name/` +2. Add navigation entry in navigation configuration +3. Implement CRUD operations +4. Add proper middleware and permissions +5. Follow established UI patterns + +### Tool Configuration Template: +```javascript +// devtool configuration +export const toolConfig = { + name: 'Tool Name', + description: 'Tool description', + icon: 'mdi:tool-icon', + path: '/devtool/tool-name', + permissions: ['developer', 'admin'], + features: [ + 'create', + 'read', + 'update', + 'delete', + 'export', + 'import' + ] +} +``` + +## Input/Output Specifications for Code Generation + +### Request Format for Component Generation: +```json +{ + "task": "component_generation", + "type": "vue_component", + "specifications": { + "name": "UserCard", + "props": ["user", "showActions"], + "events": ["edit", "delete"], + "features": ["responsive", "accessible"], + "styling": "tailwindcss" + } +} +``` + +### Response Format: +```json +{ + "success": true, + "generated_code": "", + "file_path": "components/UserCard.vue", + "dependencies": ["vue", "@nuxt/icon"], + "usage_example": "", + "explanation": "Generated a responsive user card component with edit and delete actions." +} +``` + +## Error Handling Patterns + +### Frontend Error Handling: +```javascript +// composables/useErrorHandler.js +export const useErrorHandler = () => { + const handleError = (error, context = '') => { + console.error(`Error in ${context}:`, error) + + // Show user-friendly message + const { $toast } = useNuxtApp() + $toast.error('An error occurred. Please try again.') + + // Log to monitoring service if available + if (process.env.NODE_ENV === 'production') { + // Log to external service + } + } + + return { handleError } +} +``` + +### API Error Handling: +```typescript +// server/utils/errorHandler.ts +export function handleAPIError(error: unknown) { + if (error instanceof ValidationError) { + throw createError({ + statusCode: 400, + statusMessage: 'Validation failed', + data: error.details + }) + } + + if (error instanceof DatabaseError) { + throw createError({ + statusCode: 500, + statusMessage: 'Database operation failed' + }) + } + + // Generic error + throw createError({ + statusCode: 500, + statusMessage: 'Internal server error' + }) +} +``` + +## Testing Patterns + +### Component Testing Template: +```javascript +// tests/components/UserCard.test.js +import { mount } from '@vue/test-utils' +import UserCard from '~/components/UserCard.vue' + +describe('UserCard', () => { + const mockUser = { + id: '1', + name: 'John Doe', + email: 'john@example.com' + } + + it('renders user information correctly', () => { + const wrapper = mount(UserCard, { + props: { user: mockUser } + }) + + expect(wrapper.text()).toContain('John Doe') + expect(wrapper.text()).toContain('john@example.com') + }) + + it('emits edit event when edit button is clicked', async () => { + const wrapper = mount(UserCard, { + props: { user: mockUser, showActions: true } + }) + + await wrapper.find('[data-test="edit-button"]').trigger('click') + + expect(wrapper.emitted('edit')).toBeTruthy() + expect(wrapper.emitted('edit')[0]).toEqual([mockUser]) + }) +}) +``` + +## Ethical Guidelines and Security Considerations + +### Security Best Practices: +- **Input Validation**: Always validate and sanitize user inputs +- **SQL Injection Prevention**: Use Prisma ORM parameterized queries +- **XSS Prevention**: Use Vue's built-in template sanitization +- **CSRF Protection**: Implement CSRF tokens for state-changing operations +- **Authentication**: Use secure JWT implementation with proper expiration +- **Authorization**: Implement role-based access control (RBAC) + +### Ethical Considerations: +- **Accessibility**: Follow WCAG 2.1 guidelines for component generation +- **Privacy**: Implement data protection and GDPR compliance patterns +- **Bias Prevention**: Ensure generated content is inclusive and unbiased +- **Performance**: Generate efficient code that doesn't compromise user experience + +### Data Handling: +- **Encryption**: Use encryption for sensitive data storage +- **Logging**: Log security events without exposing sensitive information +- **Audit Trail**: Maintain audit logs for critical operations +- **Data Retention**: Implement proper data retention and deletion policies + +## Performance Guidelines + +### Code Generation Best Practices: +- **Lazy Loading**: Use dynamic imports for large components +- **Tree Shaking**: Write code that supports tree shaking +- **Bundle Size**: Consider bundle size impact in generated code +- **Caching**: Implement appropriate caching strategies +- **Database Queries**: Use efficient Prisma queries with proper relations + +### Optimization Patterns: +```javascript +// Lazy component loading +const LazyComponent = defineAsyncComponent(() => import('~/components/HeavyComponent.vue')) + +// Efficient data fetching +const { data, pending, error } = await useLazyFetch('/api/data', { + key: 'unique-key', + server: false // Client-side only if needed +}) + +// Computed optimization +const expensiveComputation = computed(() => { + return useMemo(() => heavyOperation(props.data), [props.data]) +}) +``` + +--- + +This document serves as a comprehensive guide for LLMs working with the corradAF framework. It ensures consistent code generation, proper architecture patterns, and adherence to best practices for security, performance, and maintainability. \ No newline at end of file diff --git a/package.json b/package.json index 4575231..a924b0a 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,29 @@ { + "name": "corrad-af", + "version": "1.0.0", + "description": "Corrad Application Framework - A comprehensive Nuxt.js template for rapid application development", + "author": "Corrad Team", + "license": "MIT", + "keywords": [ + "nuxt", + "vue", + "typescript", + "tailwindcss", + "template", + "framework", + "development-tools", + "admin-panel", + "cms", + "authentication" + ], + "repository": { + "type": "git", + "url": "https://github.com/your-org/corrad-af" + }, + "bugs": { + "url": "https://github.com/your-org/corrad-af/issues" + }, + "homepage": "https://github.com/your-org/corrad-af#readme", "private": true, "scripts": { "build": "nuxt build", diff --git a/pages/BF-PRF/AS/DETAIL/[id]/index.vue b/pages/BF-PRF/AS/DETAIL/[id]/index.vue deleted file mode 100644 index 81c6af4..0000000 --- a/pages/BF-PRF/AS/DETAIL/[id]/index.vue +++ /dev/null @@ -1,674 +0,0 @@ - - - \ No newline at end of file diff --git a/pages/BF-PRF/AS/LIST/index.vue b/pages/BF-PRF/AS/LIST/index.vue deleted file mode 100644 index 00a279a..0000000 --- a/pages/BF-PRF/AS/LIST/index.vue +++ /dev/null @@ -1,337 +0,0 @@ - - - \ No newline at end of file diff --git a/pages/dashboard/index.vue b/pages/dashboard/index.vue index 361238f..2484307 100644 --- a/pages/dashboard/index.vue +++ b/pages/dashboard/index.vue @@ -11,328 +11,305 @@ definePageMeta({ ], }); -// Data baru untuk lapangan terbang teratas -const topAirports = ref([ - { - rank: 1, - name: "Lapangan Terbang Antarabangsa Kuala Lumpur (KLIA)", - visitors: 62000000, - }, - { - rank: 2, - name: "Lapangan Terbang Antarabangsa Kota Kinabalu", - visitors: 9000000, - }, - { rank: 3, name: "Lapangan Terbang Antarabangsa Penang", visitors: 8000000 }, - { rank: 4, name: "Lapangan Terbang Antarabangsa Kuching", visitors: 5500000 }, - { - rank: 5, - name: "Lapangan Terbang Antarabangsa Langkawi", - visitors: 3000000, - }, -]); - -// Data baru untuk kad ringkasan pantas -const quickSummary = ref([ - { title: "Jumlah Pelawat", value: "10.5 Juta", icon: "ic:outline-people" }, - { - title: "Pendapatan Pelancongan", - value: "RM 86.14 Bilion", - icon: "ic:outline-attach-money", - }, - { - title: "Tempoh Penginapan Purata", - value: "6.1 Hari", - icon: "ic:outline-hotel", - }, - { - title: "Kepuasan Pelancong", - value: "92%", - icon: "ic:outline-sentiment-satisfied", - }, -]); - -// Data Pelawat Malaysia -const visitorData = ref([ - { - name: "Pelawat Tempatan", - data: [5000000, 5500000, 6000000, 6500000, 7000000, 7500000], - }, - { - name: "Pelawat Asing", - data: [3000000, 3500000, 4000000, 4500000, 5000000, 5500000], - }, -]); - -// Data Pelawat Asing mengikut Negeri -const foreignVisitorsByState = ref([ - { state: "Selangor", visitors: 1500000 }, - { state: "Pulau Pinang", visitors: 1200000 }, - { state: "Johor", visitors: 1000000 }, - { state: "Sabah", visitors: 800000 }, - { state: "Sarawak", visitors: 600000 }, - { state: "Melaka", visitors: 500000 }, - { state: "Kedah", visitors: 400000 }, - { state: "Negeri Sembilan", visitors: 300000 }, - { state: "Perak", visitors: 250000 }, - { state: "Terengganu", visitors: 200000 }, - { state: "Kelantan", visitors: 150000 }, - { state: "Pahang", visitors: 100000 }, - { state: "Perlis", visitors: 50000 }, -]); - -// Lapangan Terbang Keberangkatan Teratas -const departureData = ref([ - { airport: "JFK", departures: 1500 }, - { airport: "LHR", departures: 1200 }, - { airport: "CDG", departures: 1000 }, - { airport: "DXB", departures: 800 }, - { airport: "SIN", departures: 600 }, -]); - -// Data Pelancong Berulang -const repeatVisitorsData = ref([ - { category: "1-2 kali", percentage: 45 }, - { category: "3-5 kali", percentage: 30 }, - { category: "6-10 kali", percentage: 15 }, - { category: ">10 kali", percentage: 10 }, -]); - -// Data Negara Asal Pelancong Asing Teratas -const topVisitorCountries = ref([ - { country: "Singapura", visitors: 1500000 }, - { country: "Indonesia", visitors: 1200000 }, - { country: "China", visitors: 1000000 }, - { country: "Thailand", visitors: 800000 }, - { country: "India", visitors: 600000 }, -]); - -const chartOptionsVisitors = computed(() => ({ - chart: { height: 350, type: "line" }, - stroke: { curve: "smooth", width: 2 }, - xaxis: { categories: ["2018", "2019", "2020", "2021", "2022", "2023"] }, - yaxis: { title: { text: "Bilangan Pelawat" } }, -})); - -const chartOptionsForeignVisitors = computed(() => ({ - chart: { type: "bar" }, - plotOptions: { bar: { horizontal: true } }, - xaxis: { categories: foreignVisitorsByState.value.map((item) => item.state) }, -})); - -const chartOptionsDeparture = computed(() => ({ - chart: { type: "bar" }, - plotOptions: { bar: { horizontal: true } }, - xaxis: { categories: departureData.value.map((item) => item.airport) }, -})); - -const chartOptionsRepeatVisitors = computed(() => ({ - chart: { type: "pie" }, - labels: repeatVisitorsData.value.map((item) => item.category), - responsive: [ - { - breakpoint: 480, - options: { - chart: { - width: 200, - }, - legend: { - position: "bottom", - }, - }, - }, - ], -})); - -const chartOptionsTopCountries = computed(() => ({ - chart: { type: "bar" }, - plotOptions: { - bar: { horizontal: false, columnWidth: "55%", endingShape: "rounded" }, - }, - dataLabels: { enabled: false }, - stroke: { show: true, width: 2, colors: ["transparent"] }, - xaxis: { categories: topVisitorCountries.value.map((item) => item.country) }, - yaxis: { title: { text: "Bilangan Pelawat" } }, - fill: { opacity: 1 }, - tooltip: { - y: { - formatter: function (val) { - return val.toLocaleString() + " pelawat"; - }, - }, - }, -})); - -onMounted(() => { - // Sebarang logik yang diperlukan semasa pemasangan +// Framework information +const frameworkInfo = ref({ + name: "corradAF", + version: "1.0.0", + description: "Corrad Application Framework - A comprehensive Nuxt.js template for rapid application development", + features: [ + "Authentication System", + "User Management", + "Role-based Access Control", + "Development Tools Suite", + "API Management", + "Menu Configuration", + "Content Management", + "Code Playground", + "ORM Integration", + "Responsive Design" + ] }); + +// Development tools available +const devTools = ref([ + { + title: "User Management", + description: "Manage users and roles with comprehensive CRUD operations", + icon: "mdi:account-group", + path: "/devtool/user-management/user", + color: "blue" + }, + { + title: "Menu Editor", + description: "Configure navigation menus and application structure", + icon: "mdi:menu", + path: "/devtool/menu-editor", + color: "green" + }, + { + title: "API Editor", + description: "Design and test API endpoints with interactive tools", + icon: "mdi:api", + path: "/devtool/api-editor", + color: "purple" + }, + { + title: "Content Editor", + description: "Manage dynamic content and templates", + icon: "mdi:file-document-edit", + path: "/devtool/content-editor", + color: "orange" + }, + { + title: "Code Playground", + description: "Test and prototype code snippets in real-time", + icon: "mdi:code-braces", + path: "/devtool/code-playground", + color: "indigo" + }, + { + title: "ORM Tools", + description: "Database schema management and query tools", + icon: "mdi:database", + path: "/devtool/orm", + color: "red" + }, + { + title: "Configuration", + description: "System settings and environment configuration", + icon: "mdi:cog", + path: "/devtool/config", + color: "gray" + } +]); + +// Quick stats +const quickStats = ref([ + { title: "Dev Tools", value: "7", icon: "mdi:tools" }, + { title: "Components", value: "50+", icon: "mdi:view-grid" }, + { title: "Auth System", value: "Ready", icon: "mdi:shield-check" }, + { title: "Framework", value: "Nuxt 3", icon: "mdi:nuxt" } +]); + +// Getting started steps +const gettingStarted = ref([ + { + step: 1, + title: "Clone Repository", + description: "Clone this template to start your new project", + command: "git clone your-project-name" + }, + { + step: 2, + title: "Install Dependencies", + description: "Install all required packages", + command: "yarn install" + }, + { + step: 3, + title: "Configure Environment", + description: "Set up your environment variables and database", + command: "cp .env.example .env" + }, + { + step: 4, + title: "Start Development", + description: "Run the development server", + command: "yarn dev" + } +]); + +function navigateToTool(path) { + navigateTo(path); +} + +function getColorClasses(color) { + const colorMap = { + blue: 'bg-blue-100 text-blue-600 hover:bg-blue-200', + green: 'bg-green-100 text-green-600 hover:bg-green-200', + purple: 'bg-purple-100 text-purple-600 hover:bg-purple-200', + orange: 'bg-orange-100 text-orange-600 hover:bg-orange-200', + indigo: 'bg-indigo-100 text-indigo-600 hover:bg-indigo-200', + red: 'bg-red-100 text-red-600 hover:bg-red-200', + gray: 'bg-gray-100 text-gray-600 hover:bg-gray-200' + }; + return colorMap[color] || 'bg-gray-100 text-gray-600 hover:bg-gray-200'; +} diff --git a/server/api/analyze-asnaf.post.ts b/server/api/analyze-asnaf.post.ts deleted file mode 100644 index 2034b0e..0000000 --- a/server/api/analyze-asnaf.post.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { defineEventHandler, readBody } from 'h3'; - -// Define an interface for the expected request body (subset of AsnafProfile) -interface AsnafAnalysisRequest { - monthlyIncome: string; - otherIncome: string; - totalIncome: string; - occupation: string; - maritalStatus: string; - dependents: Array; // Or a more specific type if you have one for dependents - // Add any other fields you deem necessary for OpenAI to analyze -} - -interface AidSuggestion { - nama: string; - peratusan: string; -} - -// Define an interface for the expected OpenAI response structure (and our API response) -interface AsnafAnalysisResponse { - hadKifayahPercentage: string; - kategoriAsnaf: string; - kategoriKeluarga: string; - cadanganKategori: string; - statusKelayakan: string; - cadanganBantuan: AidSuggestion[]; - ramalanJangkaMasaPulih: string; - rumusan: string; -} - -export default defineEventHandler(async (event): Promise => { - const body = await readBody(event); - - // --- Placeholder for Actual OpenAI API Call --- - // In a real application, you would: - // 1. Retrieve your OpenAI API key securely (e.g., from environment variables) - const openAIApiKey = process.env.OPENAI_API_KEY; - if (!openAIApiKey) { - console.error('OpenAI API key not configured. Please set OPENAI_API_KEY in your .env file.'); - throw createError({ statusCode: 500, statusMessage: 'OpenAI API key not configured' }); - } - - // 2. Construct the prompt for OpenAI using the data from `body`. - // IMPORTANT: Sanitize or carefully construct any data from `body` included in the prompt to prevent prompt injection. - const prompt = `You are an expert Zakat administrator. Based on the following applicant data: monthlyIncome: ${body.monthlyIncome}, totalIncome: ${body.totalIncome}, occupation: ${body.occupation}, maritalStatus: ${body.maritalStatus}, dependents: ${body.dependents.length}. -Return JSON with keys: hadKifayahPercentage, kategoriAsnaf, kategoriKeluarga, cadanganKategori, statusKelayakan, cadanganBantuan, ramalanJangkaMasaPulih, rumusan. -For 'cadanganBantuan', provide a JSON array of objects, where each object has a 'nama' (string, name of the aid) and 'peratusan' (string, e.g., '85%', representing suitability). Suggest 2-3 most relevant aid types. -Example for cadanganBantuan: [{"nama": "Bantuan Kewangan Bulanan", "peratusan": "90%"}, {"nama": "Bantuan Makanan Asas", "peratusan": "75%"}]. -Full JSON Example: {"hadKifayahPercentage": "75%", ..., "cadanganBantuan": [{"nama": "Bantuan Kewangan Bulanan", "peratusan": "90%"}], ...}`; - // Adjust the prompt to be more detailed and specific to your needs and desired JSON output structure. - - // 3. Make the API call to OpenAI - try { - const openAIResponse = await fetch('https://api.openai.com/v1/chat/completions', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${openAIApiKey}`, - }, - body: JSON.stringify({ - model: 'gpt-3.5-turbo', // Or your preferred model like gpt-4 - messages: [{ role: 'user', content: prompt }], - // For more consistent JSON output, consider using a model version that officially supports JSON mode if available - // and set response_format: { type: "json_object" }, (check OpenAI documentation for model compatibility) - }), - }); - - if (!openAIResponse.ok) { - const errorData = await openAIResponse.text(); - console.error('OpenAI API Error details:', errorData); - throw createError({ statusCode: openAIResponse.status, statusMessage: `Failed to get analysis from OpenAI: ${openAIResponse.statusText}` }); - } - - const openAIData = await openAIResponse.json(); - - // Parse the content from the response - structure might vary slightly based on OpenAI model/API version - // It's common for the JSON string to be in openAIData.choices[0].message.content - if (openAIData.choices && openAIData.choices[0] && openAIData.choices[0].message && openAIData.choices[0].message.content) { - const analysisResult = JSON.parse(openAIData.choices[0].message.content) as AsnafAnalysisResponse; - return analysisResult; - } else { - console.error('OpenAI response structure not as expected:', openAIData); - throw createError({ statusCode: 500, statusMessage: 'Unexpected response structure from OpenAI' }); - } - - } catch (error) { - console.error('Error during OpenAI API call or parsing:', error); - // Avoid exposing detailed internal errors to the client if they are not createError objects - if (typeof error === 'object' && error !== null && 'statusCode' in error) { - // We can infer error has statusCode here, but to be super safe with TS: - const e = error as { statusCode: number }; - if (e.statusCode) throw e; - } - throw createError({ statusCode: 500, statusMessage: 'Internal server error during AI analysis' }); - } - // --- End of Actual OpenAI API Call --- - - // The simulated response below this line should be REMOVED once the actual OpenAI call is implemented and working. - /* - console.log('Received for analysis in server route:', body); - await new Promise(resolve => setTimeout(resolve, 2000)); // Simulate API delay - - const totalIncomeNumeric = parseFloat(body.totalIncome); - let percentage = '50%'; - if (totalIncomeNumeric < 1000) percentage = '30%'; - else if (totalIncomeNumeric < 2000) percentage = '65%'; - else if (totalIncomeNumeric < 3000) percentage = '85%'; - else percentage = '110%'; - - return { - hadKifayahPercentage: percentage, - kategoriAsnaf: 'Simulated - Miskin', - kategoriKeluarga: 'Simulated - Miskin (50-100% HK)', - cadanganKategori: 'Simulated - Miskin', - statusKelayakan: 'Simulated - Layak (Miskin)', - cadanganBantuan: [ - { nama: 'Simulated - Bantuan Kewangan Bulanan', peratusan: '80%' }, - { nama: 'Simulated - Bantuan Pendidikan Anak', peratusan: '65%' } - ], - ramalanJangkaMasaPulih: 'Simulated - 6 bulan', - rumusan: 'Simulated - Pemohon memerlukan perhatian segera.' - }; - */ -}); \ No newline at end of file