diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/package-lock.json b/package-lock.json index d11406c..0d6e660 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,9 @@ "@vitejs/plugin-react": "^5.0.0", "typescript": "~5.8.2", "vite": "^6.2.0" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@babel/code-frame": { @@ -1682,9 +1685,9 @@ "license": "BSD-3-Clause" }, "node_modules/caniuse-lite": { - "version": "1.0.30001765", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001765.tgz", - "integrity": "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==", + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "dev": true, "funding": [ { @@ -1919,9 +1922,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.277", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.277.tgz", - "integrity": "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw==", + "version": "1.5.278", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.278.tgz", + "integrity": "sha512-dQ0tM1svDRQOwxnXxm+twlGTjr9Upvt8UFWAgmLsxEzFQxhbti4VwxmMjsDxVC51Zo84swW7FVCXEV+VAkhuPw==", "dev": true, "license": "ISC" }, diff --git a/package.json b/package.json index 873fcee..f8a6574 100644 --- a/package.json +++ b/package.json @@ -3,18 +3,21 @@ "private": true, "version": "0.0.0", "type": "module", + "engines": { + "node": ">=18.0.0" + }, "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { - "react": "^19.2.3", + "@cloudinary/react": "^1.13.0", + "@cloudinary/url-gen": "^1.19.0", "@google/genai": "^1.37.0", + "react": "^19.2.3", "react-dom": "^19.2.3", - "recharts": "^3.6.0", - "@cloudinary/react": "^1.13.0", - "@cloudinary/url-gen": "^1.19.0" + "recharts": "^3.6.0" }, "devDependencies": { "@types/node": "^22.14.0", diff --git a/services/cloudinaryService.ts b/services/cloudinaryService.ts index e292f97..398af09 100644 --- a/services/cloudinaryService.ts +++ b/services/cloudinaryService.ts @@ -1,10 +1,10 @@ // services/cloudinaryService.ts import { Cloudinary } from '@cloudinary/url-gen'; -// These will be set via environment variables +// These will be set via environment variables - using import.meta.env for Vite export const CLOUDINARY_CONFIG = { - cloudName: process.env.VITE_CLOUDINARY_CLOUD_NAME || 'demo', - uploadPreset: process.env.VITE_CLOUDINARY_UPLOAD_PRESET || 'unsigned_upload' + cloudName: import.meta.env.VITE_CLOUDINARY_CLOUD_NAME || 'demo', + uploadPreset: import.meta.env.VITE_CLOUDINARY_UPLOAD_PRESET || 'unsigned_upload' }; // Warn if using default values diff --git a/services/geminiService.ts b/services/geminiService.ts index 2848bc8..3d4edca 100644 --- a/services/geminiService.ts +++ b/services/geminiService.ts @@ -24,7 +24,7 @@ If a user asks about pricing, direct them to use the "B2B Quote" or WhatsApp but export class GeminiService { private getAI() { - return new GoogleGenAI({ apiKey: process.env.API_KEY }); + return new GoogleGenAI({ apiKey: import.meta.env.VITE_API_KEY || import.meta.env.API_KEY || '' }); } async *streamTech(prompt: string) { diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..0dfe8e8 --- /dev/null +++ b/vercel.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "buildCommand": "npm run build", + "outputDirectory": "dist", + "framework": "vite", + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.html" + } + ] +} diff --git a/vite-env.d.ts b/vite-env.d.ts new file mode 100644 index 0000000..e695336 --- /dev/null +++ b/vite-env.d.ts @@ -0,0 +1,12 @@ +/// + +interface ImportMetaEnv { + readonly VITE_CLOUDINARY_CLOUD_NAME: string; + readonly VITE_CLOUDINARY_UPLOAD_PRESET: string; + readonly VITE_API_KEY: string; + readonly API_KEY: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +}