Xyro123 commited on
Commit
ddf03e3
·
verified ·
1 Parent(s): 0fba177

Upload 11 files

Browse files
Files changed (11) hide show
  1. .env +1 -0
  2. .gitignore +45 -0
  3. .modified +0 -0
  4. apphosting.yaml +7 -0
  5. backend.json +193 -0
  6. blueprint.md +20 -0
  7. components.json +21 -0
  8. next-env.d.ts +5 -0
  9. postcss.config.mjs +8 -0
  10. tailwind.config.ts +99 -0
  11. tsconfig.json +27 -0
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GEMINI_API_KEY=AIzaSyBUUTboQAettDNArLcQvboPoLUGxMW2wks
.gitignore ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ /.pnp
6
+ .pnp.*
7
+ .yarn/*
8
+ !.yarn/patches
9
+ !.yarn/plugins
10
+ !.yarn/releases
11
+ !.yarn/versions
12
+
13
+ # testing
14
+ /coverage
15
+
16
+ # next.js
17
+ /.next/
18
+ /out/
19
+
20
+ # production
21
+ /build
22
+
23
+ # misc
24
+ .DS_Store
25
+ *.pem
26
+
27
+ # debug
28
+ npm-debug.log*
29
+ yarn-debug.log*
30
+ yarn-error.log*
31
+ .pnpm-debug.log*
32
+
33
+ # vercel
34
+ .vercel
35
+
36
+ # typescript
37
+ *.tsbuildinfo
38
+ next-env.d.ts
39
+
40
+ .genkit/*
41
+ .env*
42
+
43
+ # firebase
44
+ firebase-debug.log
45
+ firestore-debug.log
.modified ADDED
File without changes
apphosting.yaml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Settings to manage and configure a Firebase App Hosting backend.
2
+ # https://firebase.google.com/docs/app-hosting/configure
3
+
4
+ runConfig:
5
+ # Increase this value if you'd like to automatically spin up
6
+ # more instances in response to increased traffic.
7
+ maxInstances: 1
backend.json ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "entities": {
3
+ "User": {
4
+ "$schema": "http://json-schema.org/draft-07/schema#",
5
+ "title": "User",
6
+ "type": "object",
7
+ "description": "Represents a user of the ZeppFusion AI application.",
8
+ "properties": {
9
+ "id": {
10
+ "type": "string",
11
+ "description": "Unique identifier for the User entity."
12
+ },
13
+ "email": {
14
+ "type": "string",
15
+ "description": "Email address of the user.",
16
+ "format": "email"
17
+ },
18
+ "displayName": {
19
+ "type": "string",
20
+ "description": "Display name of the user."
21
+ },
22
+ "creationDate": {
23
+ "type": "string",
24
+ "description": "Date and time the user account was created.",
25
+ "format": "date-time"
26
+ },
27
+ "lastLogin": {
28
+ "type": "string",
29
+ "description": "Date and time of the user's last login.",
30
+ "format": "date-time"
31
+ },
32
+ "theme": {
33
+ "type": "string",
34
+ "description": "The user's preferred theme.",
35
+ "enum": [
36
+ "light",
37
+ "dark",
38
+ "system"
39
+ ]
40
+ }
41
+ },
42
+ "required": [
43
+ "id",
44
+ "email",
45
+ "displayName",
46
+ "creationDate"
47
+ ]
48
+ },
49
+ "ChatSession": {
50
+ "$schema": "http://json-schema.org/draft-07/schema#",
51
+ "title": "ChatSession",
52
+ "type": "object",
53
+ "description": "Represents a chat session between a user and one or more AI models.",
54
+ "properties": {
55
+ "id": {
56
+ "type": "string",
57
+ "description": "Unique identifier for the ChatSession entity."
58
+ },
59
+ "userId": {
60
+ "type": "string",
61
+ "description": "Reference to User. (Relationship: User 1:N ChatSession)"
62
+ },
63
+ "modelUsed": {
64
+ "type": "string",
65
+ "description": "The AI model used in this chat session (e.g., Gemini, ChatGPT 3)."
66
+ },
67
+ "startTime": {
68
+ "type": "string",
69
+ "description": "Date and time the chat session started.",
70
+ "format": "date-time"
71
+ },
72
+ "endTime": {
73
+ "type": "string",
74
+ "description": "Date and time the chat session ended.",
75
+ "format": "date-time"
76
+ }
77
+ },
78
+ "required": [
79
+ "id",
80
+ "userId",
81
+ "modelUsed",
82
+ "startTime"
83
+ ]
84
+ },
85
+ "Message": {
86
+ "$schema": "http://json-schema.org/draft-07/schema#",
87
+ "title": "Message",
88
+ "type": "object",
89
+ "description": "Represents a single message within a chat session.",
90
+ "properties": {
91
+ "id": {
92
+ "type": "string",
93
+ "description": "Unique identifier for the Message entity."
94
+ },
95
+ "chatSessionId": {
96
+ "type": "string",
97
+ "description": "Reference to ChatSession. (Relationship: ChatSession 1:N Message)"
98
+ },
99
+ "sender": {
100
+ "type": "string",
101
+ "description": "Indicates who sent the message (e.g., user, Gemini, ChatGPT)."
102
+ },
103
+ "content": {
104
+ "type": "string",
105
+ "description": "The text content of the message."
106
+ },
107
+ "timestamp": {
108
+ "type": "string",
109
+ "description": "Date and time the message was sent.",
110
+ "format": "date-time"
111
+ }
112
+ },
113
+ "required": [
114
+ "id",
115
+ "chatSessionId",
116
+ "sender",
117
+ "content",
118
+ "timestamp"
119
+ ]
120
+ }
121
+ },
122
+ "auth": {
123
+ "providers": [
124
+ "password",
125
+ "anonymous"
126
+ ]
127
+ },
128
+ "firestore": {
129
+ "structure": [
130
+ {
131
+ "path": "/users/{userId}",
132
+ "definition": {
133
+ "entityName": "User",
134
+ "schema": {
135
+ "$ref": "#/backend/entities/User"
136
+ },
137
+ "description": "Stores user profile data. Path-based ownership enables simple security rules.",
138
+ "params": [
139
+ {
140
+ "name": "userId",
141
+ "description": "The unique identifier of the user."
142
+ }
143
+ ]
144
+ }
145
+ },
146
+ {
147
+ "path": "/users/{userId}/chatSessions/{chatSessionId}",
148
+ "definition": {
149
+ "entityName": "ChatSession",
150
+ "schema": {
151
+ "$ref": "#/backend/entities/ChatSession"
152
+ },
153
+ "description": "Stores chat session data for a specific user. Nested under users for ownership.",
154
+ "params": [
155
+ {
156
+ "name": "userId",
157
+ "description": "The unique identifier of the user."
158
+ },
159
+ {
160
+ "name": "chatSessionId",
161
+ "description": "The unique identifier of the chat session."
162
+ }
163
+ ]
164
+ }
165
+ },
166
+ {
167
+ "path": "/users/{userId}/chatSessions/{chatSessionId}/messages/{messageId}",
168
+ "definition": {
169
+ "entityName": "Message",
170
+ "schema": {
171
+ "$ref": "#/backend/entities/Message"
172
+ },
173
+ "description": "Stores messages within a chat session. Nested under chat sessions for data locality and ownership.",
174
+ "params": [
175
+ {
176
+ "name": "userId",
177
+ "description": "The unique identifier of the user."
178
+ },
179
+ {
180
+ "name": "chatSessionId",
181
+ "description": "The unique identifier of the chat session."
182
+ },
183
+ {
184
+ "name": "messageId",
185
+ "description": "The unique identifier of the message."
186
+ }
187
+ ]
188
+ }
189
+ }
190
+ ],
191
+ "reasoning": "The Firestore structure is designed to ensure authorization independence, clarity, and scalability. User data is stored under `/users/{userId}`, providing path-based ownership, and chat sessions and messages are nested under the user for clear ownership and easy querying. Denormalization is avoided since the application use case fits a strict ownership model. This structure allows for simple and robust security rules based on `request.auth.uid` without requiring complex `get()` calls, thus ensuring atomic operations and ease of debugging. The structure also facilitates secure list operations, as each collection has a consistent security posture due to the path-based ownership and nested structure."
192
+ }
193
+ }
blueprint.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # **App Name**: ZeppFusion AI
2
+
3
+ ## Core Features:
4
+
5
+ - Unified AI Chat Interface: A single interface that allows users to interact with both Gemini and ChatGPT 3 models. One chat window where users can type a single query and get answers from both LLMs. Firestore for chat logs, Cloud Functions for AI API calls
6
+ - Model Selection: Allow users to select which AI model (Gemini or ChatGPT 3) they want to use for each query. Dropdown or toggle (🤖 Gemini / 🧠 ChatGPT 3). User manually picks the model for that query. User setting saved in Firestore
7
+ - Contextual AI Routing: If enabled, ZeppFusion uses a tool to automatically decide which model suits the question (e.g. factual → Gemini, creative → ChatGPT). Cloud Function router script, before passing to the LLM.
8
+ - Chat History: Stores conversations separately per model and date. Firestore (Collections: /chatSessions/{sessionId}/messages)
9
+ - Response Comparison Mode: Side-by-side card layout to visually compare both AI answers. UI rendering only (no extra backend)
10
+ - Smooth UX Animation: Subtle transitions when switching models or awaiting responses. Client-side animation (Framer Motion / Flutter Lottie)
11
+
12
+ ## Style Guidelines:
13
+
14
+ - Primary Color - Deep Purple #673AB7
15
+ - Background - Very Light Purple #F3E5F5
16
+ - Accent - Blue #2196F3
17
+ - Font Family - 'Inter' Sans-Serif (weights 400 → 700)
18
+ - Style - Modern, minimal, slightly futuristic
19
+ - Outline-style icons (e.g., Lucide Icons)
20
+ - Subtle fade / slide / pulse during model load & switch
components.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "default",
4
+ "rsc": true,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/app/globals.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components",
15
+ "utils": "@/lib/utils",
16
+ "ui": "@/components/ui",
17
+ "lib": "@/lib",
18
+ "hooks": "@/hooks"
19
+ },
20
+ "iconLibrary": "lucide"
21
+ }
next-env.d.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // NOTE: This file should not be edited
5
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
postcss.config.mjs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ },
6
+ };
7
+
8
+ export default config;
tailwind.config.ts ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type {Config} from 'tailwindcss';
2
+
3
+ export default {
4
+ darkMode: ['class'],
5
+ content: [
6
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
7
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
8
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
9
+ ],
10
+ theme: {
11
+ extend: {
12
+ fontFamily: {
13
+ body: ['Inter', 'sans-serif'],
14
+ headline: ['Inter', 'sans-serif'],
15
+ code: ['monospace'],
16
+ },
17
+ colors: {
18
+ background: 'hsl(var(--background))',
19
+ foreground: 'hsl(var(--foreground))',
20
+ card: {
21
+ DEFAULT: 'hsl(var(--card))',
22
+ foreground: 'hsl(var(--card-foreground))',
23
+ },
24
+ popover: {
25
+ DEFAULT: 'hsl(var(--popover))',
26
+ foreground: 'hsl(var(--popover-foreground))',
27
+ },
28
+ primary: {
29
+ DEFAULT: 'hsl(var(--primary))',
30
+ foreground: 'hsl(var(--primary-foreground))',
31
+ },
32
+ secondary: {
33
+ DEFAULT: 'hsl(var(--secondary))',
34
+ foreground: 'hsl(var(--secondary-foreground))',
35
+ },
36
+ muted: {
37
+ DEFAULT: 'hsl(var(--muted))',
38
+ foreground: 'hsl(var(--muted-foreground))',
39
+ },
40
+ accent: {
41
+ DEFAULT: 'hsl(var(--accent))',
42
+ foreground: 'hsl(var(--accent-foreground))',
43
+ },
44
+ destructive: {
45
+ DEFAULT: 'hsl(var(--destructive))',
46
+ foreground: 'hsl(var(--destructive-foreground))',
47
+ },
48
+ border: 'hsl(var(--border))',
49
+ input: 'hsl(var(--input))',
50
+ ring: 'hsl(var(--ring))',
51
+ chart: {
52
+ '1': 'hsl(var(--chart-1))',
53
+ '2': 'hsl(var(--chart-2))',
54
+ '3': 'hsl(var(--chart-3))',
55
+ '4': 'hsl(var(--chart-4))',
56
+ '5': 'hsl(var(--chart-5))',
57
+ },
58
+ sidebar: {
59
+ DEFAULT: 'hsl(var(--sidebar-background))',
60
+ foreground: 'hsl(var(--sidebar-foreground))',
61
+ primary: 'hsl(var(--sidebar-primary))',
62
+ 'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
63
+ accent: 'hsl(var(--sidebar-accent))',
64
+ 'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
65
+ border: 'hsl(var(--sidebar-border))',
66
+ ring: 'hsl(var(--sidebar-ring))',
67
+ },
68
+ },
69
+ borderRadius: {
70
+ lg: 'var(--radius)',
71
+ md: 'calc(var(--radius) - 2px)',
72
+ sm: 'calc(var(--radius) - 4px)',
73
+ },
74
+ keyframes: {
75
+ 'accordion-down': {
76
+ from: {
77
+ height: '0',
78
+ },
79
+ to: {
80
+ height: 'var(--radix-accordion-content-height)',
81
+ },
82
+ },
83
+ 'accordion-up': {
84
+ from: {
85
+ height: 'var(--radix-accordion-content-height)',
86
+ },
87
+ to: {
88
+ height: '0',
89
+ },
90
+ },
91
+ },
92
+ animation: {
93
+ 'accordion-down': 'accordion-down 0.2s ease-out',
94
+ 'accordion-up': 'accordion-up 0.2s ease-out',
95
+ },
96
+ },
97
+ },
98
+ plugins: [require('tailwindcss-animate')],
99
+ } satisfies Config;
tsconfig.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }