Spaces:
Running
Running
Perfect ✅ Here’s the final English Master Prompt with mandatory Admin Manual Approval for Company/Restaurant accounts included: ⸻ 🧠 MASTER IMPLEMENTATION PROMPT (English, with Admin Approval) Generate a complete full-stack project (Django + Flutter) with NFC, subscriptions, coupons, CRM, and enterprise-grade security. The solution must include all source code, documentation, and deployment setup. ⸻ 🎯 Project Goal Build an ecosystem with: 1. Backend: Django + DRF, JWT + MFA, role-based access, NFC card handling, subscriptions, payments, coupons, orders, notifications. 2. Frontend/App: Flutter (Web, Android, iOS, Windows, macOS), responsive 3D UI, animations, organization & restaurant profiles, billing, NFC scanning. 3. NFC Bridge Service: Python background service to read cards, hash UID, send securely to backend. 4. CRM/Admin Panel: Manage users, subscriptions, organizations, restaurants, NFC cards, coupons, reports. 5. Deployment: Docker + CI/CD + Monitoring. ⸻ 🔐 Security • JWT (access/refresh) with rotation. • MFA support. • RBAC with per-organization roles. • Encrypted sensitive fields. • Audit logging. • Static analysis (ruff, mypy, bandit, safety). • Automated backups. ⸻ 🗃️ Data Models (Highlights) • User + Profile + Link quotas. • Organization: (company/restaurant) with: • business_license_file (required upload). • employees_count (must be declared). • Admin Manual Approval required before activation. • OrgMembership with roles (employee, supervisor, admin, cook, accountant, delivery, etc.). • RestaurantProfile: menus, sections, items. • NFC: cards, assignments, reader devices, scan events. • Billing: plans, subscriptions, coupons, invoices. • Orders: card orders, shipments. • Notifications: in-app + email/SMS. ⸻ 🧩 REST APIs • Auth: register, login, MFA verify. • Profile: update, links (quota). • Organizations: CRUD with business license upload, employees count, approval workflow. • Restaurants: menus. • NFC: assign cards, scan, resolve profile. • Billing: plans, subscribe, coupons, payments. • CRM/Admin: approve/reject organizations, manage everything. ⸻ 📱 Flutter App • Auth (register/login). • Profile & links. • Company/Restaurant signup flow with license upload + employees count. • Pending state until Admin approval. • Subscriptions, payments, coupons. • Responsive 3D UI with Rive animations. • Multi-platform (Web, Mobile, Desktop). ⸻ 🔌 NFC Bridge • Read card UID. • SHA-256 + SALT hash. • Send with HMAC signature. • Run as systemd/Windows service. ⸻ 💳 Payments • Subscription plans. • Auto-renewal. • Coupons. • Webhooks from Stripe/Paymob/MyFatoorah. ⸻ 🖥️ CRM/Admin • Admin dashboard (Django Admin or Flutter web). • View pending Companies/Restaurants. • Approve/reject based on uploaded license. • Manage subscriptions, coupons, reports, NFC scans. ⸻ 🧪 Tests • Pytest (85%+ coverage). • Flutter integration + golden tests. • CI/CD pipeline. ⸻ ✅ Acceptance Criteria 1. Organization (Company/Restaurant) must upload a valid Business License and declare employees count. 2. Organization remains in Pending status until Admin approves it. 3. Once approved, members can join and roles are enforced. 4. All APIs documented with Swagger. 5. Flutter app responsive on all devices. 6. NFC scanning works with backend. 7. All tests pass. ⸻ 👉 Do you want me to now convert this into a ready-to-run scaffold (Django + Flutter project structure with placeholder code) so you can start coding immediately? - Initial Deployment
20457ff
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>NFC Ecosystem Platform</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .animate-fade-in { | |
| animation: fadeIn 0.5s ease-out forwards; | |
| } | |
| .card-hover { | |
| transition: all 0.3s ease; | |
| } | |
| .card-hover:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); | |
| } | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #6b46c1 0%, #4299e1 100%); | |
| } | |
| .nfc-scan-animation { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(66, 153, 225, 0.4); } | |
| 70% { box-shadow: 0 0 0 15px rgba(66, 153, 225, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(66, 153, 225, 0); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 font-sans"> | |
| <!-- Navigation --> | |
| <nav class="bg-white shadow-lg"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <div class="flex justify-between h-16"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 flex items-center"> | |
| <i class="fas fa-id-card text-indigo-600 text-2xl mr-2"></i> | |
| <span class="text-xl font-bold text-gray-900">NFC Ecosystem</span> | |
| </div> | |
| <div class="hidden sm:ml-6 sm:flex sm:space-x-8"> | |
| <a href="#" class="border-indigo-500 text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Dashboard</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Organizations</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">NFC Cards</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Billing</a> | |
| </div> | |
| </div> | |
| <div class="hidden sm:ml-6 sm:flex sm:items-center"> | |
| <div class="ml-3 relative"> | |
| <div> | |
| <button type="button" class="bg-white rounded-full flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" id="user-menu-button" aria-expanded="false" aria-haspopup="true"> | |
| <span class="sr-only">Open user menu</span> | |
| <div class="h-8 w-8 rounded-full bg-indigo-100 flex items-center justify-center"> | |
| <span class="text-indigo-600 font-medium">JD</span> | |
| </div> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="-mr-2 flex items-center sm:hidden"> | |
| <button type="button" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-controls="mobile-menu" aria-expanded="false"> | |
| <span class="sr-only">Open main menu</span> | |
| <i class="fas fa-bars"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Mobile menu, show/hide based on menu state. --> | |
| <div class="sm:hidden hidden" id="mobile-menu"> | |
| <div class="pt-2 pb-3 space-y-1"> | |
| <a href="#" class="bg-indigo-50 border-indigo-500 text-indigo-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Dashboard</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Organizations</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">NFC Cards</a> | |
| <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Billing</a> | |
| </div> | |
| <div class="pt-4 pb-3 border-t border-gray-200"> | |
| <div class="flex items-center px-4"> | |
| <div class="flex-shrink-0"> | |
| <div class="h-10 w-10 rounded-full bg-indigo-100 flex items-center justify-center"> | |
| <span class="text-indigo-600 font-medium">JD</span> | |
| </div> | |
| </div> | |
| <div class="ml-3"> | |
| <div class="text-base font-medium text-gray-800">John Doe</div> | |
| <div class="text-sm font-medium text-gray-500">john@example.com</div> | |
| </div> | |
| </div> | |
| <div class="mt-3 space-y-1"> | |
| <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:text-gray-800 hover:bg-gray-100">Your Profile</a> | |
| <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:text-gray-800 hover:bg-gray-100">Settings</a> | |
| <a href="#" class="block px-4 py-2 text-base font-medium text-gray-500 hover:text-gray-800 hover:bg-gray-100">Sign out</a> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Main Content --> | |
| <div class="py-10"> | |
| <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> | |
| <!-- Admin Approval Section --> | |
| <div class="px-4 sm:px-0 mb-10"> | |
| <h2 class="text-2xl font-bold text-gray-900 mb-2">Pending Approvals</h2> | |
| <p class="text-gray-600">Review and approve new company/restaurant registrations</p> | |
| <div class="mt-6 bg-white shadow overflow-hidden sm:rounded-lg"> | |
| <div class="px-4 py-5 sm:px-6 border-b border-gray-200"> | |
| <h3 class="text-lg leading-6 font-medium text-gray-900">Organizations Awaiting Approval</h3> | |
| <p class="mt-1 text-sm text-gray-500">These organizations have submitted their business licenses and are pending your review.</p> | |
| </div> | |
| <div class="bg-white overflow-hidden sm:rounded-md"> | |
| <ul class="divide-y divide-gray-200"> | |
| <li class="animate-fade-in"> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center"> | |
| <div class="min-w-0 flex-1 flex items-center"> | |
| <div class="flex-shrink-0"> | |
| <div class="h-12 w-12 rounded-full bg-blue-100 flex items-center justify-center"> | |
| <i class="fas fa-utensils text-blue-600"></i> | |
| </div> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-indigo-600 truncate">Gourmet Delights Restaurant</div> | |
| <div class="flex items-center text-sm text-gray-500"> | |
| <span>Submitted: 2 days ago</span> | |
| <span class="mx-1">•</span> | |
| <span>15 employees</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="ml-2 flex-shrink-0 flex"> | |
| <button onclick="showLicenseModal('Gourmet Delights Restaurant', 'restaurant_license.pdf')" class="mr-2 inline-flex items-center px-3 py-1 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
| View License | |
| </button> | |
| <button onclick="approveOrganization('org_123')" class="inline-flex items-center px-3 py-1 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> | |
| Approve | |
| </button> | |
| <button onclick="rejectOrganization('org_123')" class="ml-2 inline-flex items-center px-3 py-1 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"> | |
| Reject | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| <li class="animate-fade-in" style="animation-delay: 0.1s;"> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center"> | |
| <div class="min-w-0 flex-1 flex items-center"> | |
| <div class="flex-shrink-0"> | |
| <div class="h-12 w-12 rounded-full bg-purple-100 flex items-center justify-center"> | |
| <i class="fas fa-building text-purple-600"></i> | |
| </div> | |
| </div> | |
| <div class="ml-4"> | |
| <div class="text-sm font-medium text-indigo-600 truncate">Tech Solutions Inc.</div> | |
| <div class="flex items-center text-sm text-gray-500"> | |
| <span>Submitted: 1 day ago</span> | |
| <span class="mx-1">•</span> | |
| <span>42 employees</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="ml-2 flex-shrink-0 flex"> | |
| <button onclick="showLicenseModal('Tech Solutions Inc.', 'business_license.pdf')" class="mr-2 inline-flex items-center px-3 py-1 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
| View License | |
| </button> | |
| <button onclick="approveOrganization('org_456')" class="inline-flex items-center px-3 py-1 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"> | |
| Approve | |
| </button> | |
| <button onclick="rejectOrganization('org_456')" class="ml-2 inline-flex items-center px-3 py-1 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"> | |
| Reject | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Dashboard Stats --> | |
| <div class="px-4 sm:px-0 mb-10"> | |
| <h2 class="text-2xl font-bold text-gray-900 mb-6">System Overview</h2> | |
| <div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-4"> | |
| <!-- Active Organizations --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-indigo-500 rounded-md p-3"> | |
| <i class="fas fa-building text-white"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <dt class="text-sm font-medium text-gray-500 truncate"> | |
| Active Organizations | |
| </dt> | |
| <dd class="flex items-baseline"> | |
| <div class="text-2xl font-semibold text-gray-900"> | |
| 42 | |
| </div> | |
| <div class="ml-2 flex items-baseline text-sm font-semibold text-green-600"> | |
| <i class="fas fa-arrow-up text-xs"></i> | |
| <span class="sr-only">Increased by</span> | |
| 12% | |
| </div> | |
| </dd> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- NFC Cards Issued --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-blue-500 rounded-md p-3"> | |
| <i class="fas fa-id-card text-white"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <dt class="text-sm font-medium text-gray-500 truncate"> | |
| NFC Cards Issued | |
| </dt> | |
| <dd class="flex items-baseline"> | |
| <div class="text-2xl font-semibold text-gray-900"> | |
| 1,248 | |
| </div> | |
| <div class="ml-2 flex items-baseline text-sm font-semibold text-green-600"> | |
| <i class="fas fa-arrow-up text-xs"></i> | |
| <span class="sr-only">Increased by</span> | |
| 24% | |
| </div> | |
| </dd> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Active Subscriptions --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-green-500 rounded-md p-3"> | |
| <i class="fas fa-dollar-sign text-white"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <dt class="text-sm font-medium text-gray-500 truncate"> | |
| Active Subscriptions | |
| </dt> | |
| <dd class="flex items-baseline"> | |
| <div class="text-2xl font-semibold text-gray-900"> | |
| 38 | |
| </div> | |
| <div class="ml-2 flex items-baseline text-sm font-semibold text-green-600"> | |
| <i class="fas fa-arrow-up text-xs"></i> | |
| <span class="sr-only">Increased by</span> | |
| 8% | |
| </div> | |
| </dd> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Pending Approvals --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-yellow-500 rounded-md p-3"> | |
| <i class="fas fa-clock text-white"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <dt class="text-sm font-medium text-gray-500 truncate"> | |
| Pending Approvals | |
| </dt> | |
| <dd class="flex items-baseline"> | |
| <div class="text-2xl font-semibold text-gray-900"> | |
| 2 | |
| </div> | |
| </dd> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Activity and NFC Scanner --> | |
| <div class="px-4 sm:px-0 mb-10"> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Recent Activity --> | |
| <div class="lg:col-span-2"> | |
| <h2 class="text-2xl font-bold text-gray-900 mb-6">Recent Activity</h2> | |
| <div class="bg-white shadow overflow-hidden sm:rounded-lg"> | |
| <ul class="divide-y divide-gray-200"> | |
| <li> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-green-100 rounded-full p-2"> | |
| <i class="fas fa-check-circle text-green-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-gray-900">Organization "Cafe Bella" was approved</p> | |
| <p class="text-sm text-gray-500">2 hours ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| <li> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-blue-100 rounded-full p-2"> | |
| <i class="fas fa-id-card text-blue-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-gray-900">New NFC card registered (UID: 4A3B2C1D)</p> | |
| <p class="text-sm text-gray-500">5 hours ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| <li> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-purple-100 rounded-full p-2"> | |
| <i class="fas fa-user-plus text-purple-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-gray-900">New user registered: restaurant_manager@example.com</p> | |
| <p class="text-sm text-gray-500">1 day ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| <li> | |
| <div class="px-4 py-4 sm:px-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-yellow-100 rounded-full p-2"> | |
| <i class="fas fa-exclamation-triangle text-yellow-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-gray-900">Organization "Quick Bites" requires license verification</p> | |
| <p class="text-sm text-gray-500">2 days ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <!-- NFC Scanner --> | |
| <div> | |
| <h2 class="text-2xl font-bold text-gray-900 mb-6">NFC Card Scanner</h2> | |
| <div class="bg-white shadow overflow-hidden sm:rounded-lg p-6"> | |
| <div class="text-center"> | |
| <div class="mx-auto flex items-center justify-center h-32 w-32 rounded-full bg-blue-100 nfc-scan-animation mb-6"> | |
| <i class="fas fa-rss text-blue-600 text-4xl"></i> | |
| </div> | |
| <h3 class="text-lg font-medium text-gray-900">Scan NFC Card</h3> | |
| <p class="mt-2 text-sm text-gray-500">Place the NFC card near the reader to register or identify it</p> | |
| <div class="mt-6"> | |
| <button onclick="startNFCScan()" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
| <i class="fas fa-play mr-2"></i> Start Scanning | |
| </button> | |
| </div> | |
| </div> | |
| <div id="scanResult" class="mt-6 hidden"> | |
| <div class="rounded-md bg-green-50 p-4"> | |
| <div class="flex"> | |
| <div class="flex-shrink-0"> | |
| <i class="fas fa-check-circle text-green-400"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <h3 class="text-sm font-medium text-green-800">Card Scanned Successfully</h3> | |
| <div class="mt-2 text-sm text-green-700"> | |
| <p>Card UID: <span id="cardUID" class="font-mono">4A3B2C1D</span></p> | |
| <p class="mt-1">Card Type: <span id="cardType">Employee Access</span></p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Organizations --> | |
| <div class="px-4 sm:px-0"> | |
| <h2 class="text-2xl font-bold text-gray-900 mb-6">Recent Organizations</h2> | |
| <div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3"> | |
| <!-- Organization Card 1 --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-indigo-100 rounded-md p-3"> | |
| <i class="fas fa-utensils text-indigo-600"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <h3 class="text-lg font-medium text-gray-900">Gourmet Delights</h3> | |
| <p class="text-sm text-gray-500 truncate">Restaurant • 15 employees</p> | |
| <div class="mt-2"> | |
| <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"> | |
| <i class="fas fa-check-circle mr-1"></i> Active | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex justify-between text-sm text-gray-500"> | |
| <span>Subscribed: Premium</span> | |
| <span>Since: 12/05/2023</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-4 sm:px-6"> | |
| <div class="text-sm"> | |
| <a href="#" class="font-medium text-indigo-600 hover:text-indigo-500"> View details<span class="sr-only"> Gourmet Delights</span></a> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Organization Card 2 --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-blue-100 rounded-md p-3"> | |
| <i class="fas fa-building text-blue-600"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <h3 class="text-lg font-medium text-gray-900">Tech Solutions Inc.</h3> | |
| <p class="text-sm text-gray-500 truncate">Company • 42 employees</p> | |
| <div class="mt-2"> | |
| <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800"> | |
| <i class="fas fa-check-circle mr-1"></i> Active | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex justify-between text-sm text-gray-500"> | |
| <span>Subscribed: Enterprise</span> | |
| <span>Since: 10/15/2023</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-4 sm:px-6"> | |
| <div class="text-sm"> | |
| <a href="#" class="font-medium text-indigo-600 hover:text-indigo-500"> View details<span class="sr-only"> Tech Solutions Inc.</span></a> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Organization Card 3 --> | |
| <div class="bg-white overflow-hidden shadow rounded-lg card-hover"> | |
| <div class="px-4 py-5 sm:p-6"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 bg-purple-100 rounded-md p-3"> | |
| <i class="fas fa-coffee text-purple-600"></i> | |
| </div> | |
| <div class="ml-5 w-0 flex-1"> | |
| <h3 class="text-lg font-medium text-gray-900">Cafe Bella</h3> | |
| <p class="text-sm text-gray-500 truncate">Restaurant • 8 employees</p> | |
| <div class="mt-2"> | |
| <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800"> | |
| <i class="fas fa-clock mr-1"></i> Pending | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex justify-between text-sm text-gray-500"> | |
| <span>Plan: Basic</span> | |
| <span>Registered: 2 days ago</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-4 sm:px-6"> | |
| <div class="text-sm"> | |
| <a href="#" class="font-medium text-indigo-600 hover:text-indigo-500"> Review application<span class="sr-only"> Cafe Bella</span></a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- License Modal --> | |
| <div id="licenseModal" class="fixed z-10 inset-0 overflow-y-auto hidden"> | |
| <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> | |
| <div class="fixed inset-0 transition-opacity" aria-hidden="true"> | |
| <div class="absolute inset-0 bg-gray-500 opacity-75"></div> | |
| </div> | |
| <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span> | |
| <div class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full sm:p-6"> | |
| <div> | |
| <div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-blue-100"> | |
| <i class="fas fa-file-alt text-blue-600"></i> | |
| </div> | |
| <div class="mt-3 text-center sm:mt-5"> | |
| <h3 class="text-lg leading-6 font-medium text-gray-900" id="modalTitle">Business License</h3> | |
| <div class="mt-2"> | |
| <p class="text-sm text-gray-500">Review the submitted business license for <span id="orgName" class="font-medium">Organization Name</span></p> | |
| </div> | |
| <div class="mt-4 border-2 border-dashed border-gray-300 rounded-lg p-4"> | |
| <div class="flex justify-center"> | |
| <i class="fas fa-file-pdf text-5xl text-red-500"></i> | |
| </div> | |
| <p class="mt-2 text-sm text-gray-600 text-center" id="fileName">business_license.pdf</p> | |
| <div class="mt-4"> | |
| <button onclick="downloadLicense()" class="inline-flex items-center px-3 py-1 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"> | |
| <i class="fas fa-download mr-2"></i> Download License | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense"> | |
| <button onclick="approveFromModal()" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:col-start-2 sm:text-sm"> | |
| Approve Organization | |
| </button> | |
| <button onclick="closeLicenseModal()" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:col-start-1 sm:text-sm"> | |
| Close | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Success Notification --> | |
| <div id="successNotification" class="fixed bottom-4 right-4 hidden"> | |
| <div class="rounded-md bg-green-50 p-4 shadow-lg"> | |
| <div class="flex"> | |
| <div class="flex-shrink-0"> | |
| <i class="fas fa-check-circle text-green-400"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <p class="text-sm font-medium text-green-800" id="successMessage">Action completed successfully</p> | |
| </div> | |
| <div class="ml-auto pl-3"> | |
| <div class="-mx-1.5 -my-1.5"> | |
| <button onclick="hideSuccessNotification()" type="button" class="inline-flex bg-green-50 rounded-md p-1.5 text-green-500 hover:bg-green-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-600"> | |
| <span class="sr-only">Dismiss</span> | |
| <i class="fas fa-times h-5 w-5"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Mobile menu toggle | |
| document.querySelector('[aria-controls="mobile-menu"]').addEventListener('click', function() { | |
| const menu = document.getElementById('mobile-menu'); | |
| menu.classList.toggle('hidden'); | |
| }); | |
| // License modal functions | |
| let currentOrgId = ''; | |
| function showLicenseModal(orgName, fileName, orgId) { | |
| document.getElementById('orgName').textContent = orgName; | |
| document.getElementById('fileName').textContent = fileName; | |
| document.getElementById('licenseModal').classList.remove('hidden'); | |
| currentOrgId = orgId || ''; | |
| } | |
| function closeLicenseModal() { | |
| document.getElementById('licenseModal').classList.add('hidden'); | |
| currentOrgId = ''; | |
| } | |
| function approveFromModal() { | |
| if (currentOrgId) { | |
| approveOrganization(currentOrgId); | |
| } | |
| closeLicenseModal(); | |
| } | |
| function downloadLicense() { | |
| showSuccessNotification('License download started'); | |
| // In a real app, this would trigger a file download | |
| } | |
| // Organization approval functions | |
| function approveOrganization(orgId) { | |
| console.log(`Approving organization ${orgId}`); | |
| // In a real app, this would make an API call | |
| showSuccessNotification('Organization approved successfully'); | |
| // Remove the approved item from the UI | |
| setTimeout(() => { | |
| document.querySelector(`[data-org-id="${orgId}"]`)?.remove(); | |
| }, 500); | |
| } | |
| function rejectOrganization(orgId) { | |
| console.log(`Rejecting organization ${orgId}`); | |
| // In a real app, this would make an API call | |
| showSuccessNotification('Organization rejected'); | |
| // Remove the rejected item from the UI | |
| setTimeout(() => { | |
| document.querySelector(`[data-org-id="${orgId}"]`)?.remove(); | |
| }, 500); | |
| } | |
| // NFC Scanner functions | |
| function startNFCScan() { | |
| console.log('Starting NFC scan...'); | |
| // Simulate scan after 2 seconds | |
| setTimeout(() => { | |
| document.getElementById('scanResult').classList.remove('hidden'); | |
| showSuccessNotification('NFC card scanned successfully'); | |
| }, 2000); | |
| } | |
| // Notification functions | |
| function showSuccessNotification(message) { | |
| const notification = document.getElementById('successNotification'); | |
| document.getElementById('successMessage').textContent = message; | |
| notification.classList.remove('hidden'); | |
| // Auto-hide after 5 seconds | |
| setTimeout(() => { | |
| notification.classList.add('hidden'); | |
| }, 5000); | |
| } | |
| function hideSuccessNotification() { | |
| document.getElementById('successNotification').classList.add('hidden'); | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ahmedeldesoky284/nfcpro" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |