├── public ├── logo.png ├── mixkit.wav ├── chat-up.mp3 ├── lyra-ai.png ├── lyra-mob.png ├── voice │ ├── greeting_formal.mp3 │ ├── greeting_genz.mp3 │ ├── greeting_jualan.mp3 │ └── greeting_default.mp3 ├── success.html ├── under-construction │ └── index.html └── vite.svg ├── src ├── assets │ ├── lyra-ai.png │ └── lyra-mob.png ├── modules │ ├── limitModal.js │ ├── intentHandler.admin.js │ ├── renderSingleProductCard.js │ ├── htmlRenderer.js │ ├── productStore.js │ ├── adminAuth.js │ ├── cdnAdminAuth.js │ ├── CartManager.js │ ├── authHandler.js │ ├── intentHandler.js │ ├── chatRenderer.js │ └── checkoutHandler.js ├── api │ ├── firebase-config.js │ ├── checkout.js │ └── detect-intent-api.js ├── 404.html ├── javascript.svg ├── pages │ ├── AdminLogin.js │ ├── success.js │ ├── AdminPanel.js │ └── ChatTelegram.js ├── style.css └── main.js ├── vercel.json ├── tailwind.config.js ├── vite.config.js ├── .gitignore ├── .env.sample ├── package.json ├── index.html └── README.md /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/mixkit.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/mixkit.wav -------------------------------------------------------------------------------- /public/chat-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/chat-up.mp3 -------------------------------------------------------------------------------- /public/lyra-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/lyra-ai.png -------------------------------------------------------------------------------- /public/lyra-mob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/lyra-mob.png -------------------------------------------------------------------------------- /src/assets/lyra-ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/src/assets/lyra-ai.png -------------------------------------------------------------------------------- /src/assets/lyra-mob.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/src/assets/lyra-mob.png -------------------------------------------------------------------------------- /public/voice/greeting_formal.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/voice/greeting_formal.mp3 -------------------------------------------------------------------------------- /public/voice/greeting_genz.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/voice/greeting_genz.mp3 -------------------------------------------------------------------------------- /public/voice/greeting_jualan.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/voice/greeting_jualan.mp3 -------------------------------------------------------------------------------- /public/voice/greeting_default.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daffadevhosting/lyra-ai-chat/HEAD/public/voice/greeting_default.mp3 -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { "source": "/(.*)", "destination": "/" }, 4 | { "source": "/success", "destination": "/success.html" } 5 | 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | content: [ 3 | "./index.html", 4 | "./src/**/*.{js,html}" 5 | ], 6 | darkMode: 'class', 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | 13 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import tailwindcss from '@tailwindcss/vite' 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | tailwindcss(), 7 | ], 8 | root: './', 9 | server: { 10 | port: 3000, 11 | open: false, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /src/modules/limitModal.js: -------------------------------------------------------------------------------- 1 | export function showLimitModal() { 2 | const modal = document.getElementById('loginModal'); 3 | if (modal) modal.classList.remove('hide'); 4 | } 5 | 6 | export function hideLimitModal() { 7 | const modal = document.getElementById('loginModal'); 8 | if (modal) modal.classList.add('hide'); 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | package-lock.json 10 | 11 | node_modules 12 | dist 13 | dist-ssr 14 | *.local 15 | .env 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /src/api/firebase-config.js: -------------------------------------------------------------------------------- 1 | // src/firebase-config.js 2 | import { initializeApp } from "firebase/app"; 3 | 4 | const firebaseConfig = { 5 | apiKey: import.meta.env.VITE_FIREBASE_API_KEY, 6 | authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, 7 | projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID, 8 | appId: import.meta.env.VITE_FIREBASE_APP_ID 9 | }; 10 | 11 | export const app = initializeApp(firebaseConfig); 12 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # Firebase 2 | VITE_FIREBASE_API_KEY=xxx 3 | VITE_FIREBASE_PROJECT_ID=xxx 4 | VITE_FIREBASE_APP_ID=xxx 5 | 6 | # Groq / OpenAI 7 | VITE_GROQ_API_KEY=xxx 8 | 9 | # Midtrans 10 | VITE_MIDTRANS_CLIENT_KEY=SB-Mid-client-xxx 11 | VITE_MIDTRANS_SERVER_KEY=SB-Mid-server-xxx (backend only!) 12 | 13 | # FingerprintJS 14 | VITE_FINGERPRINT_PUBLIC_KEY=xxx 15 | 16 | # Optional 17 | VITE_APP_NAME=LYRA 18 | VITE_BASE_URL=https://lyra-ai-nine.vercel.app 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "toko-ai", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "vite": "^6.3.5" 13 | }, 14 | "dependencies": { 15 | "@tailwindcss/vite": "^4.1.10", 16 | "firebase": "^11.9.1", 17 | "lucide": "^0.515.0", 18 | "midtrans-client": "^1.4.3", 19 | "tailwindcss": "^4.1.10" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /public/success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |Yah, halaman yang kamu cari gak ada 😢
11 | Kembali ke Beranda 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/modules/intentHandler.admin.js: -------------------------------------------------------------------------------- 1 | import { getFirestore, collection, addDoc, getDocs, deleteDoc, doc } from 'firebase/firestore'; 2 | const db = getFirestore(); 3 | 4 | const intentCol = collection(db, 'intents'); 5 | 6 | export async function addIntent(trigger, response, mode) { 7 | return await addDoc(intentCol, { trigger, response, mode }); 8 | } 9 | 10 | export async function fetchAllIntents() { 11 | const snap = await getDocs(intentCol); 12 | return snap.docs.map(d => ({ id: d.id, ...d.data() })); 13 | } 14 | 15 | export async function deleteIntent(id) { 16 | return await deleteDoc(doc(db, 'intents', id)); 17 | } 18 | -------------------------------------------------------------------------------- /src/modules/renderSingleProductCard.js: -------------------------------------------------------------------------------- 1 | 2 | export function renderSingleProductCardHTML(product) { 3 | return ` 4 |${product.description?.slice(0, 80)}...
9 | 14 |Fitur ini belum siap tayang, tapi L Y Я A dan tim lagi ngebut ngerjainnya! 💪
12 | Balik ke Beranda 13 |