Mark-Lasfar commited on
Commit
f53960f
·
1 Parent(s): 6c97f50

Update backend and server frontend for OAuth JSON response, client-side navigation, and add .gitignore

Browse files
Files changed (9) hide show
  1. .gitignore +4 -0
  2. api/auth.py +91 -11
  3. api/endpoints.py +147 -56
  4. main.py +6 -2
  5. templates/docs.html +875 -271
  6. templates/index.html +693 -422
  7. templates/login.html +580 -363
  8. templates/register.html +501 -211
  9. test_models.py +99 -0
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ frontend/
2
+ .env
3
+ generated_image.png
4
+ .vscode/
api/auth.py CHANGED
@@ -1,6 +1,5 @@
1
- # api/auth.py
2
  # SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
3
- # SPDX-License-License: Apache-2.0
4
 
5
  from fastapi_users import FastAPIUsers
6
  from fastapi_users.authentication import CookieTransport, JWTStrategy, AuthenticationBackend
@@ -8,15 +7,15 @@ from fastapi_users.router.oauth import get_oauth_router
8
  from httpx_oauth.clients.google import GoogleOAuth2
9
  from httpx_oauth.clients.github import GitHubOAuth2
10
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
11
- from fastapi import Depends, Request, FastAPI
 
12
  from sqlalchemy.ext.asyncio import AsyncSession
13
  from sqlalchemy import select
14
  from fastapi_users.models import UP
15
- from typing import Optional, Dict
16
  import os
17
  import logging
18
  import secrets
19
- from fastapi.responses import RedirectResponse
20
 
21
  from api.database import User, OAuthAccount, CustomSQLAlchemyUserDatabase, get_user_db
22
  from api.models import UserRead, UserCreate, UserUpdate
@@ -145,14 +144,14 @@ class UserManager(IntegerIDMixin, BaseUserManager[User, int]):
145
  async def get_user_manager(user_db: CustomSQLAlchemyUserDatabase = Depends(get_user_db)):
146
  yield UserManager(user_db)
147
 
148
- # OAuth Routers مع معالجة مخصصة لـ GitHub
149
  google_oauth_router = get_oauth_router(
150
  google_oauth_client,
151
  auth_backend,
152
  get_user_manager,
153
  state_secret=SECRET,
154
  associate_by_email=True,
155
- redirect_url="https://mgzon-mgzon-app.hf.space/auth/google/callback", # تعديل الـ redirect_url ليحوّل مباشرة إلى /chat
156
  )
157
 
158
  github_oauth_client._access_token_url = "https://github.com/login/oauth/access_token"
@@ -163,7 +162,7 @@ github_oauth_router = get_oauth_router(
163
  get_user_manager,
164
  state_secret=SECRET,
165
  associate_by_email=True,
166
- redirect_url="https://mgzon-mgzon-app.hf.space/auth/github/callback", # تعديل الـ redirect_url ليحوّل مباشرة إلى /chat
167
  )
168
 
169
  fastapi_users = FastAPIUsers[User, int](
@@ -173,12 +172,93 @@ fastapi_users = FastAPIUsers[User, int](
173
 
174
  current_active_user = fastapi_users.current_user(active=True, optional=True)
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  # تضمين الراوترات داخل التطبيق
177
  def get_auth_router(app: FastAPI):
178
- app.include_router(google_oauth_router, prefix="/auth/google", tags=["auth"])
179
- app.include_router(github_oauth_router, prefix="/auth/github", tags=["auth"])
180
  app.include_router(fastapi_users.get_auth_router(auth_backend), prefix="/auth/jwt", tags=["auth"])
181
  app.include_router(fastapi_users.get_register_router(UserRead, UserCreate), prefix="/auth", tags=["auth"])
182
  app.include_router(fastapi_users.get_reset_password_router(), prefix="/auth", tags=["auth"])
183
  app.include_router(fastapi_users.get_verify_router(UserRead), prefix="/auth", tags=["auth"])
184
- app.include_router(fastapi_users.get_users_router(UserRead, UserUpdate), prefix="/users", tags=["users"])
 
 
 
 
 
 
 
1
  # SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
2
+ # SPDX-License-Identifier: Apache-2.0
3
 
4
  from fastapi_users import FastAPIUsers
5
  from fastapi_users.authentication import CookieTransport, JWTStrategy, AuthenticationBackend
 
7
  from httpx_oauth.clients.google import GoogleOAuth2
8
  from httpx_oauth.clients.github import GitHubOAuth2
9
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
10
+ from fastapi import Depends, Request, FastAPI, Response
11
+ from fastapi.responses import RedirectResponse , JSONResponse
12
  from sqlalchemy.ext.asyncio import AsyncSession
13
  from sqlalchemy import select
14
  from fastapi_users.models import UP
15
+ from typing import Optional
16
  import os
17
  import logging
18
  import secrets
 
19
 
20
  from api.database import User, OAuthAccount, CustomSQLAlchemyUserDatabase, get_user_db
21
  from api.models import UserRead, UserCreate, UserUpdate
 
144
  async def get_user_manager(user_db: CustomSQLAlchemyUserDatabase = Depends(get_user_db)):
145
  yield UserManager(user_db)
146
 
147
+ # تعديل الـ OAuth Routers لتضمين redirect مخصص
148
  google_oauth_router = get_oauth_router(
149
  google_oauth_client,
150
  auth_backend,
151
  get_user_manager,
152
  state_secret=SECRET,
153
  associate_by_email=True,
154
+ redirect_url=GOOGLE_REDIRECT_URL,
155
  )
156
 
157
  github_oauth_client._access_token_url = "https://github.com/login/oauth/access_token"
 
162
  get_user_manager,
163
  state_secret=SECRET,
164
  associate_by_email=True,
165
+ redirect_url=GITHUB_REDIRECT_URL,
166
  )
167
 
168
  fastapi_users = FastAPIUsers[User, int](
 
172
 
173
  current_active_user = fastapi_users.current_user(active=True, optional=True)
174
 
175
+ # إضافة route مخصص للتعامل مع الـ callback
176
+
177
+ # تعديل الـ OAuth Callback لـ Google
178
+ async def custom_oauth_callback(
179
+ code: str,
180
+ user_manager: UserManager = Depends(get_user_manager),
181
+ oauth_client=Depends(lambda: google_oauth_client),
182
+ redirect_url: str = GOOGLE_REDIRECT_URL,
183
+ response: Response = None,
184
+ ):
185
+ # جلب access token من Google
186
+ token_data = await oauth_client.get_access_token(code, redirect_url)
187
+ access_token = token_data["access_token"]
188
+ user_info = await oauth_client.get_user_info(access_token)
189
+
190
+ # استدعاء oauth_callback من UserManager
191
+ user = await user_manager.oauth_callback(
192
+ oauth_name="google",
193
+ access_token=access_token,
194
+ account_id=user_info["sub"],
195
+ account_email=user_info["email"],
196
+ expires_at=token_data.get("expires_in"),
197
+ refresh_token=token_data.get("refresh_token"),
198
+ associate_by_email=True,
199
+ is_verified_by_default=True,
200
+ )
201
+
202
+ # إنشاء JWT token
203
+ jwt_strategy = get_jwt_strategy()
204
+ token = await jwt_strategy.write(user)
205
+
206
+ # تعيين الـ token في الكوكيز
207
+ cookie_transport.set_cookie(response, token)
208
+
209
+ # رجع JSON بدل redirect – الـ frontend هيتحكم في التوجيه
210
+ return JSONResponse(content={
211
+ "message": "Google login successful",
212
+ "access_token": token
213
+ }, status_code=200)
214
+
215
+ # تعديل الـ OAuth Callback لـ GitHub
216
+ async def custom_github_oauth_callback(
217
+ code: str,
218
+ user_manager: UserManager = Depends(get_user_manager),
219
+ oauth_client=Depends(lambda: github_oauth_client),
220
+ redirect_url: str = GITHUB_REDIRECT_URL,
221
+ response: Response = None,
222
+ ):
223
+ # جلب access token من GitHub
224
+ token_data = await oauth_client.get_access_token(code, redirect_url)
225
+ access_token = token_data["access_token"]
226
+ user_info = await oauth_client.get_user_info(access_token)
227
+
228
+ # استدعاء oauth_callback من UserManager
229
+ user = await user_manager.oauth_callback(
230
+ oauth_name="github",
231
+ access_token=access_token,
232
+ account_id=str(user_info["id"]),
233
+ account_email=user_info.get("email") or f"{user_info['login']}@github.com",
234
+ expires_at=token_data.get("expires_in"),
235
+ refresh_token=token_data.get("refresh_token"),
236
+ associate_by_email=True,
237
+ is_verified_by_default=True,
238
+ )
239
+
240
+ # إنشاء JWT token
241
+ jwt_strategy = get_jwt_strategy()
242
+ token = await jwt_strategy.write(user)
243
+
244
+ # تعيين الـ token في الكوكيز
245
+ cookie_transport.set_cookie(response, token)
246
+
247
+ # رجع JSON بدل redirect – الـ frontend هيتحكم في التوجيه
248
+ return JSONResponse(content={
249
+ "message": "GitHub login successful",
250
+ "access_token": token
251
+ }, status_code=200)
252
+
253
  # تضمين الراوترات داخل التطبيق
254
  def get_auth_router(app: FastAPI):
 
 
255
  app.include_router(fastapi_users.get_auth_router(auth_backend), prefix="/auth/jwt", tags=["auth"])
256
  app.include_router(fastapi_users.get_register_router(UserRead, UserCreate), prefix="/auth", tags=["auth"])
257
  app.include_router(fastapi_users.get_reset_password_router(), prefix="/auth", tags=["auth"])
258
  app.include_router(fastapi_users.get_verify_router(UserRead), prefix="/auth", tags=["auth"])
259
+ app.include_router(fastapi_users.get_users_router(UserRead, UserUpdate), prefix="/users", tags=["users"])
260
+
261
+ # إضافة الـ custom callback routes
262
+ app.get("/auth/google/callback")(custom_oauth_callback)
263
+ app.get("/auth/github/callback")(custom_github_oauth_callback)
264
+
api/endpoints.py CHANGED
@@ -15,6 +15,8 @@ from sqlalchemy import select, delete
15
  from utils.generation import request_generation, select_model, check_model_availability
16
  from utils.web_search import web_search
17
  import io
 
 
18
  from openai import OpenAI
19
  from motor.motor_asyncio import AsyncIOMotorClient
20
  from datetime import datetime
@@ -22,7 +24,7 @@ import logging
22
  from typing import List, Optional
23
  # from utils.constants import MODEL_ALIASES, MODEL_NAME, SECONDARY_MODEL_NAME, TERTIARY_MODEL_NAME, CLIP_BASE_MODEL, CLIP_LARGE_MODEL, ASR_MODEL, TTS_MODEL, IMAGE_GEN_MODEL, SECONDARY_IMAGE_GEN_MODEL
24
  from utils.constants import MODEL_ALIASES, MODEL_NAME, SECONDARY_MODEL_NAME, TERTIARY_MODEL_NAME, CLIP_BASE_MODEL, CLIP_LARGE_MODEL, ASR_MODEL, TTS_MODEL, IMAGE_GEN_MODEL, SECONDARY_IMAGE_GEN_MODEL, IMAGE_INFERENCE_API
25
-
26
  import psutil
27
  import time
28
  router = APIRouter()
@@ -138,6 +140,7 @@ async def performance_stats():
138
  "uptime": time.time() - psutil.boot_time() # مدة تشغيل النظام بالثواني
139
  }
140
 
 
141
  @router.post("/api/chat")
142
  async def chat_endpoint(
143
  request: Request,
@@ -175,7 +178,6 @@ async def chat_endpoint(
175
  preferred_model = user.preferred_model if user else None
176
  model_name, api_endpoint = select_model(req.message, input_type="text", preferred_model=preferred_model)
177
 
178
- # جرب النموذج الأساسي
179
  is_available, api_key, selected_endpoint = check_model_availability(model_name, HF_TOKEN)
180
  if not is_available:
181
  logger.warning(f"Model {model_name} is not available at {api_endpoint}, trying fallback model.")
@@ -219,67 +221,71 @@ async def chat_endpoint(
219
  logger.error(f"Audio generation failed: {e}")
220
  raise HTTPException(status_code=502, detail=f"Audio generation failed: {str(e)}")
221
 
222
- response_chunks = []
223
- try:
224
- for chunk in stream:
225
- logger.debug(f"Processing text chunk: {chunk[:100]}...")
226
- if isinstance(chunk, str) and chunk.strip() and chunk not in ["analysis", "assistantfinal"]:
227
- response_chunks.append(chunk)
228
- else:
229
- logger.warning(f"Skipping chunk: {chunk}")
230
- response = "".join(response_chunks)
231
- if not response.strip():
232
- logger.warning(f"Empty response from {model_name}. Trying fallback model {SECONDARY_MODEL_NAME}.")
233
- model_name = SECONDARY_MODEL_NAME
234
- is_available, api_key, selected_endpoint = check_model_availability(model_name, HF_TOKEN)
235
- if not is_available:
236
- logger.error(f"Fallback model {model_name} is not available at {selected_endpoint}")
237
- raise HTTPException(status_code=503, detail=f"No available models. Tried {MODEL_NAME} and {SECONDARY_MODEL_NAME}.")
238
-
239
- stream = request_generation(
240
- api_key=api_key,
241
- api_base=selected_endpoint,
242
- message=req.message,
243
- system_prompt=system_prompt,
244
- model_name=model_name,
245
- chat_history=req.history,
246
- temperature=req.temperature,
247
- max_new_tokens=req.max_new_tokens or 2048,
248
- deep_search=req.enable_browsing,
249
- input_type="text",
250
- output_format=req.output_format
251
- )
252
- response_chunks = []
253
  for chunk in stream:
254
- logger.debug(f"Processing fallback text chunk: {chunk[:100]}...")
255
  if isinstance(chunk, str) and chunk.strip() and chunk not in ["analysis", "assistantfinal"]:
256
  response_chunks.append(chunk)
 
 
257
  else:
258
- logger.warning(f"Skipping fallback chunk: {chunk}")
 
259
  response = "".join(response_chunks)
260
  if not response.strip():
261
- logger.error(f"Empty response from fallback model {model_name}.")
262
- raise HTTPException(status_code=502, detail=f"Empty response from both {MODEL_NAME} and {SECONDARY_MODEL_NAME}.")
263
- logger.info(f"Chat response: {response[:100]}...")
264
- except Exception as e:
265
- logger.error(f"Chat generation failed: {e}")
266
- raise HTTPException(status_code=500, detail=f"Chat generation failed: {str(e)}")
267
-
268
- if user and conversation:
269
- assistant_msg = Message(role="assistant", content=response, conversation_id=conversation.id)
270
- db.add(assistant_msg)
271
- await db.commit()
272
- conversation.updated_at = datetime.utcnow()
273
- await db.commit()
274
- return {
275
- "response": response,
276
- "conversation_id": conversation.conversation_id,
277
- "conversation_url": f"https://mgzon-mgzon-app.hf.space/chat/{conversation.conversation_id}",
278
- "conversation_title": conversation.title
279
- }
280
-
281
- return {"response": response}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
 
283
 
284
  @router.post("/api/image-generation")
285
  async def image_generation_endpoint(
@@ -942,3 +948,88 @@ async def update_user_settings(
942
  "is_active": user.is_active,
943
  "is_superuser": user.is_superuser
944
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  from utils.generation import request_generation, select_model, check_model_availability
16
  from utils.web_search import web_search
17
  import io
18
+ import asyncio
19
+ import json
20
  from openai import OpenAI
21
  from motor.motor_asyncio import AsyncIOMotorClient
22
  from datetime import datetime
 
24
  from typing import List, Optional
25
  # from utils.constants import MODEL_ALIASES, MODEL_NAME, SECONDARY_MODEL_NAME, TERTIARY_MODEL_NAME, CLIP_BASE_MODEL, CLIP_LARGE_MODEL, ASR_MODEL, TTS_MODEL, IMAGE_GEN_MODEL, SECONDARY_IMAGE_GEN_MODEL
26
  from utils.constants import MODEL_ALIASES, MODEL_NAME, SECONDARY_MODEL_NAME, TERTIARY_MODEL_NAME, CLIP_BASE_MODEL, CLIP_LARGE_MODEL, ASR_MODEL, TTS_MODEL, IMAGE_GEN_MODEL, SECONDARY_IMAGE_GEN_MODEL, IMAGE_INFERENCE_API
27
+ from fastapi import Body
28
  import psutil
29
  import time
30
  router = APIRouter()
 
140
  "uptime": time.time() - psutil.boot_time() # مدة تشغيل النظام بالثواني
141
  }
142
 
143
+
144
  @router.post("/api/chat")
145
  async def chat_endpoint(
146
  request: Request,
 
178
  preferred_model = user.preferred_model if user else None
179
  model_name, api_endpoint = select_model(req.message, input_type="text", preferred_model=preferred_model)
180
 
 
181
  is_available, api_key, selected_endpoint = check_model_availability(model_name, HF_TOKEN)
182
  if not is_available:
183
  logger.warning(f"Model {model_name} is not available at {api_endpoint}, trying fallback model.")
 
221
  logger.error(f"Audio generation failed: {e}")
222
  raise HTTPException(status_code=502, detail=f"Audio generation failed: {str(e)}")
223
 
224
+ async def stream_response():
225
+ response_chunks = []
226
+ try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  for chunk in stream:
 
228
  if isinstance(chunk, str) and chunk.strip() and chunk not in ["analysis", "assistantfinal"]:
229
  response_chunks.append(chunk)
230
+ yield chunk.encode('utf-8') # إرسال الـ chunk مباشرةً
231
+ await asyncio.sleep(0.05) # تأخير بسيط لمحاكاة الكتابة
232
  else:
233
+ logger.warning(f"Skipping chunk: {chunk}")
234
+
235
  response = "".join(response_chunks)
236
  if not response.strip():
237
+ logger.warning(f"Empty response from {model_name}. Trying fallback model {SECONDARY_MODEL_NAME}.")
238
+ model_name = SECONDARY_MODEL_NAME
239
+ is_available, api_key, selected_endpoint = check_model_availability(model_name, HF_TOKEN)
240
+ if not is_available:
241
+ logger.error(f"Fallback model {model_name} is not available at {selected_endpoint}")
242
+ yield f"Error: No available models. Tried {MODEL_NAME} and {SECONDARY_MODEL_NAME}.".encode('utf-8')
243
+ return
244
+
245
+ stream = request_generation(
246
+ api_key=api_key,
247
+ api_base=selected_endpoint,
248
+ message=req.message,
249
+ system_prompt=system_prompt,
250
+ model_name=model_name,
251
+ chat_history=req.history,
252
+ temperature=req.temperature,
253
+ max_new_tokens=req.max_new_tokens or 2048,
254
+ deep_search=req.enable_browsing,
255
+ input_type="text",
256
+ output_format=req.output_format
257
+ )
258
+ response_chunks = []
259
+ for chunk in stream:
260
+ if isinstance(chunk, str) and chunk.strip() and chunk not in ["analysis", "assistantfinal"]:
261
+ response_chunks.append(chunk)
262
+ yield chunk.encode('utf-8')
263
+ await asyncio.sleep(0.05)
264
+ else:
265
+ logger.warning(f"Skipping fallback chunk: {chunk}")
266
+
267
+ response = "".join(response_chunks)
268
+ if not response.strip():
269
+ logger.error(f"Empty response from fallback model {model_name}.")
270
+ yield f"Error: Empty response from both {MODEL_NAME} and {SECONDARY_MODEL_NAME}.".encode('utf-8')
271
+ return
272
+
273
+ if user and conversation:
274
+ assistant_msg = Message(role="assistant", content=response, conversation_id=conversation.id)
275
+ db.add(assistant_msg)
276
+ await db.commit()
277
+ conversation.updated_at = datetime.utcnow()
278
+ await db.commit()
279
+ yield json.dumps({
280
+ "conversation_id": conversation.conversation_id,
281
+ "conversation_url": f"https://mgzon-mgzon-app.hf.space/chat/{conversation.conversation_id}",
282
+ "conversation_title": conversation.title
283
+ }, ensure_ascii=False).encode('utf-8')
284
+ except Exception as e:
285
+ logger.error(f"Chat generation failed: {e}")
286
+ yield f"Error: Chat generation failed: {str(e)}".encode('utf-8')
287
 
288
+ return StreamingResponse(stream_response(), media_type="text/plain")
289
 
290
  @router.post("/api/image-generation")
291
  async def image_generation_endpoint(
 
948
  "is_active": user.is_active,
949
  "is_superuser": user.is_superuser
950
  }}
951
+
952
+
953
+
954
+ @router.post("/api/conversations/sync", response_model=ConversationOut)
955
+ async def sync_conversation(
956
+ request: Request,
957
+ payload: dict = Body(...),
958
+ user: User = Depends(current_active_user),
959
+ db: AsyncSession = Depends(get_db)
960
+ ):
961
+ if not user:
962
+ raise HTTPException(status_code=401, detail="Login required")
963
+
964
+ messages = payload.get("messages", [])
965
+ title = payload.get("title", "Untitled Conversation")
966
+ conversation_id = payload.get("conversation_id")
967
+
968
+ logger.info(f"Syncing conversation for user {user.email}, conversation_id: {conversation_id}")
969
+
970
+ try:
971
+ # Check if conversation exists
972
+ if conversation_id:
973
+ result = await db.execute(
974
+ select(Conversation).filter(
975
+ Conversation.conversation_id == conversation_id,
976
+ Conversation.user_id == user.id
977
+ )
978
+ )
979
+ conversation = result.scalar_one_or_none()
980
+ if not conversation:
981
+ raise HTTPException(status_code=404, detail="Conversation not found")
982
+
983
+ # Update existing conversation
984
+ conversation.title = title
985
+ conversation.updated_at = datetime.utcnow()
986
+
987
+ # Delete old messages
988
+ await db.execute(
989
+ delete(Message).filter(Message.conversation_id == conversation.id)
990
+ )
991
+
992
+ # Add new messages
993
+ for msg in messages:
994
+ new_message = Message(
995
+ conversation_id=conversation.id,
996
+ role=msg.get("role", "user"),
997
+ content=msg.get("content", ""),
998
+ created_at=datetime.utcnow()
999
+ )
1000
+ db.add(new_message)
1001
+
1002
+ await db.commit()
1003
+ await db.refresh(conversation)
1004
+ logger.info(f"Updated conversation {conversation_id} for user {user.email}")
1005
+ else:
1006
+ # Create new conversation
1007
+ conversation_id = str(uuid.uuid4())
1008
+ conversation = Conversation(
1009
+ conversation_id=conversation_id,
1010
+ user_id=user.id,
1011
+ title=title,
1012
+ created_at=datetime.utcnow(),
1013
+ updated_at=datetime.utcnow()
1014
+ )
1015
+ db.add(conversation)
1016
+ await db.commit()
1017
+ await db.refresh(conversation)
1018
+
1019
+ # Add messages
1020
+ for msg in messages:
1021
+ new_message = Message(
1022
+ conversation_id=conversation.id,
1023
+ role=msg.get("role", "user"),
1024
+ content=msg.get("content", ""),
1025
+ created_at=datetime.utcnow()
1026
+ )
1027
+ db.add(new_message)
1028
+
1029
+ await db.commit()
1030
+ logger.info(f"Created new conversation {conversation_id} for user {user.email}")
1031
+
1032
+ return ConversationOut.from_orm(conversation)
1033
+ except Exception as e:
1034
+ logger.error(f"Error syncing conversation: {str(e)}")
1035
+ raise HTTPException(status_code=500, detail=f"Failed to sync conversation: {str(e)}")
main.py CHANGED
@@ -120,13 +120,17 @@ app.add_middleware(
120
  "https://mgzon-mgzon-app.hf.space",
121
  "http://localhost:7860",
122
  "http://localhost:8000",
 
 
 
 
123
  "https://hager-zon.vercel.app",
124
  "https://mgzon-mgzon-app.hf.space/auth/google/callback",
125
  "https://mgzon-mgzon-app.hf.space/auth/github/callback",
126
  ],
127
  allow_credentials=True,
128
- allow_methods=["GET", "POST", "OPTIONS", "PUT", "DELETE"],
129
- allow_headers=["Accept", "Content-Type", "Authorization", "X-Requested-With", "X-Session-ID"],
130
  )
131
  logger.debug("CORS middleware configured with allowed origins")
132
 
 
120
  "https://mgzon-mgzon-app.hf.space",
121
  "http://localhost:7860",
122
  "http://localhost:8000",
123
+ "http://localhost", # إضافة لدعم Capacitor على Android/iOS
124
+ "https://localhost", # إضافة لدعم HTTPS المحلي
125
+ "capacitor://localhost", # دعم Capacitor native apps
126
+ "file://", # دعم الملفات المحلية في offline mode
127
  "https://hager-zon.vercel.app",
128
  "https://mgzon-mgzon-app.hf.space/auth/google/callback",
129
  "https://mgzon-mgzon-app.hf.space/auth/github/callback",
130
  ],
131
  allow_credentials=True,
132
+ allow_methods=["*"], # سمح بكل الـ methods
133
+ allow_headers=["*"], # سمح بكل الـ headers
134
  )
135
  logger.debug("CORS middleware configured with allowed origins")
136
 
templates/docs.html CHANGED
@@ -1,284 +1,888 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="description" content="Explore MGZon Chatbot API documentation for integrating AI-powered code generation and e-commerce tools.">
7
- <meta name="keywords" content="MGZon Chatbot, API documentation, code generation, e-commerce, FastAPI, Mark Al-Asfar">
8
- <meta name="author" content="Mark Al-Asfar">
9
- <meta name="robots" content="index, follow">
10
- <title>API Documentation - MGZon Chatbot</title>
11
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
- <link rel="apple-touch-icon" href="/static/images/mg.svg">
13
- <!-- Open Graph -->
14
- <meta property="og:title" content="API Documentation - MGZon Chatbot">
15
- <meta property="og:description" content="Explore MGZon Chatbot API documentation for integrating AI-powered code generation and e-commerce tools.">
16
- <meta property="og:image" content="/static/images/mg.svg">
17
- <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/docs">
18
- <meta property="og:type" content="website">
19
- <!-- Twitter Card -->
20
- <meta name="twitter:card" content="summary_large_image">
21
- <meta name="twitter:title" content="API Documentation - MGZon Chatbot">
22
- <meta name="twitter:description" content="Explore MGZon Chatbot API documentation for integrating AI-powered code generation and e-commerce tools.">
23
- <meta name="twitter:image" content="/static/images/mg.svg">
24
- <!-- JSON-LD -->
25
- <script type="application/ld+json">
26
- {
27
- "@context": "https://schema.org",
28
- "@type": "WebPage",
29
- "name": "API Documentation - MGZon Chatbot",
30
- "url": "https://mgzon-mgzon-app.hf.space/docs",
31
- "description": "Explore MGZon Chatbot API documentation for integrating AI-powered code generation and e-commerce tools.",
32
- "keywords": ["MGZon Chatbot", "API documentation", "code generation", "e-commerce", "FastAPI", "Mark Al-Asfar", "MGZon", "MGZon AI", "AI chatbot", "Code generation bot", "Python AI chatbot", "FastAPI integration", "AI for coding", "AI developer tools", "text generation"],
33
- "isPartOf": {
34
- "@type": "WebSite",
35
- "name": "MGZon Chatbot",
36
- "url": "https://mgzon-mgzon-app.hf.space/"
37
- }
38
- }
39
- </script>
40
- <!-- Tailwind (v3) -->
41
- <script src="https://cdn.tailwindcss.com"></script>
42
- <!-- Boxicons -->
43
- <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
44
- <!-- Prism (for code highlighting) -->
45
- <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
46
- <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
47
- <style>
48
- @keyframes gradientShift {
49
- 0% { background-position: 0% 50%; }
50
- 50% { background-position: 100% 50%; }
51
- 100% { background-position: 0% 50%; }
52
- }
53
- body {
54
- background: linear-gradient(135deg, #0f172a, #0e7490, #065f46, #064e3b);
55
- background-size: 400% 400%;
56
- animation: gradientShift 15s ease infinite;
57
- font-family: system-ui, sans-serif;
58
- }
59
- .glass {
60
- background: rgba(255, 255, 255, 0.07);
61
- border-radius: 1rem;
62
- border: 1px solid rgba(255, 255, 255, 0.12);
63
- backdrop-filter: blur(12px);
64
- -webkit-backdrop-filter: blur(12px);
65
- }
66
- .sidebar {
67
- transition: transform 0.3s ease-in-out;
68
- }
69
- .sidebar.collapsed .logo {
70
- opacity: 0;
71
- transition: opacity 0.2s ease;
72
- }
73
- .main-content {
74
- min-height: calc(100vh - 4rem);
75
- }
76
- .glass:hover {
77
- transform: scale(1.05);
78
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
79
- background: rgba(255, 255, 255, 0.15);
80
- }
81
- @media (max-width: 768px) {
82
- .sidebar {
83
- transform: translateX(-100%);
84
- }
85
- .sidebar.active {
86
- transform: translateX(0);
87
  }
88
  }
89
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  </head>
91
- <body class="text-white flex flex-col min-h-screen">
92
- <!-- Mobile toggle button -->
93
- <button id="sidebarToggle" class="md:hidden fixed top-4 left-4 z-50 p-2 text-2xl text-white rounded bg-gray-800/60 hover:bg-gray-700/80 transition" aria-label="Toggle navigation">
94
- <i class="bx bx-menu"></i>
95
- </button>
96
- <!-- Sidebar -->
97
- <aside id="sidebar" class="sidebar fixed inset-y-0 left-0 w-64 bg-gradient-to-b from-teal-800 to-emerald-900 p-6 flex flex-col overflow-y-auto z-40">
98
- <button id="closeSidebar" class="md:hidden text-white text-2xl absolute top-4 right-4" aria-label="Close sidebar">✕</button>
99
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="logo w-20 h-20 mx-auto mb-8 animate-pulse">
100
- <nav class="flex flex-col gap-3">
101
- <a href="/" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Home</a>
102
- <a href="/docs" class="px-4 py-2 rounded-lg bg-emerald-600">API Documentation</a>
103
- <a href="/about" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">About MGZon</a>
104
- <a href="/login" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Login</a>
105
- <a href="/register" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Register</a>
106
- <a href="https://hager-zon.vercel.app/community" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Community</a>
107
- <a href="https://mark-elasfar.web.app/" target="_blank" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Mark Al-Asfar</a>
108
- </nav>
109
- </aside>
110
- <!-- Main content -->
111
- <main class="flex-1 md:ml-64 p-6 main-content">
112
- <section class="container max-w-6xl mx-auto">
113
- <div class="text-center py-12">
114
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
115
- <h1 class="text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-300 to-emerald-400">About MGZon AI by Mark Al-Asfar</h1>
116
- MGZon Chatbot API Documentation
117
- </h1>
118
- <p class="text-lg max-w-2xl mx-auto mb-8">
119
- Integrate MGZon Chatbot's AI-powered features into your applications. Learn how to use our APIs for code generation, web search, and e-commerce solutions.
120
- </p>
121
- <p>Explore the MGZon Chatbot API for seamless integration of AI-powered code generation, text generation, and e-commerce automation. Built by Mark Al-Asfar using FastAPI and Hugging Face AI.</p>
122
- <a href="https://x.ai/api" target="_blank" class="inline-flex items-center bg-gradient-to-r from-emerald-500 to-teal-600 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition-transform shadow-lg hover:shadow-xl">
123
- Get API Key <i class="bx bx-key ml-2"></i>
124
- </a>
125
- </div>
126
- <!-- API Overview -->
127
- <section class="my-12">
128
- <h2 class="text-3xl font-bold text-center mb-8">API Overview</h2>
129
- <div class="glass p-6">
130
- <p class="mb-4">The MGZon Chatbot API provides endpoints for code generation, real-time web search, and e-commerce functionalities. Built with FastAPI, it offers secure and scalable integration.</p>
131
- <p>Base URL: <code class="bg-gray-800/60 p-1 rounded">https://mgzon-mgzon-app.hf.space/api</code></p>
132
- </div>
133
- </section>
134
- <!-- Authentication -->
135
- <section class="my-12">
136
- <h2 class="text-3xl font-bold text-center mb-8">Authentication</h2>
137
- <div class="glass p-6">
138
- <p class="mb-4">Use JWT tokens for authentication. Register or login to obtain a token.</p>
139
- <pre><code class="language-bash">
140
- curl -X POST "https://mgzon-mgzon-app.hf.space/auth/jwt/login" \
141
- -H "Content-Type: application/x-www-form-urlencoded" \
142
- -d "username=your_email&password=your_password"
143
- </code></pre>
144
  </div>
145
- </section>
146
- <!-- Endpoints -->
147
- <section class="my-12">
148
- <h2 class="text-3xl font-bold text-center mb-8">Endpoints</h2>
149
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
150
- <div class="glass p-6">
151
- <h3 class="text-xl font-semibold mb-2">/chat (POST)</h3>
152
- <p class="mb-4">Interact with the AI chatbot for code generation or queries.</p>
153
- <pre><code class="language-bash">
154
- curl -X POST "https://mgzon-mgzon-app.hf.space/chat" \
155
- -H "Authorization: Bearer your_token" \
156
- -H "Content-Type: application/json" \
157
- -d '{"message": "Generate a Python function"}'
158
- </code></pre>
159
- </div>
160
- <div class="glass p-6">
161
- <h3 class="text-xl font-semibold mb-2">/web_search (POST)</h3>
162
- <p class="mb-4">Perform real-time web searches.</p>
163
- <pre><code class="language-bash">
164
- curl -X POST "https://mgzon-mgzon-app.hf.space/web_search" \
165
- -H "Authorization: Bearer your_token" \
166
- -H "Content-Type: application/json" \
167
- -d '{"query": "AI trends 2025"}'
168
- </code></pre>
169
- </div>
170
  </div>
171
- </section>
172
- <!-- Getting Started -->
173
- <section class="my-12">
174
- <h2 class="text-3xl font-bold text-center mb-8">Getting Started</h2>
175
- <div class="glass p-6">
176
- <p class="mb-4">1. Register at <a href="/register" class="text-emerald-300 hover:underline">/register</a>.</p>
177
- <p class="mb-4">2. Obtain your API key from <a href="https://x.ai/api" target="_blank" class="text-emerald-300 hover:underline">xAI API</a>.</p>
178
- <p>3. Use the endpoints above to integrate MGZon Chatbot into your application.</p>
179
- </div>
180
- </section>
181
  </section>
182
- </main>
183
- <!-- Footer -->
184
- <footer class="bg-gradient-to-r from-teal-900 to-emerald-900 py-12 mt-8">
185
- <div class="container max-w-6xl mx-auto text-center">
186
- <img src="/static/images/mg.svg" alt="MGZon Chatbot Logo by Mark Al-Asfar" class="w-32 h-32 mx-auto mb-6 animate-bounce">
187
- <p class="mb-4">
188
- Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-emerald-300 hover:underline">Mark Al-Asfar</a>
189
- | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-emerald-300 hover:underline">MGZon AI</a>
190
- </p>
191
- <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
192
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('email')">
193
- <i class="bx bx-mail-send text-3xl text-emerald-300 mb-2"></i>
194
- <h4 class="font-semibold mb-1">Email Us</h4>
195
- <p><a href="mailto:support@mgzon.com" class="text-emerald-300 hover:underline">support@mgzon.com</a></p>
196
- <div id="email-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
197
- <p>Reach out to our support team for any inquiries or assistance.</p>
198
- <button onclick="closeCardDetails('email')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
199
- </div>
200
- </div>
201
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
202
- <i class="bx bx-phone text-3xl text-emerald-300 mb-2"></i>
203
- <h4 class="font-semibold mb-1">Phone Support</h4>
204
- <p>+1-800-123-4567</p>
205
- <div id="phone-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
206
- <p>Contact our support team via phone for immediate assistance.</p>
207
- <button onclick="closeCardDetails('phone')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
208
- </div>
209
- </div>
210
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('community')">
211
- <i class="bx bx-group text-3xl text-emerald-300 mb-2"></i>
212
- <h4 class="font-semibold mb-1">Community</h4>
213
- <p><a href="https://hager-zon.vercel.app/community" class="text-emerald-300 hover:underline">Join us</a></p>
214
- <div id="community-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
215
- <p>Join our vibrant community to share ideas and collaborate.</p>
216
- <button onclick="closeCardDetails('community')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
217
- </div>
218
  </div>
219
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
220
- <i class="bx bx-code-alt text-3xl text-emerald-300 mb-2"></i>
221
- <h4 class="font-semibold mb-1">API Docs</h4>
222
- <p><a href="/docs" class="text-emerald-300 hover:underline">Explore Docs</a></p>
223
- <div id="api-docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
224
- <p>Explore our API documentation for seamless integration.</p>
225
- <button onclick="closeCardDetails('api-docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
226
- </div>
227
- </div>
228
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
229
- <i class="bx bx-help-circle text-3xl text-emerald-300 mb-2"></i>
230
- <h4 class="font-semibold mb-1">FAQ</h4>
231
- <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-emerald-300 hover:underline">Read FAQ</a></p>
232
- <div id="faq-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
233
- <p>Find answers to common questions in our FAQ section.</p>
234
- <button onclick="closeCardDetails('faq')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
235
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  </div>
237
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
238
- <i class="bx bx-book text-3xl text-emerald-300 mb-2"></i>
239
- <h4 class="font-semibold mb-1">Documentation</h4>
240
- <p><a href="/docs" class="text-emerald-300 hover:underline">Full Docs</a></p>
241
- <div id="docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
242
- <p>Access comprehensive documentation for MGZon Chatbot.</p>
243
- <button onclick="closeCardDetails('docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
244
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
245
  </div>
246
- </div>
247
- <div class="flex justify-center gap-6 mt-6">
248
- <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-github"></i></a>
249
- <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-twitter"></i></a>
250
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-facebook"></i></a>
251
- </div>
252
- <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
253
- </div>
254
- </footer>
255
- <script>
256
- const sidebar = document.getElementById('sidebar');
257
- const toggleBtn = document.getElementById('sidebarToggle');
258
- const closeSidebarBtn = document.getElementById('closeSidebar');
259
- toggleBtn.addEventListener('click', () => {
260
- sidebar.classList.toggle('active');
261
- sidebar.classList.toggle('-translate-x-full');
262
- sidebar.classList.toggle('translate-x-0');
263
- });
264
- closeSidebarBtn.addEventListener('click', () => {
265
- sidebar.classList.remove('active');
266
- sidebar.classList.add('-translate-x-full');
267
- sidebar.classList.remove('translate-x-0');
268
- });
269
- document.addEventListener('click', (e) => {
270
- if (!sidebar.contains(e.target) && !toggleBtn.contains(e.target) && window.innerWidth < 768) {
271
- sidebar.classList.remove('active');
272
- sidebar.classList.add('-translate-x-full');
273
- sidebar.classList.remove('translate-x-0');
274
- }
275
- });
276
- function showCardDetails(cardId) {
277
- document.getElementById(`${cardId}-details`).classList.remove('hidden');
278
- }
279
- function closeCardDetails(cardId) {
280
- document.getElementById(`${cardId}-details`).classList.add('hidden');
281
- }
282
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  </body>
284
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="description" content="MGZon Chatbot API Documentation – Detailed guide for integrating AI-powered features like code generation, web search, and e-commerce solutions by Mark Al-Asfar.">
7
+ <meta name="keywords" content="MGZon API Docs, AI Chatbot Integration, Code Generation API, E-commerce AI, Mark Al-Asfar, FastAPI, Gradio">
8
+ <meta name="author" content="Mark Al-Asfar">
9
+ <meta name="robots" content="index, follow">
10
+ <title>MGZon Chatbot API Documentation</title>
11
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
+ <link rel="manifest" href="/static/manifest.json">
13
+ <link rel="apple-touch-icon" sizes="180x180" href="/static/images/mg-180.png">
14
+ <meta name="apple-mobile-web-app-capable" content="yes">
15
+ <meta name="apple-mobile-web-app-title" content="MGZon">
16
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
17
+ <meta name="theme-color" content="#00f0ff">
18
+ <meta property="og:title" content="MGZon Chatbot API Documentation">
19
+ <meta property="og:description" content="Comprehensive API docs for MGZon Chatbot: Integrate AI for code, search, and e-commerce by Mark Al-Asfar.">
20
+ <meta property="og:image" content="/static/images/mg.svg">
21
+ <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/docs">
22
+ <meta property="og:type" content="website">
23
+ <meta name="twitter:card" content="summary_large_image">
24
+ <meta name="twitter:title" content="MGZon Chatbot API Documentation">
25
+ <meta name="twitter:description" content="Comprehensive API docs for MGZon Chatbot: Integrate AI for code, search, and e-commerce by Mark Al-Asfar.">
26
+ <meta name="twitter:image" content="/static/images/mg.svg">
27
+ <script type="application/ld+json">
28
+ {
29
+ "@context": "https://schema.org",
30
+ "@type": "WebSite",
31
+ "name": "MGZon Chatbot API Docs",
32
+ "url": "https://mgzon-mgzon-app.hf.space/docs",
33
+ "description": "API Documentation for MGZon Chatbot by Mark Al-Asfar: Integrate AI for code generation, real-time web search, and e-commerce solutions.",
34
+ "keywords": ["MGZon API", "AI Integration", "Code Generation API", "E-commerce API", "Mark Al-Asfar", "FastAPI Docs", "Hugging Face API", "2025 AI API", "chatgpt api", "grok api", "deepseek api", "text generation api"],
35
+ "potentialAction": {
36
+ "@type": "SearchAction",
37
+ "target": "https://mgzon-mgzon-app.hf.space/?q={search_term_string}",
38
+ "query-input": "required name=search_term_string"
39
+ },
40
+ "publisher": {
41
+ "@type": "Organization",
42
+ "name": "MGZon AI",
43
+ "logo": {
44
+ "@type": "ImageObject",
45
+ "url": "/static/images/mg.svg"
46
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
  }
49
+ </script>
50
+ <script src="https://cdn.tailwindcss.com"></script>
51
+ <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
52
+ <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
53
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
54
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
55
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/particles.js/2.0.0/particles.min.js"></script>
56
+ <style>
57
+ :root {
58
+ --font-sans: 'Poppins', sans-serif;
59
+ --font-mono: 'Orbitron', monospace;
60
+ --radius: 1rem;
61
+ }
62
+
63
+ :root.dark {
64
+ --background: 220 70% 10%;
65
+ --foreground: 0 0% 95%;
66
+ --card: 220 70% 15%;
67
+ --card-foreground: 0 0% 90%;
68
+ --primary: 180 100% 50%;
69
+ --primary-foreground: 0 0% 0%;
70
+ --secondary: 260 80% 30%;
71
+ --secondary-foreground: 0 0% 95%;
72
+ --muted: 220 50% 20%;
73
+ --muted-foreground: 0 0% 70%;
74
+ --accent: 320 100% 60%;
75
+ --accent-foreground: 0 0% 95%;
76
+ --border: 220 50% 25%;
77
+ }
78
+
79
+ :root.light {
80
+ --background: 0 0% 100%;
81
+ --foreground: 220 70% 10%;
82
+ --card: 0 0% 95%;
83
+ --card-foreground: 220 70% 15%;
84
+ --primary: 180 100% 50%;
85
+ --primary-foreground: 0 0% 100%;
86
+ --secondary: 260 80% 40%;
87
+ --secondary-foreground: 0 0% 10%;
88
+ --muted: 0 0% 90%;
89
+ --muted-foreground: 0 0% 40%;
90
+ --accent: 320 100% 50%;
91
+ --accent-foreground: 0 0% 10%;
92
+ --border: 0 0% 80%;
93
+ }
94
+
95
+ * {
96
+ margin: 0;
97
+ padding: 0;
98
+ box-sizing: border-box;
99
+ }
100
+
101
+ body {
102
+ font-family: var(--font-sans);
103
+ background: hsl(var(--background));
104
+ color: hsl(var(--foreground));
105
+ line-height: 1.6;
106
+ min-height: 100vh;
107
+ position: relative;
108
+ overflow-x: hidden;
109
+ }
110
+
111
+ #particles-js {
112
+ position: fixed;
113
+ top: 0;
114
+ left: 0;
115
+ width: 100%;
116
+ height: 100%;
117
+ z-index: -1;
118
+ }
119
+
120
+ .container {
121
+ max-width: 1280px;
122
+ margin: 0 auto;
123
+ padding: 0 2rem;
124
+ }
125
+
126
+ .header {
127
+ padding: 2rem 0;
128
+ text-align: center;
129
+ background: linear-gradient(135deg, hsl(var(--background)), hsl(var(--card)));
130
+ }
131
+
132
+ .logo {
133
+ width: 200px;
134
+ height: auto;
135
+ filter: drop-shadow(0 0 20px hsl(var(--primary) / 0.5));
136
+ animation: logoSpin 10s linear infinite;
137
+ }
138
+
139
+ @keyframes logoSpin {
140
+ 0% { transform: rotateY(0deg) scale(1); }
141
+ 50% { transform: rotateY(180deg) scale(1.1); }
142
+ 100% { transform: rotateY(360deg) scale(1); }
143
+ }
144
+
145
+ .hero {
146
+ padding: 3rem 0;
147
+ text-align: center;
148
+ position: relative;
149
+ background: transparent;
150
+ }
151
+
152
+ .hero-tagline {
153
+ font-family: 'Orbitron', sans-serif;
154
+ font-size: 2.5rem;
155
+ font-weight: 700;
156
+ margin-bottom: 1.5rem;
157
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
158
+ -webkit-background-clip: text;
159
+ -webkit-text-fill-color: transparent;
160
+ animation: fadeIn 1s ease-out;
161
+ }
162
+
163
+ .hero .subtitle {
164
+ font-size: 1.2rem;
165
+ color: hsl(var(--muted-foreground));
166
+ margin-bottom: 2rem;
167
+ max-width: 800px;
168
+ margin-left: auto;
169
+ margin-right: auto;
170
+ animation: fadeIn 1s ease-out 0.3s both;
171
+ }
172
+
173
+ .highlight {
174
+ color: hsl(var(--primary));
175
+ font-weight: 600;
176
+ }
177
+
178
+ .nav-links {
179
+ display: flex;
180
+ justify-content: center;
181
+ gap: 1.5rem;
182
+ margin-bottom: 3rem;
183
+ flex-wrap: wrap;
184
+ animation: fadeIn 1s ease-out 0.6s both;
185
+ }
186
+
187
+ .nav-link {
188
+ padding: 1rem 2.5rem;
189
+ border-radius: var(--radius);
190
+ text-decoration: none;
191
+ font-family: 'Orbitron', sans-serif;
192
+ font-weight: 500;
193
+ transition: all 0.3s ease;
194
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
195
+ color: hsl(var(--card-foreground));
196
+ position: relative;
197
+ overflow: hidden;
198
+ box-shadow: 0 4px 15px hsl(var(--foreground) / 0.2);
199
+ }
200
+
201
+ .nav-link:hover {
202
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
203
+ color: hsl(var(--primary-foreground));
204
+ transform: translateY(-5px) scale(1.05);
205
+ box-shadow: 0 10px 30px hsl(var(--primary) / 0.5);
206
+ }
207
+
208
+ .nav-link::before {
209
+ content: '';
210
+ position: absolute;
211
+ top: 0;
212
+ left: -100%;
213
+ width: 100%;
214
+ height: 100%;
215
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
216
+ transition: left 0.5s;
217
+ }
218
+
219
+ .nav-link:hover::before {
220
+ left: 100%;
221
+ }
222
+
223
+ .cta-button {
224
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
225
+ color: hsl(var(--primary-foreground));
226
+ border: none !important;
227
+ font-size: 1.2rem;
228
+ padding: 1.2rem 3rem !important;
229
+ font-weight: 700;
230
+ }
231
+
232
+ .cta-button:hover {
233
+ box-shadow: 0 15px 40px hsl(var(--primary) / 0.6);
234
+ transform: translateY(-8px) scale(1.1);
235
+ }
236
+
237
+ .code-snippet {
238
+ background: hsl(var(--muted));
239
+ border: 1px solid hsl(var(--border));
240
+ border-radius: var(--radius);
241
+ padding: 1.5rem;
242
+ font-family: var(--font-mono);
243
+ font-size: 1rem;
244
+ color: hsl(var(--primary));
245
+ margin: 0 auto;
246
+ overflow-x: auto;
247
+ max-width: 700px;
248
+ position: relative;
249
+ animation: fadeIn 1s ease-out 0.8s both;
250
+ box-shadow: 0 5px 20px hsl(var(--primary) / 0.3);
251
+ }
252
+
253
+ .code-snippet::before {
254
+ content: '';
255
+ position: absolute;
256
+ top: 0;
257
+ left: 0;
258
+ right: 0;
259
+ height: 4px;
260
+ background: linear-gradient(90deg, hsl(var(--primary)), hsl(var(--accent)));
261
+ }
262
+
263
+ .quick-features {
264
+ padding: 4rem 0;
265
+ background: transparent;
266
+ }
267
+
268
+ .quick-features-grid {
269
+ display: grid;
270
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
271
+ gap: 2rem;
272
+ margin-top: 2rem;
273
+ }
274
+
275
+ .quick-feature {
276
+ text-align: center;
277
+ padding: 2rem;
278
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
279
+ border-radius: var(--radius);
280
+ transition: all 0.3s ease;
281
+ box-shadow: 0 5px 15px hsl(var(--foreground) / 0.2);
282
+ }
283
+
284
+ .quick-feature:hover {
285
+ transform: translateY(-10px) scale(1.05);
286
+ box-shadow: 0 15px 30px hsl(var(--primary) / 0.4);
287
+ }
288
+
289
+ .quick-feature-icon {
290
+ font-size: 3rem;
291
+ margin-bottom: 1.5rem;
292
+ display: block;
293
+ color: hsl(var(--primary));
294
+ transition: transform 0.3s ease;
295
+ }
296
+
297
+ .quick-feature:hover .quick-feature-icon {
298
+ transform: scale(1.2) rotate(5deg);
299
+ }
300
+
301
+ .quick-feature h3 {
302
+ font-size: 1.25rem;
303
+ font-weight: 600;
304
+ margin-bottom: 1rem;
305
+ color: hsl(var(--foreground));
306
+ }
307
+
308
+ .quick-feature p {
309
+ color: hsl(var(--muted-foreground));
310
+ font-size: 1rem;
311
+ }
312
+
313
+ .wave-divider {
314
+ height: 120px;
315
+ background: transparent;
316
+ position: relative;
317
+ overflow: hidden;
318
+ }
319
+
320
+ .wave-divider::before {
321
+ content: '';
322
+ position: absolute;
323
+ bottom: 0;
324
+ left: 0;
325
+ width: 200%;
326
+ height: 100%;
327
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--background)));
328
+ border-radius: 50%;
329
+ animation: wave 10s ease-in-out infinite;
330
+ }
331
+
332
+ @keyframes wave {
333
+ 0%, 100% { transform: translateX(-50%) translateY(70%); }
334
+ 50% { transform: translateX(-50%) translateY(50%); }
335
+ }
336
+
337
+ .features {
338
+ padding: 5rem 0;
339
+ background: hsl(var(--card));
340
+ }
341
+
342
+ .features-grid {
343
+ display: grid;
344
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
345
+ gap: 2.5rem;
346
+ margin-top: 3rem;
347
+ }
348
+
349
+ .feature-card {
350
+ padding: 2.5rem;
351
+ background: hsl(var(--background));
352
+ border: 1px solid hsl(var(--border));
353
+ border-radius: var(--radius);
354
+ transition: all 0.3s ease;
355
+ position: relative;
356
+ overflow: hidden;
357
+ box-shadow: 0 5px 20px hsl(var(--foreground) / 0.2);
358
+ }
359
+
360
+ .feature-card::before {
361
+ content: '';
362
+ position: absolute;
363
+ top: -2px;
364
+ left: -2px;
365
+ right: -2px;
366
+ bottom: -2px;
367
+ background: linear-gradient(45deg, hsl(var(--primary) / 0.2), transparent, hsl(var(--accent) / 0.2));
368
+ border-radius: var(--radius);
369
+ z-index: -1;
370
+ opacity: 0;
371
+ transition: opacity 0.3s ease;
372
+ }
373
+
374
+ .feature-card:hover::before {
375
+ opacity: 1;
376
+ }
377
+
378
+ .feature-card:hover {
379
+ transform: translateY(-10px) scale(1.05);
380
+ box-shadow: 0 20px 40px hsl(var(--primary) / 0.5);
381
+ }
382
+
383
+ .feature-icon {
384
+ width: 3.5rem;
385
+ height: 3.5rem;
386
+ background: linear-gradient(135deg, hsl(var(--primary) / 0.2), hsl(var(--accent) / 0.2));
387
+ border-radius: 50%;
388
+ display: flex;
389
+ align-items: center;
390
+ justify-content: center;
391
+ margin-bottom: 1.5rem;
392
+ font-size: 1.8rem;
393
+ color: hsl(var(--primary));
394
+ transition: transform 0.3s ease;
395
+ }
396
+
397
+ .feature-card:hover .feature-icon {
398
+ transform: rotate(360deg) scale(1.2);
399
+ }
400
+
401
+ .feature-card h3 {
402
+ font-size: 1.5rem;
403
+ font-weight: 700;
404
+ margin-bottom: 1rem;
405
+ color: hsl(var(--card-foreground));
406
+ }
407
+
408
+ .feature-card p {
409
+ color: hsl(var(--muted-foreground));
410
+ font-size: 1rem;
411
+ }
412
+
413
+ .section-title {
414
+ font-family: 'Orbitron', sans-serif;
415
+ text-align: center;
416
+ font-size: 3rem;
417
+ font-weight: 700;
418
+ margin-bottom: 1.5rem;
419
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
420
+ -webkit-background-clip: text;
421
+ -webkit-text-fill-color: transparent;
422
+ animation: fadeIn 1s ease-out;
423
+ }
424
+
425
+ .section-subtitle {
426
+ text-align: center;
427
+ color: hsl(var(--muted-foreground));
428
+ font-size: 1.2rem;
429
+ margin-bottom: 2rem;
430
+ }
431
+
432
+ .footer {
433
+ padding: 4rem 0;
434
+ border-top: 1px solid hsl(var(--border));
435
+ text-align: center;
436
+ background: linear-gradient(135deg, hsl(var(--background)), hsl(var(--card)));
437
+ }
438
+
439
+ .disclaimer {
440
+ background: hsl(var(--muted));
441
+ color: hsl(var(--muted-foreground));
442
+ padding: 2rem;
443
+ border-radius: var(--radius);
444
+ margin-bottom: 2rem;
445
+ border-left: 5px solid hsl(var(--primary));
446
+ box-shadow: 0 5px 20px hsl(var(--primary) / 0.3);
447
+ }
448
+
449
+ .disclaimer h4 {
450
+ font-weight: 700;
451
+ margin-bottom: 1rem;
452
+ color: hsl(var(--foreground));
453
+ }
454
+
455
+ .theme-toggle {
456
+ position: fixed;
457
+ top: 2rem;
458
+ right: 2rem;
459
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
460
+ border: 1px solid hsl(var(--border));
461
+ color: hsl(var(--card-foreground));
462
+ padding: 1rem;
463
+ border-radius: var(--radius);
464
+ cursor: pointer;
465
+ font-size: 1.5rem;
466
+ transition: all 0.3s ease;
467
+ z-index: 1000;
468
+ }
469
+
470
+ .theme-toggle:hover {
471
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
472
+ transform: scale(1.2) rotate(360deg);
473
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
474
+ }
475
+
476
+ @keyframes fadeIn {
477
+ from { opacity: 0; transform: translateY(40px); }
478
+ to { opacity: 1; transform: translateY(0); }
479
+ }
480
+
481
+ @media (max-width: 768px) {
482
+ .hero-tagline {
483
+ font-size: 2rem;
484
+ }
485
+
486
+ .nav-links {
487
+ flex-direction: column;
488
+ align-items: center;
489
+ }
490
+
491
+ .nav-link {
492
+ width: 250px;
493
+ text-align: center;
494
+ }
495
+
496
+ .container {
497
+ padding: 0 1.5rem;
498
+ }
499
+
500
+ .quick-features-grid {
501
+ grid-template-columns: 1fr;
502
+ }
503
+ }
504
+ </style>
505
  </head>
506
+ <body>
507
+ <div id="particles-js"></div>
508
+
509
+ <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
510
+
511
+ <header class="header">
512
+ <div class="container">
513
+ <img src="/static/images/mg.svg" alt="MGZon Logo" class="logo">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  </div>
515
+ </header>
516
+
517
+ <section class="hero">
518
+ <div class="container">
519
+ <h1 class="hero-tagline">MGZon Chatbot API Documentation</h1>
520
+ <p class="subtitle">
521
+ Explore the <span class="highlight">MGZon Chatbot API</span> for seamless integration of AI-powered code generation, text generation, and e-commerce automation. Built by Mark Al-Asfar using FastAPI and Hugging Face AI. Rivals tools like ChatGPT, Grok, and DeepSeek.
522
+ </p>
523
+
524
+ <div class="nav-links">
525
+ <a href="/" class="nav-link">Home</a>
526
+ <a href="/docs" class="nav-link">API Documentation</a>
527
+ <a href="/about" class="nav-link">About MGZon</a>
528
+ <a href="https://hager-zon.vercel.app/community" class="nav-link">Community</a>
529
+ <a href="https://mark-elasfar.web.app/" class="nav-link">Mark Al-Asfar</a>
530
+ <a href="/chat" class="nav-link cta-button">Launch Chatbot</a>
531
+ </div>
532
+
533
+ <div class="code-snippet">
534
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/chat" -H "Content-Type: application/json" -d '{"message": "Hello MGZon!"}'
535
+ </div>
 
 
 
 
536
  </div>
 
 
 
 
 
 
 
 
 
 
537
  </section>
538
+
539
+ <section class="quick-features">
540
+ <div class="container">
541
+ <div class="quick-features-grid">
542
+ <div class="quick-feature">
543
+ <span class="quick-feature-icon">🔑</span>
544
+ <h3>Authentication</h3>
545
+ <p>Secure JWT-based auth for all endpoints. Register and login to get started.</p>
546
+ </div>
547
+
548
+ <div class="quick-feature">
549
+ <span class="quick-feature-icon">📡</span>
550
+ <h3>Real-Time APIs</h3>
551
+ <p>Endpoints for chat, code generation, image analysis, and more.</p>
552
+ </div>
553
+
554
+ <div class="quick-feature">
555
+ <span class="quick-feature-icon">📊</span>
556
+ <h3>Performance Stats</h3>
557
+ <p>Monitor API performance and model info in real-time.</p>
558
+ </div>
559
+
560
+ <div class="quick-feature">
561
+ <span class="quick-feature-icon">🛡️</span>
562
+ <h3>Secure & Scalable</h3>
563
+ <p>Built with FastAPI for high performance and security.</p>
564
+ </div>
565
+ </div>
 
 
 
 
 
 
 
 
566
  </div>
567
+ </section>
568
+
569
+ <div class="wave-divider"></div>
570
+
571
+ <section class="features">
572
+ <div class="container">
573
+ <h2 class="section-title">API Endpoints Dashboard</h2>
574
+ <p class="section-subtitle">Browse and explore all available endpoints with examples and schemas.</p>
575
+
576
+ <div class="features-grid">
577
+ <div class="feature-card">
578
+ <div class="feature-icon">📄</div>
579
+ <h3>GET /openapi.json</h3>
580
+ <p>Retrieve the full OpenAPI specification in JSON format.</p>
581
+ <div class="code-snippet mt-2 text-sm">
582
+ curl -X GET "https://mgzon-mgzon-app.hf.space/openapi.json"
583
+ </div>
584
+ </div>
585
+
586
+ <div class="feature-card">
587
+ <div class="feature-icon">⚙️</div>
588
+ <h3>GET /api/settings</h3>
589
+ <p>Get current API settings and configurations.</p>
590
+ <div class="code-snippet mt-2 text-sm">
591
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/settings"
592
+ </div>
593
+ </div>
594
+
595
+ <div class="feature-card">
596
+ <div class="feature-icon">🤖</div>
597
+ <h3>GET /api/model-info</h3>
598
+ <p>Fetch information about the AI models in use.</p>
599
+ <div class="code-snippet mt-2 text-sm">
600
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/model-info"
601
+ </div>
602
+ </div>
603
+
604
+ <div class="feature-card">
605
+ <div class="feature-icon">📈</div>
606
+ <h3>GET /api/performance</h3>
607
+ <p>View performance statistics for the API.</p>
608
+ <div class="code-snippet mt-2 text-sm">
609
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/performance"
610
+ </div>
611
+ </div>
612
+
613
+ <div class="feature-card">
614
+ <div class="feature-icon">💬</div>
615
+ <h3>POST /api/chat</h3>
616
+ <p>Interact with the chatbot for queries and code generation.</p>
617
+ <div class="code-snippet mt-2 text-sm">
618
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/chat" -H "Content-Type: application/json" -d '{"message": "Generate code"}'
619
+ </div>
620
+ </div>
621
+
622
+ <div class="feature-card">
623
+ <div class="feature-icon">🖼️</div>
624
+ <h3>POST /api/image-generation</h3>
625
+ <p>Generate images based on text prompts.</p>
626
+ <div class="code-snippet mt-2 text-sm">
627
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/image-generation" -H "Content-Type: application/json" -d '{"prompt": "A futuristic city"}'
628
+ </div>
629
+ </div>
630
+
631
+ <div class="feature-card">
632
+ <div class="feature-icon">🎤</div>
633
+ <h3>POST /api/audio-transcription</h3>
634
+ <p>Transcribe audio files to text.</p>
635
+ <div class="code-snippet mt-2 text-sm">
636
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/audio-transcription" -F "file=@audio.wav"
637
+ </div>
638
+ </div>
639
+
640
+ <div class="feature-card">
641
+ <div class="feature-icon">🔊</div>
642
+ <h3>POST /api/text-to-speech</h3>
643
+ <p>Convert text to speech audio.</p>
644
+ <div class="code-snippet mt-2 text-sm">
645
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/text-to-speech" -H "Content-Type: application/json" -d '{"text": "Hello world"}'
646
+ </div>
647
+ </div>
648
+
649
+ <div class="feature-card">
650
+ <div class="feature-icon">💻</div>
651
+ <h3>POST /api/code</h3>
652
+ <p>Generate or analyze code snippets.</p>
653
+ <div class="code-snippet mt-2 text-sm">
654
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/code" -H "Content-Type: application/json" -d '{"prompt": "Write a Python function"}'
655
+ </div>
656
+ </div>
657
+
658
+ <div class="feature-card">
659
+ <div class="feature-icon">🔍</div>
660
+ <h3>POST /api/analysis</h3>
661
+ <p>Perform text or data analysis.</p>
662
+ <div class="code-snippet mt-2 text-sm">
663
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/analysis" -H "Content-Type: application/json" -d '{"data": "Analyze this text"}'
664
+ </div>
665
+ </div>
666
+
667
+ <div class="feature-card">
668
+ <div class="feature-icon">🖼️</div>
669
+ <h3>POST /api/image-analysis</h3>
670
+ <p>Analyze images for content and features.</p>
671
+ <div class="code-snippet mt-2 text-sm">
672
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/image-analysis" -F "file=@image.jpg"
673
+ </div>
674
+ </div>
675
+
676
+ <div class="feature-card">
677
+ <div class="feature-icon">🧪</div>
678
+ <h3>GET /api/test-model</h3>
679
+ <p>Test the AI model with a sample query.</p>
680
+ <div class="code-snippet mt-2 text-sm">
681
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/test-model"
682
+ </div>
683
+ </div>
684
+
685
+ <div class="feature-card">
686
+ <div class="feature-icon">📜</div>
687
+ <h3>GET /api/conversations</h3>
688
+ <p>List all user conversations.</p>
689
+ <div class="code-snippet mt-2 text-sm">
690
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/conversations"
691
+ </div>
692
+ </div>
693
+
694
+ <div class="feature-card">
695
+ <div class="feature-icon">➕</div>
696
+ <h3>POST /api/conversations</h3>
697
+ <p>Create a new conversation.</p>
698
+ <div class="code-snippet mt-2 text-sm">
699
+ curl -X POST "https://mgzon-mgzon-app.hf.space/api/conversations" -H "Content-Type: application/json" -d '{}'
700
+ </div>
701
+ </div>
702
+
703
+ <div class="feature-card">
704
+ <div class="feature-icon">📖</div>
705
+ <h3>GET /api/conversations/{conversation_id}</h3>
706
+ <p>Get details of a specific conversation.</p>
707
+ <div class="code-snippet mt-2 text-sm">
708
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/conversations/123"
709
+ </div>
710
+ </div>
711
+
712
+ <div class="feature-card">
713
+ <div class="feature-icon">🗑️</div>
714
+ <h3>DELETE /api/conversations/{conversation_id}</h3>
715
+ <p>Delete a conversation.</p>
716
+ <div class="code-snippet mt-2 text-sm">
717
+ curl -X DELETE "https://mgzon-mgzon-app.hf.space/api/conversations/123"
718
+ </div>
719
+ </div>
720
+
721
+ <div class="feature-card">
722
+ <div class="feature-icon">✏️</div>
723
+ <h3>PUT /api/conversations/{conversation_id}/title</h3>
724
+ <p>Update conversation title.</p>
725
+ <div class="code-snippet mt-2 text-sm">
726
+ curl -X PUT "https://mgzon-mgzon-app.hf.space/api/conversations/123/title" -H "Content-Type: application/json" -d '{"title": "New Title"}'
727
+ </div>
728
+ </div>
729
+
730
+ <div class="feature-card">
731
+ <div class="feature-icon">👤</div>
732
+ <h3>PUT /users/me</h3>
733
+ <p>Update current user settings.</p>
734
+ <div class="code-snippet mt-2 text-sm">
735
+ curl -X PUT "https://mgzon-mgzon-app.hf.space/users/me" -H "Content-Type: application/json" -d '{"settings": {}}'
736
+ </div>
737
+ </div>
738
+
739
+ <div class="feature-card">
740
+ <div class="feature-icon">🔒</div>
741
+ <h3>GET /api/verify-token</h3>
742
+ <p>Verify authentication token.</p>
743
+ <div class="code-snippet mt-2 text-sm">
744
+ curl -X GET "https://mgzon-mgzon-app.hf.space/api/verify-token"
745
+ </div>
746
+ </div>
747
+
748
+ <div class="feature-card">
749
+ <div class="feature-icon">🚪</div>
750
+ <h3>POST /logout</h3>
751
+ <p>Logout the current user.</p>
752
+ <div class="code-snippet mt-2 text-sm">
753
+ curl -X POST "https://mgzon-mgzon-app.hf.space/logout"
754
+ </div>
755
+ </div>
756
+
757
+ <div class="feature-card">
758
+ <div class="feature-icon">🐞</div>
759
+ <h3>GET /debug/routes</h3>
760
+ <p>Debug API routes (dev only).</p>
761
+ <div class="code-snippet mt-2 text-sm">
762
+ curl -X GET "https://mgzon-mgzon-app.hf.space/debug/routes"
763
+ </div>
764
+ </div>
765
+
766
+ <div class="feature-card">
767
+ <div class="feature-icon">🏠</div>
768
+ <h3>GET /</h3>
769
+ <p>Root endpoint for the app.</p>
770
+ <div class="code-snippet mt-2 text-sm">
771
+ curl -X GET "https://mgzon-mgzon-app.hf.space/"
772
+ </div>
773
+ </div>
774
+
775
+ <div class="feature-card">
776
+ <div class="feature-icon">📋</div>
777
+ <h3>GET /docs</h3>
778
+ <p>API Documentation page (you're here!).</p>
779
+ <div class="code-snippet mt-2 text-sm">
780
+ curl -X GET "https://mgzon-mgzon-app.hf.space/docs"
781
+ </div>
782
+ </div>
783
+
784
+ <!-- Add more endpoints as needed, following the same pattern -->
785
+
786
+ </div>
787
  </div>
788
+ </section>
789
+
790
+ <footer class="footer">
791
+ <div class="container">
792
+ <div class="disclaimer">
793
+ <h4>API Usage Guidelines</h4>
794
+ <p>
795
+ All endpoints require authentication unless specified. Use your JWT token in the Authorization header.
796
+ For full schemas and advanced usage, refer to /openapi.json.
797
+ </p>
798
+ <div style="text-align:center; margin-top: 1.5rem;">
799
+ <a href="/openapi.json" class="nav-link cta-button">Download OpenAPI JSON</a>
800
+ </div>
801
+ </div>
802
+ <div class="flex justify-center gap-6 mb-4">
803
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-github"></i></a>
804
+ <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-twitter"></i></a>
805
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-facebook"></i></a>
806
+ </div>
807
+ <p>© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
808
  </div>
809
+ </footer>
810
+
811
+ <button id="installAppBtn" style="display: none;" class="fixed bottom-4 right-4 bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] text-white px-6 py-3 rounded-full shadow-lg z-50">
812
+ 📲 Install MG Chat
813
+ </button>
814
+
815
+ <script>
816
+ // Particles.js initialization
817
+ particlesJS('particles-js', {
818
+ particles: {
819
+ number: { value: 80, density: { enable: true, value_area: 800 } },
820
+ color: { value: ['#00f0ff', '#ff007a', '#6b21a8'] },
821
+ shape: { type: 'circle' },
822
+ opacity: { value: 0.5, random: true },
823
+ size: { value: 3, random: true },
824
+ line_linked: { enable: true, distance: 150, color: '#00f0ff', opacity: 0.4, width: 1 },
825
+ move: { enable: true, speed: 3, direction: 'none', random: true }
826
+ },
827
+ interactivity: {
828
+ detect_on: 'canvas',
829
+ events: { onhover: { enable: true, mode: 'repulse' }, onclick: { enable: true, mode: 'push' } },
830
+ modes: { repulse: { distance: 100 }, push: { particles_nb: 4 } }
831
+ },
832
+ retina_detect: true
833
+ });
834
+
835
+ function toggleTheme() {
836
+ const html = document.documentElement;
837
+ const button = document.querySelector('.theme-toggle');
838
+ if (html.classList.contains('dark')) {
839
+ html.classList.remove('dark');
840
+ html.classList.add('light');
841
+ button.textContent = '☀️';
842
+ localStorage.setItem('theme', 'light');
843
+ } else {
844
+ html.classList.remove('light');
845
+ html.classList.add('dark');
846
+ button.textContent = '🌙';
847
+ localStorage.setItem('theme', 'dark');
848
+ }
849
+ }
850
+
851
+ // Load saved theme preference or system preference
852
+ const savedTheme = localStorage.getItem('theme');
853
+ if (savedTheme) {
854
+ document.documentElement.classList.remove('dark', 'light');
855
+ document.documentElement.classList.add(savedTheme);
856
+ document.querySelector('.theme-toggle').textContent = savedTheme === 'dark' ? '🌙' : '☀️';
857
+ } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
858
+ document.documentElement.classList.remove('dark');
859
+ document.documentElement.classList.add('light');
860
+ document.querySelector('.theme-toggle').textContent = '☀️';
861
+ localStorage.setItem('theme', 'light');
862
+ }
863
+
864
+ if ('serviceWorker' in navigator) {
865
+ navigator.serviceWorker.register('/static/js/sw.js')
866
+ .then(reg => console.log('✅ Service Worker Registered', reg))
867
+ .catch(err => console.error('❌ Service Worker registration failed', err));
868
+ }
869
+
870
+ let deferredPrompt;
871
+ window.addEventListener('beforeinstallprompt', (e) => {
872
+ e.preventDefault();
873
+ deferredPrompt = e;
874
+ const installBtn = document.getElementById('installAppBtn');
875
+ if (installBtn) {
876
+ installBtn.style.display = 'block';
877
+ installBtn.addEventListener('click', () => {
878
+ deferredPrompt.prompt();
879
+ deferredPrompt.userChoice.then(choice => {
880
+ console.log(choice.outcome === 'accepted' ? '✅ User accepted the install prompt' : '❌ User dismissed the install prompt');
881
+ deferredPrompt = null;
882
+ });
883
+ });
884
+ }
885
+ });
886
+ </script>
887
  </body>
888
  </html>
templates/index.html CHANGED
@@ -1,444 +1,715 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="description" content="MGZon Chatbot – AI-powered assistant for code generation, web search, and e-commerce solutions by Mark Al-Asfar from Alexandria, Egypt.">
7
- <meta name="keywords" content="MGZon Chatbot, AI assistant, code generation, e-commerce, Mark Al-Asfar, United States, FastAPI, Gradio">
8
- <meta name="author" content="Mark Al-Asfar">
9
- <meta name="robots" content="index, follow">
10
- <title>MGZon Chatbot – Powered by AI</title>
11
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
- <!-- manifest for Android/Chrome -->
13
- <link rel="manifest" href="/static/manifest.json">
14
- <!-- iOS Web App Support -->
15
- <link rel="apple-touch-icon" sizes="180x180" href="/static/images/mg-180.png">
16
- <meta name="apple-mobile-web-app-capable" content="yes">
17
- <meta name="apple-mobile-web-app-title" content="MGZon">
18
- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
19
- <!-- General Theme -->
20
- <meta name="theme-color" content="#2d3748">
21
- <!-- Open Graph -->
22
- <meta property="og:title" content="MGZon Chatbot – AI-Powered Solutions">
23
- <meta property="og:description" content="Explore MGZon Chatbot for code generation, web search, and e-commerce solutions by Mark Al-Asfar.">
24
- <meta property="og:image" content="/static/images/mg.svg">
25
- <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/">
26
- <meta property="og:type" content="website">
27
- <!-- Twitter Card -->
28
- <meta name="twitter:card" content="summary_large_image">
29
- <meta name="twitter:title" content="MGZon Chatbot – AI-Powered Solutions">
30
- <meta name="twitter:description" content="Explore MGZon Chatbot for code generation, web search, and e-commerce solutions by Mark Al-Asfar.">
31
- <meta name="twitter:image" content="/static/images/mg.svg">
32
- <!-- JSON-LD -->
33
- <script type="application/ld+json">
34
- {
35
- "@context": "https://schema.org",
36
- "@type": "WebSite",
37
- "name": "MGZon Chatbot",
38
- "url": "https://mgzon-mgzon-app.hf.space/",
39
- "description": "MGZon Chatbot by Mark Al-Asfar: Your AI assistant for code generation, real-time web search, and e-commerce solutions.",
40
- "keywords": ["MGZon Chatbot", "AI chatbot", "Code generation AI", "E-commerce AI solutions", "Mark Al-Asfar", "AI assistant for developers", "FastAPI chatbot", "Real-time web search AI", "MGZon AI", "Python AI chatbot", "AI for coding", "E-commerce automation", "Hugging Face AI", "2025 AI trends", "chatgpt", "grok", "deepseek", "text generation"],
41
- "potentialAction": {
42
- "@type": "SearchAction",
43
- "target": "https://mgzon-mgzon-app.hf.space/?q={search_term_string}",
44
- "query-input": "required name=search_term_string"
45
- },
46
- "publisher": {
47
- "@type": "Organization",
48
- "name": "MGZon AI",
49
- "logo": {
50
- "@type": "ImageObject",
51
- "url": "/static/images/mg.svg"
52
- }
53
- }
54
- }
55
- </script>
56
- <!-- Tailwind (v3) -->
57
- <script src="https://cdn.tailwindcss.com"></script>
58
- <!-- Boxicons -->
59
- <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
60
- <!-- Prism (for code highlighting) -->
61
- <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
62
- <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
63
- <style>
64
- @keyframes gradientShift {
65
- 0% { background-position: 0% 50%; }
66
- 50% { background-position: 100% 50%; }
67
- 100% { background-position: 0% 50%; }
68
- }
69
- body {
70
- background: linear-gradient(135deg, #0f172a, #0e7490, #065f46, #064e3b);
71
- background-size: 400% 400%;
72
- animation: gradientShift 15s ease infinite;
73
- font-family: system-ui, sans-serif;
74
- }
75
- .glass {
76
- background: rgba(255, 255, 255, 0.07);
77
- border-radius: 1rem;
78
- border: 1px solid rgba(255, 255, 255, 0.12);
79
- backdrop-filter: blur(12px);
80
- -webkit-backdrop-filter: blur(12px);
81
- }
82
- .sidebar {
83
- transition: transform 0.3s ease-in-out;
84
- }
85
- .sidebar.collapsed .logo {
86
- opacity: 0;
87
- transition: opacity 0.2s ease;
88
- }
89
- .main-content {
90
- min-height: calc(100vh - 4rem);
91
- }
92
- .loading {
93
- display: inline-block;
94
- width: 1rem;
95
- height: 1rem;
96
- border: 2px solid currentColor;
97
- border-top-color: transparent;
98
- border-radius: 50%;
99
- animation: spin 0.8s linear infinite;
100
- margin-left: 0.5rem;
101
- }
102
- @keyframes spin {
103
- to { transform: rotate(360deg); }
104
- }
105
- .glass:hover {
106
- transform: scale(1.05);
107
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
108
- background: rgba(255, 255, 255, 0.15);
109
- }
110
- @media (max-width: 768px) {
111
- .sidebar {
112
- transform: translateX(-100%);
113
- }
114
- .sidebar.active {
115
- transform: translateX(0);
116
  }
117
  }
118
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  </head>
120
- <body class="text-white flex flex-col min-h-screen">
121
- <!-- Mobile toggle button -->
122
- <button id="sidebarToggle" class="md:hidden fixed top-4 left-4 z-50 p-2 text-2xl text-white rounded bg-gray-800/60 hover:bg-gray-700/80 transition" aria-label="Toggle navigation">
123
- <i class="bx bx-menu"></i>
124
- </button>
125
- <!-- Sidebar -->
126
- <aside id="sidebar" class="sidebar fixed inset-y-0 left-0 w-64 bg-gradient-to-b from-teal-800 to-emerald-900 p-6 flex flex-col overflow-y-auto z-40">
127
- <button id="closeSidebar" class="md:hidden text-white text-2xl absolute top-4 right-4" aria-label="Close sidebar">✕</button>
128
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="logo w-20 h-20 mx-auto mb-8 animate-pulse">
129
- <nav class="flex flex-col gap-3">
130
- <a href="/" class="px-4 py-2 rounded-lg bg-emerald-600">Home</a>
131
- <a href="/docs" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">API Documentation</a>
132
- <a href="/about" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">About MGZon</a>
133
- {% if is_authenticated %}
134
- <a href="/chat" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Chat</a>
135
- <a id="logoutBtn" href="/logout" class="px-4 py-2 rounded-lg hover:bg-red-600 transition">Logout</a>
136
- {% else %}
137
- <a href="/login" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Login</a>
138
- <a href="/register" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Register</a>
139
- {% endif %}
140
- <a href="https://hager-zon.vercel.app/community" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Community</a>
141
- <a href="https://mark-elasfar.web.app/" target="_blank" class="px-4 py-2 rounded-lg hover:bg-emerald-600 transition">Mark Al-Asfar</a>
142
- </nav>
143
- </aside>
144
- <!-- Main content -->
145
- <main class="flex-1 md:ml-64 p-6 main-content">
146
- <section class="container max-w-6xl mx-auto">
147
- <!-- Hero -->
148
- <div class="text-center py-12">
149
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
150
- <h1 class="text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-300 to-emerald-400">
151
- Welcome to MGZon Chatbot 🚀
152
- </h1>
153
- <p class="text-lg max-w-2xl mx-auto mb-8">
154
- MGZon Chatbot is an AI-powered assistant for code generation, web search, and e-commerce solutions. Built with Gradio and FastAPI by Mark Al-Asfar from United States. Ready to code smarter and shop better? Discover MGZon Chatbot, an AI-powered assistant by Mark Al-Asfar for code generation, real-time web search, and e-commerce automation. Built with FastAPI and Hugging Face AI, MGZon rivals tools like ChatGPT, Grok, and DeepSeek.
155
- </p>
156
- {% if is_authenticated %}
157
- <div class="flex justify-center gap-4">
158
- <a href="/chat" id="launchBtn" class="inline-flex items-center bg-gradient-to-r from-emerald-500 to-teal-600 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition-transform shadow-lg hover:shadow-xl">
159
- Launch Chatbot <i class="bx bx-rocket ml-2"></i>
160
- <span id="spinner" class="loading hidden"></span>
161
- </a>
162
- <a id="logoutBtn" href="/logout" class="inline-flex items-center bg-gradient-to-r from-red-500 to-orange-600 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition-transform shadow-lg hover:shadow-xl">
163
- Logout <i class="bx bx-log-out ml-2"></i>
164
- </a>
165
- </div>
166
- {% else %}
167
- <div class="flex justify-center gap-4">
168
- <a href="/login" class="inline-flex items-center bg-gradient-to-r from-blue-500 to-cyan-600 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition-transform shadow-lg hover:shadow-xl">
169
- Login <i class="bx bx-log-in ml-2"></i>
170
- </a>
171
- <a href="/register" class="inline-flex items-center bg-gradient-to-r from-emerald-500 to-teal-600 text-white px-8 py-4 rounded-full text-lg font-semibold hover:scale-105 transition-transform shadow-lg hover:shadow-xl">
172
- Sign Up <i class="bx bx-user-plus ml-2"></i>
173
- </a>
174
- </div>
175
- {% endif %}
176
- </div>
177
- <!-- Features -->
178
- <section class="my-12">
179
- <h2 class="text-3xl font-bold text-center mb-8">Why Choose MGZon?</h2>
180
- <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
181
- <div class="glass p-6 relative group cursor-pointer" onclick="showCardDetails('code-generation')">
182
- <button class="absolute top-2 right-2 text-gray-300 hover:text-white transition" onclick="event.stopPropagation(); closeCardDetails('code-generation')" aria-label="Close card">&times;</button>
183
- <i class="bx bx-code-alt text-4xl text-emerald-300 mb-4"></i>
184
- <h3 class="text-xl font-semibold mb-2">Code Generation</h3>
185
- <p>Generate clean, well-commented code for React, Django, Flask, Node.js, and more.</p>
186
- <div id="code-generation-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
187
- <p>Supports multiple frameworks with examples and best practices for seamless integration.</p>
188
- <button onclick="closeCardDetails('code-generation')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
189
- </div>
190
- </div>
191
- <div class="glass p-6 relative group cursor-pointer" onclick="showCardDetails('web-search')">
192
- <button class="absolute top-2 right-2 text-gray-300 hover:text-white transition" onclick="event.stopPropagation(); closeCardDetails('web-search')" aria-label="Close card">&times;</button>
193
- <i class="bx bx-search text-4xl text-emerald-300 mb-4"></i>
194
- <h3 class="text-xl font-semibold mb-2">Web Search</h3>
195
- <p>Real-time web search for MGZon queries and industry insights.</p>
196
- <div id="web-search-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
197
- <p>Get up-to-date answers and insights tailored to your needs.</p>
198
- <button onclick="closeCardDetails('web-search')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
199
  </div>
200
- </div>
201
- <div class="glass p-6 relative group cursor-pointer" onclick="showCardDetails('ecommerce')">
202
- <button class="absolute top-2 right-2 text-gray-300 hover:text-white transition" onclick="event.stopPropagation(); closeCardDetails('ecommerce')" aria-label="Close card">&times;</button>
203
- <i class="bx bx-cart text-4xl text-emerald-300 mb-4"></i>
204
- <h3 class="text-xl font-semibold mb-2">E-commerce Solutions</h3>
205
- <p>AI-driven tools to optimize your online store and boost sales.</p>
206
- <div id="ecommerce-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
207
- <p>From product recommendations to inventory management, MGZon enhances your e-commerce experience.</p>
208
- <button onclick="closeCardDetails('ecommerce')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
209
  </div>
210
- </div>
211
  </div>
212
- </section>
213
- <!-- News -->
214
- <section class="my-12">
215
- <h2 class="text-3xl font-bold text-center mb-8">Latest MGZon Updates</h2>
216
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
217
- <div class="glass p-6">
218
- <h3 class="text-xl font-semibold mb-2">New AI Features</h3>
219
- <p>Explore our latest AI updates for smarter code and e-commerce tools.</p>
220
- <a href="/blog" target="_blank" class="text-emerald-300 hover:underline">Read More →</a>
221
- </div>
222
- <div class="glass p-6">
223
- <h3 class="text-xl font-semibold mb-2">Global Expansion</h3>
224
- <p>New warehouses in the USA, Canada, and China to serve you better.</p>
225
- <a href="https://hager-zon.vercel.app/community" target="_blank" class="text-emerald-300 hover:underline">Learn More →</a>
226
- </div>
227
- </div>
228
- </section>
229
- <!-- Testimonials -->
230
- <section class="my-12">
231
- <h2 class="text-3xl font-bold text-center mb-8">What Our Users Say</h2>
232
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
233
- <div class="glass p-6">
234
- <p class="mb-4">"MGZon Chatbot transformed how I code. The AI-generated snippets are accurate and save hours!"</p>
235
- <p class="font-semibold">– Ahmed, Developer</p>
236
- </div>
237
- <div class="glass p-6">
238
- <p class="mb-4">"The e-commerce tools helped me optimize my store and boost sales by 30%."</p>
239
- <p class="font-semibold">– Sarah, Store Owner</p>
240
- </div>
241
- </div>
242
- </section>
243
  </section>
244
- </main>
245
- <!-- Footer -->
246
- <footer class="bg-gradient-to-r from-teal-900 to-emerald-900 py-12 mt-8">
247
- <div class="container max-w-6xl mx-auto text-center">
248
- <img src="/static/images/mg.svg" alt="MGZon Chatbot Logo by Mark Al-Asfar" class="w-32 h-32 mx-auto mb-6 animate-bounce">
249
- <p class="mb-4">
250
- Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-emerald-300 hover:underline">Mark Al-Asfar</a>
251
- | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-emerald-300 hover:underline">MGZon AI</a>
252
- </p>
253
- <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
254
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('email')">
255
- <i class="bx bx-mail-send text-3xl text-emerald-300 mb-2"></i>
256
- <h4 class="font-semibold mb-1">Email Us</h4>
257
- <p><a href="mailto:support@mgzon.com" class="text-emerald-300 hover:underline">support@mgzon.com</a></p>
258
- <div id="email-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
259
- <p>Reach out to our support team for any inquiries or assistance.</p>
260
- <button onclick="closeCardDetails('email')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
261
- </div>
262
- </div>
263
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
264
- <i class="bx bx-phone text-3xl text-emerald-300 mb-2"></i>
265
- <h4 class="font-semibold mb-1">Phone Support</h4>
266
- <p>+1-800-123-4567</p>
267
- <div id="phone-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
268
- <p>Contact our support team via phone for immediate assistance.</p>
269
- <button onclick="closeCardDetails('phone')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
270
- </div>
271
- </div>
272
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('community')">
273
- <i class="bx bx-group text-3xl text-emerald-300 mb-2"></i>
274
- <h4 class="font-semibold mb-1">Community</h4>
275
- <p><a href="https://hager-zon.vercel.app/community" class="text-emerald-300 hover:underline">Join us</a></p>
276
- <div id="community-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
277
- <p>Join our vibrant community to share ideas and collaborate.</p>
278
- <button onclick="closeCardDetails('community')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
279
- </div>
280
- </div>
281
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
282
- <i class="bx bx-code-alt text-3xl text-emerald-300 mb-2"></i>
283
- <h4 class="font-semibold mb-1">API Docs</h4>
284
- <p><a href="/docs" class="text-emerald-300 hover:underline">Explore Docs</a></p>
285
- <div id="api-docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
286
- <p>Explore our API documentation for seamless integration.</p>
287
- <button onclick="closeCardDetails('api-docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
288
- </div>
289
- </div>
290
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
291
- <i class="bx bx-help-circle text-3xl text-emerald-300 mb-2"></i>
292
- <h4 class="font-semibold mb-1">FAQ</h4>
293
- <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-emerald-300 hover:underline">Read FAQ</a></p>
294
- <div id="faq-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
295
- <p>Find answers to common questions in our FAQ section.</p>
296
- <button onclick="closeCardDetails('faq')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
297
- </div>
298
- </div>
299
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
300
- <i class="bx bx-book text-3xl text-emerald-300 mb-2"></i>
301
- <h4 class="font-semibold mb-1">Documentation</h4>
302
- <p><a href="/docs" class="text-emerald-300 hover:underline">Full Docs</a></p>
303
- <div id="docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
304
- <p>Access comprehensive documentation for MGZon Chatbot.</p>
305
- <button onclick="closeCardDetails('docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
306
- </div>
307
- </div>
308
- </div>
309
- <div class="flex justify-center gap-6 mt-6">
310
- <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-github"></i></a>
311
- <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-twitter"></i></a>
312
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-facebook"></i></a>
313
- </div>
314
- <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
315
- </div>
316
- <button id="installAppBtn" style="display: none;" class="fixed bottom-4 right-4 bg-blue-600 text-white px-4 py-2 rounded shadow-lg z-50">
317
- 📲 Install MG Chat
318
- </button>
319
- </footer>
320
- <script>
321
- // Sidebar toggle
322
- const sidebar = document.getElementById('sidebar');
323
- const toggleBtn = document.getElementById('sidebarToggle');
324
- const closeSidebarBtn = document.getElementById('closeSidebar');
325
-
326
- if (toggleBtn && sidebar) {
327
- toggleBtn.addEventListener('click', () => {
328
- sidebar.classList.toggle('active');
329
- sidebar.classList.toggle('-translate-x-full');
330
- sidebar.classList.toggle('translate-x-0');
331
- console.log('Sidebar toggled');
332
- });
333
- } else {
334
- console.warn('Sidebar or toggle button not found');
335
- }
336
 
337
- if (closeSidebarBtn && sidebar) {
338
- closeSidebarBtn.addEventListener('click', () => {
339
- sidebar.classList.remove('active');
340
- sidebar.classList.add('-translate-x-full');
341
- sidebar.classList.remove('translate-x-0');
342
- console.log('Sidebar closed');
343
- });
344
- }
345
-
346
- // Close sidebar when clicking outside on mobile
347
- document.addEventListener('click', (e) => {
348
- if (!sidebar.contains(e.target) && !toggleBtn.contains(e.target) && window.innerWidth < 768) {
349
- sidebar.classList.remove('active');
350
- sidebar.classList.add('-translate-x-full');
351
- sidebar.classList.remove('translate-x-0');
352
- console.log('Sidebar closed due to outside click');
353
- }
354
- });
 
 
 
 
 
 
 
 
 
 
 
355
 
356
- // Show/hide card details
357
- function showCardDetails(cardId) {
358
- document.getElementById(`${cardId}-details`).classList.remove('hidden');
359
- }
360
 
361
- function closeCardDetails(cardId) {
362
- document.getElementById(`${cardId}-details`).classList.add('hidden');
363
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
- // Launch button spinner
366
- const launchBtn = document.getElementById('launchBtn');
367
- const spinner = document.getElementById('spinner');
368
- if (launchBtn && spinner) {
369
- launchBtn.addEventListener('click', (e) => {
370
- spinner.classList.remove('hidden');
371
- setTimeout(() => spinner.classList.add('hidden'), 2000);
372
- });
373
- }
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
- // Logout handler
376
- const logoutBtn = document.getElementById('logoutBtn');
377
- if (logoutBtn) {
378
- logoutBtn.addEventListener('click', async (e) => {
379
- e.preventDefault();
380
- console.log('Logout button clicked');
381
- try {
382
- const response = await fetch('/logout', {
383
- method: 'GET',
384
- credentials: 'include'
385
- });
386
- if (response.ok) {
387
- localStorage.removeItem('token');
388
- console.log('Token removed from localStorage');
389
- window.location.href = '/login';
390
- } else {
391
- console.error('Logout failed:', response.status);
392
- alert('Failed to log out. Please try again.');
393
- }
394
- } catch (error) {
395
- console.error('Logout error:', error);
396
- alert('Error during logout: ' + error.message);
397
- }
398
- });
399
- }
400
 
401
- // Service Worker for PWA
402
- if ('serviceWorker' in navigator) {
403
- navigator.serviceWorker.register('/static/js/sw.js')
404
- .then(function(reg) {
405
- console.log('✅ Service Worker Registered', reg);
406
- }).catch(function(err) {
407
- console.error('❌ Service Worker registration failed', err);
 
 
 
 
 
 
 
 
 
 
 
408
  });
409
- }
410
 
411
- // Handle beforeinstallprompt for PWA
412
- let deferredPrompt;
413
- window.addEventListener('beforeinstallprompt', (e) => {
414
- e.preventDefault();
415
- deferredPrompt = e;
416
- const installBtn = document.getElementById('installAppBtn');
417
- if (installBtn) {
418
- installBtn.style.display = 'block';
419
- installBtn.addEventListener('click', () => {
420
- deferredPrompt.prompt();
421
- deferredPrompt.userChoice.then(choice => {
422
- if (choice.outcome === 'accepted') {
423
- console.log('✅ User accepted the install prompt');
424
  } else {
425
- console.log('❌ User dismissed the install prompt');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
  }
427
- deferredPrompt = null;
428
- });
429
  });
430
- }
431
- });
432
-
433
- // Card animations
434
- document.querySelectorAll('.glass').forEach(card => {
435
- card.addEventListener('mouseenter', () => {
436
- card.style.transform = 'scale(1.05) rotate(1deg)';
437
- });
438
- card.addEventListener('mouseleave', () => {
439
- card.style.transform = 'scale(1) rotate(0deg)';
440
- });
441
- });
442
- </script>
443
  </body>
444
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="description" content="MGZon Chatbot – AI-powered assistant for code generation, web search, and e-commerce solutions by Mark Al-Asfar from Alexandria, Egypt.">
7
+ <meta name="keywords" content="MGZon Chatbot, AI assistant, code generation, e-commerce, Mark Al-Asfar, United States, FastAPI, Gradio">
8
+ <meta name="author" content="Mark Al-Asfar">
9
+ <meta name="robots" content="index, follow">
10
+ <title>MGZon Chatbot – Powered by AI</title>
11
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
+ <link rel="manifest" href="/static/manifest.json">
13
+ <link rel="apple-touch-icon" sizes="180x180" href="/static/images/mg-180.png">
14
+ <meta name="apple-mobile-web-app-capable" content="yes">
15
+ <meta name="apple-mobile-web-app-title" content="MGZon">
16
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
17
+ <meta name="theme-color" content="#00f0ff">
18
+ <meta property="og:title" content="MGZon Chatbot – AI-Powered Solutions">
19
+ <meta property="og:description" content="Explore MGZon Chatbot for code generation, web search, and e-commerce solutions by Mark Al-Asfar.">
20
+ <meta property="og:image" content="/static/images/mg.svg">
21
+ <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/">
22
+ <meta property="og:type" content="website">
23
+ <meta name="twitter:card" content="summary_large_image">
24
+ <meta name="twitter:title" content="MGZon Chatbot – AI-Powered Solutions">
25
+ <meta name="twitter:description" content="Explore MGZon Chatbot for code generation, web search, and e-commerce solutions by Mark Al-Asfar.">
26
+ <meta name="twitter:image" content="/static/images/mg.svg">
27
+ <script type="application/ld+json">
28
+ {
29
+ "@context": "https://schema.org",
30
+ "@type": "WebSite",
31
+ "name": "MGZon Chatbot",
32
+ "url": "https://mgzon-mgzon-app.hf.space/",
33
+ "description": "MGZon Chatbot by Mark Al-Asfar: Your AI assistant for code generation, real-time web search, and e-commerce solutions.",
34
+ "keywords": ["MGZon Chatbot", "AI chatbot", "Code generation AI", "E-commerce AI solutions", "Mark Al-Asfar", "AI assistant for developers", "FastAPI chatbot", "Real-time web search AI", "MGZon AI", "Python AI chatbot", "AI for coding", "E-commerce automation", "Hugging Face AI", "2025 AI trends", "chatgpt", "grok", "deepseek", "text generation"],
35
+ "potentialAction": {
36
+ "@type": "SearchAction",
37
+ "target": "https://mgzon-mgzon-app.hf.space/?q={search_term_string}",
38
+ "query-input": "required name=search_term_string"
39
+ },
40
+ "publisher": {
41
+ "@type": "Organization",
42
+ "name": "MGZon AI",
43
+ "logo": {
44
+ "@type": "ImageObject",
45
+ "url": "/static/images/mg.svg"
46
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
  }
49
+ </script>
50
+ <script src="https://cdn.tailwindcss.com"></script>
51
+ <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
52
+ <link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css" rel="stylesheet">
53
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
54
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
55
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/particles.js/2.0.0/particles.min.js"></script>
56
+ <style>
57
+ :root {
58
+ --font-sans: 'Poppins', sans-serif;
59
+ --font-mono: 'Orbitron', monospace;
60
+ --radius: 1rem;
61
+ }
62
+
63
+ :root.dark {
64
+ --background: 220 70% 10%;
65
+ --foreground: 0 0% 95%;
66
+ --card: 220 70% 15%;
67
+ --card-foreground: 0 0% 90%;
68
+ --primary: 180 100% 50%;
69
+ --primary-foreground: 0 0% 0%;
70
+ --secondary: 260 80% 30%;
71
+ --secondary-foreground: 0 0% 95%;
72
+ --muted: 220 50% 20%;
73
+ --muted-foreground: 0 0% 70%;
74
+ --accent: 320 100% 60%;
75
+ --accent-foreground: 0 0% 95%;
76
+ --border: 220 50% 25%;
77
+ }
78
+
79
+ :root.light {
80
+ --background: 0 0% 100%;
81
+ --foreground: 220 70% 10%;
82
+ --card: 0 0% 95%;
83
+ --card-foreground: 220 70% 15%;
84
+ --primary: 180 100% 50%;
85
+ --primary-foreground: 0 0% 100%;
86
+ --secondary: 260 80% 40%;
87
+ --secondary-foreground: 0 0% 10%;
88
+ --muted: 0 0% 90%;
89
+ --muted-foreground: 0 0% 40%;
90
+ --accent: 320 100% 50%;
91
+ --accent-foreground: 0 0% 10%;
92
+ --border: 0 0% 80%;
93
+ }
94
+
95
+ * {
96
+ margin: 0;
97
+ padding: 0;
98
+ box-sizing: border-box;
99
+ }
100
+
101
+ body {
102
+ font-family: var(--font-sans);
103
+ background: hsl(var(--background));
104
+ color: hsl(var(--foreground));
105
+ line-height: 1.6;
106
+ min-height: 100vh;
107
+ position: relative;
108
+ overflow-x: hidden;
109
+ }
110
+
111
+ #particles-js {
112
+ position: fixed;
113
+ top: 0;
114
+ left: 0;
115
+ width: 100%;
116
+ height: 100%;
117
+ z-index: -1;
118
+ }
119
+
120
+ .container {
121
+ max-width: 1280px;
122
+ margin: 0 auto;
123
+ padding: 0 2rem;
124
+ }
125
+
126
+ .header {
127
+ padding: 2rem 0;
128
+ text-align: center;
129
+ background: linear-gradient(135deg, hsl(var(--background)), hsl(var(--card)));
130
+ }
131
+
132
+ .logo {
133
+ width: 200px;
134
+ height: auto;
135
+ filter: drop-shadow(0 0 20px hsl(var(--primary) / 0.5));
136
+ animation: logoSpin 10s linear infinite;
137
+ }
138
+
139
+ @keyframes logoSpin {
140
+ 0% { transform: rotateY(0deg) scale(1); }
141
+ 50% { transform: rotateY(180deg) scale(1.1); }
142
+ 100% { transform: rotateY(360deg) scale(1); }
143
+ }
144
+
145
+ .hero {
146
+ padding: 3rem 0;
147
+ text-align: center;
148
+ position: relative;
149
+ background: transparent;
150
+ }
151
+
152
+ .hero-tagline {
153
+ font-family: 'Orbitron', sans-serif;
154
+ font-size: 2.5rem;
155
+ font-weight: 700;
156
+ margin-bottom: 1.5rem;
157
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
158
+ -webkit-background-clip: text;
159
+ -webkit-text-fill-color: transparent;
160
+ animation: fadeIn 1s ease-out;
161
+ }
162
+
163
+ .hero .subtitle {
164
+ font-size: 1.2rem;
165
+ color: hsl(var(--muted-foreground));
166
+ margin-bottom: 2rem;
167
+ max-width: 800px;
168
+ margin-left: auto;
169
+ margin-right: auto;
170
+ animation: fadeIn 1s ease-out 0.3s both;
171
+ }
172
+
173
+ .highlight {
174
+ color: hsl(var(--primary));
175
+ font-weight: 600;
176
+ }
177
+
178
+ .nav-links {
179
+ display: flex;
180
+ justify-content: center;
181
+ gap: 1.5rem;
182
+ margin-bottom: 3rem;
183
+ flex-wrap: wrap;
184
+ animation: fadeIn 1s ease-out 0.6s both;
185
+ }
186
+
187
+ .nav-link {
188
+ padding: 1rem 2.5rem;
189
+ border-radius: var(--radius);
190
+ text-decoration: none;
191
+ font-family: 'Orbitron', sans-serif;
192
+ font-weight: 500;
193
+ transition: all 0.3s ease;
194
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
195
+ color: hsl(var(--card-foreground));
196
+ position: relative;
197
+ overflow: hidden;
198
+ box-shadow: 0 4px 15px hsl(var(--foreground) / 0.2);
199
+ }
200
+
201
+ .nav-link:hover {
202
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
203
+ color: hsl(var(--primary-foreground));
204
+ transform: translateY(-5px) scale(1.05);
205
+ box-shadow: 0 10px 30px hsl(var(--primary) / 0.5);
206
+ }
207
+
208
+ .nav-link::before {
209
+ content: '';
210
+ position: absolute;
211
+ top: 0;
212
+ left: -100%;
213
+ width: 100%;
214
+ height: 100%;
215
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
216
+ transition: left 0.5s;
217
+ }
218
+
219
+ .nav-link:hover::before {
220
+ left: 100%;
221
+ }
222
+
223
+ .cta-button {
224
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
225
+ color: hsl(var(--primary-foreground));
226
+ border: none !important;
227
+ font-size: 1.2rem;
228
+ padding: 1.2rem 3rem !important;
229
+ font-weight: 700;
230
+ }
231
+
232
+ .cta-button:hover {
233
+ box-shadow: 0 15px 40px hsl(var(--primary) / 0.6);
234
+ transform: translateY(-8px) scale(1.1);
235
+ }
236
+
237
+ .code-snippet {
238
+ background: hsl(var(--muted));
239
+ border: 1px solid hsl(var(--border));
240
+ border-radius: var(--radius);
241
+ padding: 1.5rem;
242
+ font-family: var(--font-mono);
243
+ font-size: 1rem;
244
+ color: hsl(var(--primary));
245
+ margin: 0 auto;
246
+ overflow-x: auto;
247
+ max-width: 700px;
248
+ position: relative;
249
+ animation: fadeIn 1s ease-out 0.8s both;
250
+ box-shadow: 0 5px 20px hsl(var(--primary) / 0.3);
251
+ }
252
+
253
+ .code-snippet::before {
254
+ content: '';
255
+ position: absolute;
256
+ top: 0;
257
+ left: 0;
258
+ right: 0;
259
+ height: 4px;
260
+ background: linear-gradient(90deg, hsl(var(--primary)), hsl(var(--accent)));
261
+ }
262
+
263
+ .quick-features {
264
+ padding: 4rem 0;
265
+ background: transparent;
266
+ }
267
+
268
+ .quick-features-grid {
269
+ display: grid;
270
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
271
+ gap: 2rem;
272
+ margin-top: 2rem;
273
+ }
274
+
275
+ .quick-feature {
276
+ text-align: center;
277
+ padding: 2rem;
278
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
279
+ border-radius: var(--radius);
280
+ transition: all 0.3s ease;
281
+ box-shadow: 0 5px 15px hsl(var(--foreground) / 0.2);
282
+ }
283
+
284
+ .quick-feature:hover {
285
+ transform: translateY(-10px) scale(1.05);
286
+ box-shadow: 0 15px 30px hsl(var(--primary) / 0.4);
287
+ }
288
+
289
+ .quick-feature-icon {
290
+ font-size: 3rem;
291
+ margin-bottom: 1.5rem;
292
+ display: block;
293
+ color: hsl(var(--primary));
294
+ transition: transform 0.3s ease;
295
+ }
296
+
297
+ .quick-feature:hover .quick-feature-icon {
298
+ transform: scale(1.2) rotate(5deg);
299
+ }
300
+
301
+ .quick-feature h3 {
302
+ font-size: 1.25rem;
303
+ font-weight: 600;
304
+ margin-bottom: 1rem;
305
+ color: hsl(var(--foreground));
306
+ }
307
+
308
+ .quick-feature p {
309
+ color: hsl(var(--muted-foreground));
310
+ font-size: 1rem;
311
+ }
312
+
313
+ .wave-divider {
314
+ height: 120px;
315
+ background: transparent;
316
+ position: relative;
317
+ overflow: hidden;
318
+ }
319
+
320
+ .wave-divider::before {
321
+ content: '';
322
+ position: absolute;
323
+ bottom: 0;
324
+ left: 0;
325
+ width: 200%;
326
+ height: 100%;
327
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--background)));
328
+ border-radius: 50%;
329
+ animation: wave 10s ease-in-out infinite;
330
+ }
331
+
332
+ @keyframes wave {
333
+ 0%, 100% { transform: translateX(-50%) translateY(70%); }
334
+ 50% { transform: translateX(-50%) translateY(50%); }
335
+ }
336
+
337
+ .features {
338
+ padding: 5rem 0;
339
+ background: hsl(var(--card));
340
+ }
341
+
342
+ .features-grid {
343
+ display: grid;
344
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
345
+ gap: 2.5rem;
346
+ margin-top: 3rem;
347
+ }
348
+
349
+ .feature-card {
350
+ padding: 2.5rem;
351
+ background: hsl(var(--background));
352
+ border: 1px solid hsl(var(--border));
353
+ border-radius: var(--radius);
354
+ transition: all 0.3s ease;
355
+ position: relative;
356
+ overflow: hidden;
357
+ box-shadow: 0 5px 20px hsl(var(--foreground) / 0.2);
358
+ }
359
+
360
+ .feature-card::before {
361
+ content: '';
362
+ position: absolute;
363
+ top: -2px;
364
+ left: -2px;
365
+ right: -2px;
366
+ bottom: -2px;
367
+ background: linear-gradient(45deg, hsl(var(--primary) / 0.2), transparent, hsl(var(--accent) / 0.2));
368
+ border-radius: var(--radius);
369
+ z-index: -1;
370
+ opacity: 0;
371
+ transition: opacity 0.3s ease;
372
+ }
373
+
374
+ .feature-card:hover::before {
375
+ opacity: 1;
376
+ }
377
+
378
+ .feature-card:hover {
379
+ transform: translateY(-10px) scale(1.05);
380
+ box-shadow: 0 20px 40px hsl(var(--primary) / 0.5);
381
+ }
382
+
383
+ .feature-icon {
384
+ width: 3.5rem;
385
+ height: 3.5rem;
386
+ background: linear-gradient(135deg, hsl(var(--primary) / 0.2), hsl(var(--accent) / 0.2));
387
+ border-radius: 50%;
388
+ display: flex;
389
+ align-items: center;
390
+ justify-content: center;
391
+ margin-bottom: 1.5rem;
392
+ font-size: 1.8rem;
393
+ color: hsl(var(--primary));
394
+ transition: transform 0.3s ease;
395
+ }
396
+
397
+ .feature-card:hover .feature-icon {
398
+ transform: rotate(360deg) scale(1.2);
399
+ }
400
+
401
+ .feature-card h3 {
402
+ font-size: 1.5rem;
403
+ font-weight: 700;
404
+ margin-bottom: 1rem;
405
+ color: hsl(var(--card-foreground));
406
+ }
407
+
408
+ .feature-card p {
409
+ color: hsl(var(--muted-foreground));
410
+ font-size: 1rem;
411
+ }
412
+
413
+ .section-title {
414
+ font-family: 'Orbitron', sans-serif;
415
+ text-align: center;
416
+ font-size: 3rem;
417
+ font-weight: 700;
418
+ margin-bottom: 1.5rem;
419
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
420
+ -webkit-background-clip: text;
421
+ -webkit-text-fill-color: transparent;
422
+ animation: fadeIn 1s ease-out;
423
+ }
424
+
425
+ .section-subtitle {
426
+ text-align: center;
427
+ color: hsl(var(--muted-foreground));
428
+ font-size: 1.2rem;
429
+ margin-bottom: 2rem;
430
+ }
431
+
432
+ .footer {
433
+ padding: 4rem 0;
434
+ border-top: 1px solid hsl(var(--border));
435
+ text-align: center;
436
+ background: linear-gradient(135deg, hsl(var(--background)), hsl(var(--card)));
437
+ }
438
+
439
+ .disclaimer {
440
+ background: hsl(var(--muted));
441
+ color: hsl(var(--muted-foreground));
442
+ padding: 2rem;
443
+ border-radius: var(--radius);
444
+ margin-bottom: 2rem;
445
+ border-left: 5px solid hsl(var(--primary));
446
+ box-shadow: 0 5px 20px hsl(var(--primary) / 0.3);
447
+ }
448
+
449
+ .disclaimer h4 {
450
+ font-weight: 700;
451
+ margin-bottom: 1rem;
452
+ color: hsl(var(--foreground));
453
+ }
454
+
455
+ .theme-toggle {
456
+ position: fixed;
457
+ top: 2rem;
458
+ right: 2rem;
459
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
460
+ border: 1px solid hsl(var(--border));
461
+ color: hsl(var(--card-foreground));
462
+ padding: 1rem;
463
+ border-radius: var(--radius);
464
+ cursor: pointer;
465
+ font-size: 1.5rem;
466
+ transition: all 0.3s ease;
467
+ z-index: 1000;
468
+ }
469
+
470
+ .theme-toggle:hover {
471
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
472
+ transform: scale(1.2) rotate(360deg);
473
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
474
+ }
475
+
476
+ @keyframes fadeIn {
477
+ from { opacity: 0; transform: translateY(40px); }
478
+ to { opacity: 1; transform: translateY(0); }
479
+ }
480
+
481
+ @media (max-width: 768px) {
482
+ .hero-tagline {
483
+ font-size: 2rem;
484
+ }
485
+
486
+ .nav-links {
487
+ flex-direction: column;
488
+ align-items: center;
489
+ }
490
+
491
+ .nav-link {
492
+ width: 250px;
493
+ text-align: center;
494
+ }
495
+
496
+ .container {
497
+ padding: 0 1.5rem;
498
+ }
499
+
500
+ .quick-features-grid {
501
+ grid-template-columns: 1fr;
502
+ }
503
+ }
504
+ </style>
505
  </head>
506
+ <body>
507
+ <div id="particles-js"></div>
508
+
509
+ <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
510
+
511
+ <header class="header">
512
+ <div class="container">
513
+ <img src="/static/images/mg.svg" alt="MGZon Logo" class="logo">
514
+ </div>
515
+ </header>
516
+
517
+ <section class="hero">
518
+ <div class="container">
519
+ <h1 class="hero-tagline">MGZon Chatbot – Powered by AI</h1>
520
+ <p class="subtitle">
521
+ MGZon Chatbot is an <span class="highlight">AI-powered assistant</span> for code generation, web search, and e-commerce solutions. Built with Gradio and FastAPI by Mark Al-Asfar from United States. Ready to code smarter and shop better? Discover MGZon Chatbot, an AI-powered assistant by Mark Al-Asfar for code generation, real-time web search, and e-commerce automation. Built with FastAPI and Hugging Face AI, MGZon rivals tools like ChatGPT, Grok, and DeepSeek.
522
+ </p>
523
+
524
+ <div class="nav-links">
525
+ <a href="/" class="nav-link">Home</a>
526
+ <a href="/docs" class="nav-link">API Documentation</a>
527
+ <a href="/about" class="nav-link">About MGZon</a>
528
+ <a href="https://hager-zon.vercel.app/community" class="nav-link">Community</a>
529
+ <a href="https://mark-elasfar.web.app/" class="nav-link">Mark Al-Asfar</a>
530
+ <a href="/chat" class="nav-link cta-button">Launch Chatbot</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
  </div>
532
+
533
+ <div class="code-snippet">
534
+ uvicorn main:app --reload
 
 
 
 
 
 
535
  </div>
 
536
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
  </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
 
539
+ <section class="quick-features">
540
+ <div class="container">
541
+ <div class="quick-features-grid">
542
+ <div class="quick-feature">
543
+ <span class="quick-feature-icon">🧠</span>
544
+ <h3>Code Generation</h3>
545
+ <p>Generate clean, well-commented code for React, Django, Flask, Node.js, and more.</p>
546
+ </div>
547
+
548
+ <div class="quick-feature">
549
+ <span class="quick-feature-icon">⚡</span>
550
+ <h3>Web Search</h3>
551
+ <p>Real-time web search for MGZon queries and industry insights.</p>
552
+ </div>
553
+
554
+ <div class="quick-feature">
555
+ <span class="quick-feature-icon">🔗</span>
556
+ <h3>E-commerce Solutions</h3>
557
+ <p>AI-driven tools to optimize your online store and boost sales.</p>
558
+ </div>
559
+
560
+ <div class="quick-feature">
561
+ <span class="quick-feature-icon">🌊</span>
562
+ <h3>AI Assistant</h3>
563
+ <p>Your AI assistant for developers, powered by FastAPI and Hugging Face AI.</p>
564
+ </div>
565
+ </div>
566
+ </div>
567
+ </section>
568
 
569
+ <div class="wave-divider"></div>
 
 
 
570
 
571
+ <section class="features">
572
+ <div class="container">
573
+ <h2 class="section-title">Why Choose MGZon?</h2>
574
+ <p class="section-subtitle">Experience the power of AI-powered solutions for code, search, and e-commerce</p>
575
+
576
+ <div class="features-grid">
577
+ <div class="feature-card">
578
+ <div class="feature-icon">🔒</div>
579
+ <h3>Secure & Private</h3>
580
+ <p>We do not persist any data regarding your interactions or API keys - everything stays local and private.</p>
581
+ </div>
582
+
583
+ <div class="feature-card">
584
+ <div class="feature-icon">👁️</div>
585
+ <h3>Real-Time Insights</h3>
586
+ <p>Get up-to-date answers and insights tailored to your needs with real-time web search.</p>
587
+ </div>
588
+
589
+ <div class="feature-card">
590
+ <div class="feature-icon">🧠</div>
591
+ <h3>Context-Aware AI</h3>
592
+ <p>MGZon loads relevant data for your queries, making it fast and precise.</p>
593
+ </div>
594
+
595
+ <div class="feature-card">
596
+ <div class="feature-icon">🤝</div>
597
+ <h3>Developer-Friendly</h3>
598
+ <p>Supports multiple frameworks with examples and best practices for seamless integration.</p>
599
+ </div>
600
+
601
+ <div class="feature-card">
602
+ <div class="feature-icon">⚡</div>
603
+ <h3>Efficient Automation</h3>
604
+ <p>From product recommendations to inventory management, enhance your e-commerce experience.</p>
605
+ </div>
606
+
607
+ <div class="feature-card">
608
+ <div class="feature-icon">🎯</div>
609
+ <h3>Precision-Driven</h3>
610
+ <p>AI-generated snippets are accurate and save hours, boosting productivity.</p>
611
+ </div>
612
+ </div>
613
+ </div>
614
+ </section>
615
 
616
+ <footer class="footer">
617
+ <div class="container">
618
+ <div class="disclaimer">
619
+ <h4>Getting Started</h4>
620
+ <p>
621
+ To use MGZon Chatbot, simply launch the chatbot interface.
622
+ You can use our pre-configured AI models or bring your own.
623
+ We do not persist any data regarding your queries or interactions - everything stays local and private.
624
+ </p>
625
+ <div style="text-align:center; margin-top: 1.5rem;">
626
+ <a href="/chat" class="nav-link cta-button">Launch Chatbot</a>
627
+ </div>
628
+ </div>
629
+ <div class="flex justify-center gap-6 mb-4">
630
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-github"></i></a>
631
+ <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-twitter"></i></a>
632
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-facebook"></i></a>
633
+ </div>
634
+ <p>© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
635
+ </div>
636
+ </footer>
637
 
638
+ <button id="installAppBtn" style="display: none;" class="fixed bottom-4 right-4 bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] text-white px-6 py-3 rounded-full shadow-lg z-50">
639
+ 📲 Install MG Chat
640
+ </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
 
642
+ <script>
643
+ // Particles.js initialization
644
+ particlesJS('particles-js', {
645
+ particles: {
646
+ number: { value: 80, density: { enable: true, value_area: 800 } },
647
+ color: { value: ['#00f0ff', '#ff007a', '#6b21a8'] },
648
+ shape: { type: 'circle' },
649
+ opacity: { value: 0.5, random: true },
650
+ size: { value: 3, random: true },
651
+ line_linked: { enable: true, distance: 150, color: '#00f0ff', opacity: 0.4, width: 1 },
652
+ move: { enable: true, speed: 3, direction: 'none', random: true }
653
+ },
654
+ interactivity: {
655
+ detect_on: 'canvas',
656
+ events: { onhover: { enable: true, mode: 'repulse' }, onclick: { enable: true, mode: 'push' } },
657
+ modes: { repulse: { distance: 100 }, push: { particles_nb: 4 } }
658
+ },
659
+ retina_detect: true
660
  });
 
661
 
662
+ function toggleTheme() {
663
+ const html = document.documentElement;
664
+ const button = document.querySelector('.theme-toggle');
665
+ if (html.classList.contains('dark')) {
666
+ html.classList.remove('dark');
667
+ html.classList.add('light');
668
+ button.textContent = '☀️';
669
+ localStorage.setItem('theme', 'light');
 
 
 
 
 
670
  } else {
671
+ html.classList.remove('light');
672
+ html.classList.add('dark');
673
+ button.textContent = '🌙';
674
+ localStorage.setItem('theme', 'dark');
675
+ }
676
+ }
677
+
678
+ // Load saved theme preference or system preference
679
+ const savedTheme = localStorage.getItem('theme');
680
+ if (savedTheme) {
681
+ document.documentElement.classList.remove('dark', 'light');
682
+ document.documentElement.classList.add(savedTheme);
683
+ document.querySelector('.theme-toggle').textContent = savedTheme === 'dark' ? '🌙' : '☀️';
684
+ } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
685
+ document.documentElement.classList.remove('dark');
686
+ document.documentElement.classList.add('light');
687
+ document.querySelector('.theme-toggle').textContent = '☀️';
688
+ localStorage.setItem('theme', 'light');
689
+ }
690
+
691
+ if ('serviceWorker' in navigator) {
692
+ navigator.serviceWorker.register('/static/js/sw.js')
693
+ .then(reg => console.log('✅ Service Worker Registered', reg))
694
+ .catch(err => console.error('❌ Service Worker registration failed', err));
695
+ }
696
+
697
+ let deferredPrompt;
698
+ window.addEventListener('beforeinstallprompt', (e) => {
699
+ e.preventDefault();
700
+ deferredPrompt = e;
701
+ const installBtn = document.getElementById('installAppBtn');
702
+ if (installBtn) {
703
+ installBtn.style.display = 'block';
704
+ installBtn.addEventListener('click', () => {
705
+ deferredPrompt.prompt();
706
+ deferredPrompt.userChoice.then(choice => {
707
+ console.log(choice.outcome === 'accepted' ? '✅ User accepted the install prompt' : '❌ User dismissed the install prompt');
708
+ deferredPrompt = null;
709
+ });
710
+ });
711
  }
 
 
712
  });
713
+ </script>
 
 
 
 
 
 
 
 
 
 
 
 
714
  </body>
715
  </html>
templates/login.html CHANGED
@@ -1,412 +1,629 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
-
4
  <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <meta name="description"
8
- content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign in with email, Google, or GitHub.">
9
- <meta name="keywords" content="MGZon Chatbot, login, AI assistant, code generation, e-commerce, Mark Al-Asfar">
10
- <meta name="author" content="Mark Al-Asfar">
11
- <meta name="robots" content="index, follow">
12
- <title>Login - MGZon Chatbot</title>
13
- <!-- manifest for Android/Chrome -->
14
- <link rel="manifest" href="/static/manifest.json">
15
- <!-- iOS Web App Support -->
16
- <link rel="apple-touch-icon" sizes="180x180" href="/static/images/mg.svg">
17
- <meta name="apple-mobile-web-app-capable" content="yes">
18
- <meta name="apple-mobile-web-app-title" content="MGZon">
19
- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
20
- <!-- General Theme -->
21
- <meta name="theme-color" content="#2d3748">
22
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
23
- <!-- Open Graph -->
24
- <meta property="og:title" content="Login - MGZon Chatbot">
25
- <meta property="og:description"
26
- content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
27
- <meta property="og:image" content="/static/images/mg.svg">
28
- <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/login">
29
- <meta property="og:type" content="website">
30
- <!-- Twitter Card -->
31
- <meta name="twitter:card" content="summary_large_image">
32
- <meta name="twitter:title" content="Login - MGZon Chatbot">
33
- <meta name="twitter:description"
34
- content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
35
- <meta name="twitter:image" content="/static/images/mg.svg">
36
- <!-- JSON-LD -->
37
- <script type="application/ld+json">
38
- {
39
- "@context": "https://schema.org",
40
- "@type": "WebPage",
41
- "name": "Login - MGZon Chatbot",
42
- "url": "https://mgzon-mgzon-app.hf.space/login",
43
- "description": "Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign in with email, Google, or GitHub.",
44
- "keywords": ["MGZon Chatbot", "login", "AI chatbot", "code generation", "e-commerce", "Mark Al-Asfar", "MGZon", "MGZon AI", "E-commerce chatbot", "Python AI chatbot", "FastAPI integration"],
45
- "isPartOf": {
46
- "@type": "WebSite",
47
- "name": "MGZon Chatbot",
48
- "url": "https://mgzon-mgzon-app.hf.space/"
49
- }
50
- }
51
- </script>
52
- <!-- Tailwind (v3) -->
53
- <script src="https://cdn.tailwindcss.com"></script>
54
- <!-- Boxicons -->
55
- <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
56
- <style>
57
- @keyframes gradientShift {
58
- 0% {
59
- background-position: 0% 50%;
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- 50% {
63
- background-position: 100% 50%;
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- 100% {
67
- background-position: 0% 50%;
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- body {
72
- background: linear-gradient(135deg, #0f172a, #0e7490, #065f46, #064e3b);
73
- background-size: 400% 400%;
74
- animation: gradientShift 15s ease infinite;
75
- font-family: system-ui, sans-serif;
76
- }
77
 
78
- .glass {
79
- background: rgba(255, 255, 255, 0.07);
80
- border-radius: 1rem;
81
- border: 1px solid rgba(255, 255, 255, 0.12);
82
- backdrop-filter: blur(12px);
83
- -webkit-backdrop-filter: blur(12px);
84
- }
 
 
85
 
86
- .loading {
87
- display: inline-block;
88
- width: 1rem;
89
- height: 1rem;
90
- border: 2px solid currentColor;
91
- border-top-color: transparent;
92
- border-radius: 50%;
93
- animation: spin 0.8s linear infinite;
94
- margin-left: 0.5rem;
95
- }
96
 
97
- @keyframes spin {
98
- to {
99
- transform: rotate(360deg);
100
- }
101
- }
102
 
103
- .glass:hover {
104
- transform: scale(1.05);
105
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
106
- background: rgba(255, 255, 255, 0.15);
107
- }
108
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  </head>
 
 
110
 
111
- <body class="text-white min-h-screen flex flex-col justify-center items-center">
112
- <div class="container max-w-md mx-auto text-center py-12">
113
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6 animate-bounce">
114
- <h1 class="text-4xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-300 to-emerald-400">
115
- Login to MGZon Chatbot
116
- </h1>
117
- <div class="glass p-8">
118
- <form id="loginForm" action="/auth/jwt/login" method="POST" class="flex flex-col gap-4">
119
- <input type="email" name="username" id="email" placeholder="Email"
120
- class="p-3 rounded-lg bg-gray-800/60 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500"
121
- required>
122
- <input type="password" name="password" id="password" placeholder="Password"
123
- class="p-3 rounded-lg bg-gray-800/60 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500"
124
- required>
125
- <button type="submit" id="loginBtn"
126
- class="bg-gradient-to-r from-emerald-500 to-teal-600 text-white px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
127
- Login <i class="bx bx-log-in ml-2"></i>
128
- <span id="spinner" class="loading hidden"></span>
129
- </button>
130
- </form>
131
- <div class="flex justify-center gap-4 mt-4 flex-wrap">
132
- <button id="googleLoginBtn"
133
- class="inline-flex items-center bg-gradient-to-r from-white to-gray-200 text-gray-800 px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
134
- Login with Google <i class="bx bxl-google ml-2"></i>
135
- </button>
136
- <button id="githubLoginBtn"
137
- class="inline-flex items-center bg-gradient-to-r from-gray-800 to-black text-white px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
138
- Login with GitHub <i class="bx bxl-github ml-2"></i>
139
- </button>
140
- </div>
141
- <p class="mt-4">Don't have an account? <a href="/register" class="text-emerald-300 hover:underline">Register</a>
142
- </p>
143
- <p id="errorMsg" class="text-red-500 mt-4 hidden"></p>
144
- </div>
145
- </div>
146
- <footer class="bg-gradient-to-r from-teal-900 to-emerald-900 py-12 mt-8 w-full">
147
- <div class="container max-w-6xl mx-auto text-center">
148
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6 animate-pulse">
149
- <p class="mb-4">
150
- Developed by <a href="https://mark-elasfar.web.app/" target="_blank"
151
- class="text-emerald-300 hover:underline">Mark Al-Asfar</a>
152
- | Powered by <a href="https://hager-zon.vercel.app/" target="_blank"
153
- class="text-emerald-300 hover:underline">MGZon AI</a>
154
- </p>
155
- <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
156
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('email')">
157
- <i class="bx bx-mail-send text-3xl text-emerald-300 mb-2"></i>
158
- <h4 class="font-semibold mb-1">Email Us</h4>
159
- <p><a href="mailto:support@mgzon.com" class="text-emerald-300 hover:underline">support@mgzon.com</a></p>
160
- <div id="email-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
161
- <p>Reach out to our support team for any inquiries or assistance.</p>
162
- <button onclick="closeCardDetails('email')"
163
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
164
- </div>
165
- </div>
166
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
167
- <i class="bx bx-phone text-3xl text-emerald-300 mb-2"></i>
168
- <h4 class="font-semibold mb-1">Phone Support</h4>
169
- <p>+1-800-123-4567</p>
170
- <div id="phone-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
171
- <p>Contact our support team via phone for immediate assistance.</p>
172
- <button onclick="closeCardDetails('phone')"
173
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
174
- </div>
175
- </div>
176
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('community')">
177
- <i class="bx bx-group text-3xl text-emerald-300 mb-2"></i>
178
- <h4 class="font-semibold mb-1">Community</h4>
179
- <p><a href="https://hager-zon.vercel.app/community" class="text-emerald-300 hover:underline">Join us</a></p>
180
- <div id="community-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
181
- <p>Join our vibrant community to share ideas and collaborate.</p>
182
- <button onclick="closeCardDetails('community')"
183
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
184
- </div>
185
- </div>
186
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
187
- <i class="bx bx-code-alt text-3xl text-emerald-300 mb-2"></i>
188
- <h4 class="font-semibold mb-1">API Docs</h4>
189
- <p><a href="/docs" class="text-emerald-300 hover:underline">Explore Docs</a></p>
190
- <div id="api-docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
191
- <p>Explore our API documentation for seamless integration.</p>
192
- <button onclick="closeCardDetails('api-docs')"
193
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
194
- </div>
195
- </div>
196
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
197
- <i class="bx bx-help-circle text-3xl text-emerald-300 mb-2"></i>
198
- <h4 class="font-semibold mb-1">FAQ</h4>
199
- <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-emerald-300 hover:underline">Read
200
- FAQ</a></p>
201
- <div id="faq-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
202
- <p>Find answers to common questions in our FAQ section.</p>
203
- <button onclick="closeCardDetails('faq')"
204
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
205
- </div>
206
- </div>
207
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
208
- <i class="bx bx-book text-3xl text-emerald-300 mb-2"></i>
209
- <h4 class="font-semibold mb-1">Documentation</h4>
210
- <p><a href="/docs" class="text-emerald-300 hover:underline">Full Docs</a></p>
211
- <div id="docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
212
- <p>Access comprehensive documentation for MGZon Chatbot.</p>
213
- <button onclick="closeCardDetails('docs')"
214
- class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
215
- </div>
216
  </div>
217
- </div>
218
- <div class="flex justify-center gap-6 mt-6">
219
- <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i
220
- class="bx bxl-github"></i></a>
221
- <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i
222
- class="bx bxl-twitter"></i></a>
223
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/"
224
- class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-facebook"></i></a>
225
- </div>
226
- <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
227
  </div>
228
- <button id="installAppBtn" style="display: none;"
229
- class="fixed bottom-4 right-4 bg-blue-600 text-white px-4 py-2 rounded shadow-lg z-50">
230
- 📲 Install MG Chat
231
- </button>
232
- </footer>
233
-
234
- <script>
235
- console.log('Login page script loaded'); // Debugging: Ensure script is running
236
-
237
- const loginForm = document.getElementById('loginForm');
238
- const loginBtn = document.getElementById('loginBtn');
239
- const spinner = document.getElementById('spinner');
240
- const errorMsg = document.getElementById('errorMsg');
241
- const googleLoginBtn = document.getElementById('googleLoginBtn');
242
- const githubLoginBtn = document.getElementById('githubLoginBtn');
243
-
244
- // Check authentication status on page load
245
- async function checkAuthStatus() {
246
- try {
247
- const response = await fetch('/api/check-auth', {
248
- method: 'GET',
249
- credentials: 'include',
250
- headers: { 'Accept': 'application/json' }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  });
252
- const data = await response.json();
253
- if (data.is_authenticated) {
254
- console.log('User is authenticated, redirecting to /chat');
255
- window.location.href = '/chat';
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
- } catch (error) {
258
- console.error('Error checking auth status:', error);
259
- }
260
- }
261
 
262
- // Handle email/password login
263
- loginForm.addEventListener('submit', async (e) => {
264
- e.preventDefault();
265
- console.log('Login form submitted'); // Debugging
266
- spinner.classList.remove('hidden');
267
- errorMsg.classList.add('hidden');
268
- const formData = new FormData(loginForm);
269
- try {
270
- const response = await fetch('/auth/jwt/login', {
271
- method: 'POST',
272
- body: formData
273
- });
274
- spinner.classList.add('hidden');
275
- if (response.ok) {
276
- console.log('Login successful, redirecting to /chat'); // Debugging
277
- window.location.href = '/chat';
278
- } else {
279
- const error = await response.json();
280
- errorMsg.textContent = error.detail || 'Login failed. Please try again.';
281
- errorMsg.classList.remove('hidden');
282
- console.error('Login failed:', error); // Debugging
283
  }
284
- } catch (error) {
285
- spinner.classList.add('hidden');
286
- errorMsg.textContent = 'An error occurred. Please try again.';
287
- errorMsg.classList.remove('hidden');
288
- console.error('Error during login:', error); // Debugging
289
- }
290
- });
291
-
292
- // Handle Google OAuth login
293
- googleLoginBtn.addEventListener('click', async (e) => {
294
- e.preventDefault();
295
- console.log('Google login button clicked');
296
- spinner.classList.remove('hidden');
297
- errorMsg.classList.add('hidden');
298
- try {
299
- const response = await fetch('https://mgzon-mgzon-app.hf.space/auth/google/authorize', {
300
- method: 'GET',
301
- headers: { 'Accept': 'application/json' }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  });
303
  if (!response.ok) {
304
- throw new Error(`HTTP error! Status: ${response.status}`);
305
  }
306
  const data = await response.json();
307
  if (data.authorization_url) {
308
- console.log('Redirecting to Google:', data.authorization_url);
309
- window.location.href = data.authorization_url;
310
  } else {
311
- throw new Error('No authorization URL received');
312
  }
313
- } catch (error) {
314
  spinner.classList.add('hidden');
315
  errorMsg.textContent = 'Failed to initiate Google login. Please try again.';
316
  errorMsg.classList.remove('hidden');
317
  console.error('Error initiating Google login:', error);
318
- }
319
- });
320
-
321
- // Handle GitHub OAuth login
322
- githubLoginBtn.addEventListener('click', async (e) => {
323
- e.preventDefault();
324
- console.log('GitHub login button clicked');
325
- spinner.classList.remove('hidden');
326
- errorMsg.classList.add('hidden');
327
- try {
328
- const response = await fetch('https://mgzon-mgzon-app.hf.space/auth/github/authorize', {
329
- method: 'GET',
330
- headers: { 'Accept': 'application/json' }
331
  });
332
  if (!response.ok) {
333
- throw new Error(`HTTP error! Status: ${response.status}`);
334
  }
335
  const data = await response.json();
336
  if (data.authorization_url) {
337
- console.log('Redirecting to GitHub:', data.authorization_url);
338
- window.location.href = data.authorization_url;
339
  } else {
340
- throw new Error('No authorization URL received');
341
  }
342
- } catch (error) {
343
  spinner.classList.add('hidden');
344
  errorMsg.textContent = 'Failed to initiate GitHub login. Please try again.';
345
  errorMsg.classList.remove('hidden');
346
  console.error('Error initiating GitHub login:', error);
347
- }
348
- });
349
-
350
- // Check for error query parameters on page load (for OAuth errors)
351
- window.addEventListener('load', () => {
352
- console.log('Page loaded, checking for OAuth callback');
353
- const urlParams = new URLSearchParams(window.location.search);
354
- const error = urlParams.get('error');
355
- if (error) {
356
- errorMsg.textContent = decodeURIComponent(error);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  errorMsg.classList.remove('hidden');
358
- console.error('OAuth error from URL:', error);
359
- } else if (urlParams.get('code')) {
360
- // If there's a 'code' parameter, it means OAuth login was successful
361
- console.log('OAuth login successful, redirecting to /chat');
362
- window.location.href = '/chat';
363
  }
364
- });
365
-
366
- // Handle card details toggle
367
- function showCardDetails(cardId) {
368
- console.log('Showing card details:', cardId); // Debugging
369
- document.getElementById(`${cardId}-details`).classList.remove('hidden');
370
  }
 
 
371
 
372
- function closeCardDetails(cardId) {
373
- console.log('Closing card details:', cardId); // Debugging
374
- document.getElementById(`${cardId}-details`).classList.add('hidden');
375
- }
 
376
 
377
- // Service Worker for PWA
378
- if ('serviceWorker' in navigator) {
379
- console.log('Registering service worker'); // Debugging
380
- navigator.serviceWorker.register('/static/js/sw.js')
381
- .then(reg => console.log('✅ Service Worker Registered', reg))
382
- .catch(err => console.error('❌ Service Worker registration failed', err));
383
- }
384
 
385
- // Handle PWA install prompt
386
- let deferredPrompt;
387
- window.addEventListener('beforeinstallprompt', (e) => {
388
- console.log('Before install prompt triggered'); // Debugging
389
- e.preventDefault();
390
- deferredPrompt = e;
391
- const installBtn = document.getElementById('installAppBtn');
392
- if (installBtn) {
393
- installBtn.style.display = 'block';
394
- installBtn.addEventListener('click', () => {
395
- console.log('Install button clicked'); // Debugging
396
- deferredPrompt.prompt();
397
- deferredPrompt.userChoice.then(choice => {
398
- if (choice.outcome === 'accepted') {
399
- console.log('✅ User accepted the install prompt');
400
- } else {
401
- console.log('❌ User dismissed the install prompt');
 
 
 
 
 
 
 
 
 
 
 
 
402
  }
403
- deferredPrompt = null;
404
- });
405
  });
406
- }
407
- });
408
- </script>
409
-
410
  </body>
411
-
412
- </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en" class="dark">
 
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="description" content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign in with email, Google, or GitHub.">
7
+ <meta name="keywords" content="MGZon Chatbot, login, AI assistant, code generation, e-commerce, Mark Al-Asfar">
8
+ <meta name="author" content="Mark Al-Asfar">
9
+ <meta name="robots" content="index, follow">
10
+ <title>Login - MGZon Chatbot</title>
11
+ <link rel="manifest" href="/static/manifest.json">
12
+ <link rel="apple-touch-icon" sizes="180x180" href="/static/images/mg.svg">
13
+ <meta name="apple-mobile-web-app-capable" content="yes">
14
+ <meta name="apple-mobile-web-app-title" content="MGZon">
15
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
16
+ <meta name="theme-color" content="#00f0ff">
17
+ <meta property="og:title" content="Login - MGZon Chatbot">
18
+ <meta property="og:description" content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
19
+ <meta property="og:image" content="/static/images/mg.svg">
20
+ <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/login">
21
+ <meta property="og:type" content="website">
22
+ <meta name="twitter:card" content="summary_large_image">
23
+ <meta name="twitter:title" content="Login - MGZon Chatbot">
24
+ <meta name="twitter:description" content="Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
25
+ <meta name="twitter:image" content="/static/images/mg.svg">
26
+ <script type="application/ld+json">
27
+ {
28
+ "@context": "https://schema.org",
29
+ "@type": "WebPage",
30
+ "name": "Login - MGZon Chatbot",
31
+ "url": "https://mgzon-mgzon-app.hf.space/login",
32
+ "description": "Login to MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign in with email, Google, or GitHub.",
33
+ "keywords": ["MGZon Chatbot", "login", "AI chatbot", "code generation", "e-commerce", "Mark Al-Asfar", "MGZon", "MGZon AI", "E-commerce chatbot", "Python AI chatbot", "FastAPI integration"],
34
+ "isPartOf": {
35
+ "@type": "WebSite",
36
+ "name": "MGZon Chatbot",
37
+ "url": "https://mgzon-mgzon-app.hf.space/"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
+ }
40
+ </script>
41
+ <script src="https://cdn.tailwindcss.com"></script>
42
+ <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
43
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
44
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/particles.js/2.0.0/particles.min.js"></script>
45
+ <style>
46
+ :root {
47
+ --font-sans: 'Poppins', sans-serif;
48
+ --font-mono: 'Orbitron', monospace;
49
+ --radius: 1rem;
50
+ }
51
 
52
+ :root.dark {
53
+ --background: 220 70% 10%;
54
+ --foreground: 0 0% 95%;
55
+ --card: 220 70% 15%;
56
+ --card-foreground: 0 0% 90%;
57
+ --primary: 180 100% 50%;
58
+ --primary-foreground: 0 0% 0%;
59
+ --secondary: 260 80% 30%;
60
+ --secondary-foreground: 0 0% 95%;
61
+ --muted: 220 50% 20%;
62
+ --muted-foreground: 0 0% 70%;
63
+ --accent: 320 100% 60%;
64
+ --accent-foreground: 0 0% 95%;
65
+ --border: 220 50% 25%;
66
+ }
67
 
68
+ :root.light {
69
+ --background: 0 0% 100%;
70
+ --foreground: 220 70% 10%;
71
+ --card: 0 0% 95%;
72
+ --card-foreground: 220 70% 15%;
73
+ --primary: 180 100% 50%;
74
+ --primary-foreground: 0 0% 100%;
75
+ --secondary: 260 80% 40%;
76
+ --secondary-foreground: 0 0% 10%;
77
+ --muted: 0 0% 90%;
78
+ --muted-foreground: 0 0% 40%;
79
+ --accent: 320 100% 50%;
80
+ --accent-foreground: 0 0% 10%;
81
+ --border: 0 0% 80%;
82
+ }
83
 
84
+ * {
85
+ margin: 0;
86
+ padding: 0;
87
+ box-sizing: border-box;
88
+ }
 
89
 
90
+ body {
91
+ font-family: var(--font-sans);
92
+ background: hsl(var(--background));
93
+ color: hsl(var(--foreground));
94
+ line-height: 1.6;
95
+ min-height: 100vh;
96
+ position: relative;
97
+ overflow-x: hidden;
98
+ }
99
 
100
+ #particles-js {
101
+ position: fixed;
102
+ top: 0;
103
+ left: 0;
104
+ width: 100%;
105
+ height: 100%;
106
+ z-index: -1;
107
+ }
 
 
108
 
109
+ .container {
110
+ max-width: 1280px;
111
+ margin: 0 auto;
112
+ padding: 0 2rem;
113
+ }
114
 
115
+ .glass {
116
+ background: rgba(255, 255, 255, 0.07);
117
+ border-radius: var(--radius);
118
+ border: 1px solid rgba(255, 255, 255, 0.12);
119
+ backdrop-filter: blur(12px);
120
+ -webkit-backdrop-filter: blur(12px);
121
+ transition: all 0.3s ease;
122
+ }
123
+
124
+ .glass:hover {
125
+ transform: scale(1.05);
126
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
127
+ background: rgba(255, 255, 255, 0.15);
128
+ }
129
+
130
+ .login-button {
131
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
132
+ color: hsl(var(--primary-foreground));
133
+ border: none;
134
+ padding: 1rem 2rem;
135
+ border-radius: var(--radius);
136
+ font-family: var(--font-mono);
137
+ font-weight: 600;
138
+ transition: all 0.3s ease;
139
+ position: relative;
140
+ overflow: hidden;
141
+ }
142
+
143
+ .login-button:hover {
144
+ transform: translateY(-5px) scale(1.05);
145
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
146
+ }
147
+
148
+ .login-button::before {
149
+ content: '';
150
+ position: absolute;
151
+ top: 0;
152
+ left: -100%;
153
+ width: 100%;
154
+ height: 100%;
155
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
156
+ transition: left 0.5s;
157
+ }
158
+
159
+ .login-button:hover::before {
160
+ left: 100%;
161
+ }
162
+
163
+ .input-field {
164
+ background: hsl(var(--muted));
165
+ border: 1px solid hsl(var(--border));
166
+ color: hsl(var(--foreground));
167
+ padding: 0.75rem;
168
+ border-radius: var(--radius);
169
+ font-family: var(--font-sans);
170
+ transition: all 0.3s ease;
171
+ }
172
+
173
+ .input-field:focus {
174
+ outline: none;
175
+ border-color: hsl(var(--primary));
176
+ box-shadow: 0 0 10px hsl(var(--primary) / 0.5);
177
+ }
178
+
179
+ .theme-toggle {
180
+ position: fixed;
181
+ top: 2rem;
182
+ right: 2rem;
183
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
184
+ border: 1px solid hsl(var(--border));
185
+ color: hsl(var(--card-foreground));
186
+ padding: 1rem;
187
+ border-radius: var(--radius);
188
+ cursor: pointer;
189
+ font-size: 1.5rem;
190
+ transition: all 0.3s ease;
191
+ z-index: 1000;
192
+ }
193
+
194
+ .theme-toggle:hover {
195
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
196
+ transform: scale(1.2) rotate(360deg);
197
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
198
+ }
199
+
200
+ .error-message {
201
+ background: hsl(var(--muted));
202
+ border-left: 5px solid hsl(var(--accent));
203
+ padding: 1rem;
204
+ border-radius: var(--radius);
205
+ color: hsl(var(--accent-foreground));
206
+ }
207
+
208
+ .footer-card {
209
+ transition: all 0.3s ease;
210
+ box-shadow: 0 5px 15px hsl(var(--foreground) / 0.2);
211
+ }
212
+
213
+ .footer-card:hover {
214
+ transform: translateY(-10px) scale(1.05);
215
+ box-shadow: 0 15px 30px hsl(var(--primary) / 0.4);
216
+ }
217
+
218
+ .footer-card-icon {
219
+ transition: transform 0.3s ease;
220
+ }
221
+
222
+ .footer-card:hover .footer-card-icon {
223
+ transform: scale(1.2) rotate(5deg);
224
+ }
225
+
226
+ .wave-divider {
227
+ height: 120px;
228
+ background: transparent;
229
+ position: relative;
230
+ overflow: hidden;
231
+ }
232
+
233
+ .wave-divider::before {
234
+ content: '';
235
+ position: absolute;
236
+ bottom: 0;
237
+ left: 0;
238
+ width: 200%;
239
+ height: 100%;
240
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--background)));
241
+ border-radius: 50%;
242
+ animation: wave 10s ease-in-out infinite;
243
+ }
244
+
245
+ @keyframes wave {
246
+ 0%, 100% { transform: translateX(-50%) translateY(70%); }
247
+ 50% { transform: translateX(-50%) translateY(50%); }
248
+ }
249
+
250
+ @keyframes fadeIn {
251
+ from { opacity: 0; transform: translateY(40px); }
252
+ to { opacity: 1; transform: translateY(0); }
253
+ }
254
+
255
+ .footer {
256
+ text-align: center; /* Ensure footer content is centered */
257
+ }
258
+
259
+ .footer p {
260
+ margin-left: auto;
261
+ margin-right: auto;
262
+ }
263
+
264
+ @media (max-width: 768px) {
265
+ .container {
266
+ padding: 0 1.5rem;
267
+ }
268
+ }
269
+ </style>
270
  </head>
271
+ <body>
272
+ <div id="particles-js"></div>
273
 
274
+ <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
275
+
276
+ <div class="container flex flex-col justify-center items-center min-h-screen">
277
+ <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-32 h-32 mx-auto mb-6" style="animation: fadeIn 1s ease-out;">
278
+ <h1 class="text-4xl font-bold mb-4 font-[var(--font-mono)] bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] bg-clip-text text-transparent" style="animation: fadeIn 1s ease-out 0.3s both;">
279
+ Login to MGZon Chatbot
280
+ </h1>
281
+ <div class="glass p-8 max-w-md w-full" style="animation: fadeIn 1s ease-out 0.6s both;">
282
+ <form id="loginForm" action="/auth/jwt/login" method="POST" class="flex flex-col gap-4">
283
+ <input type="email" name="username" id="email" placeholder="Email" class="input-field" required>
284
+ <input type="password" name="password" id="password" placeholder="Password" class="input-field" required>
285
+ <button type="submit" id="loginBtn" class="login-button">
286
+ Login <i class="bx bx-log-in ml-2"></i>
287
+ <span id="spinner" class="loading hidden"></span>
288
+ </button>
289
+ </form>
290
+ <div class="flex justify-center gap-4 mt-4 flex-wrap">
291
+ <button id="googleLoginBtn" class="login-button inline-flex items-center">
292
+ Login with Google <i class="bx bxl-google ml-2"></i>
293
+ </button>
294
+ <button id="githubLoginBtn" class="login-button inline-flex items-center">
295
+ Login with GitHub <i class="bx bxl-github ml-2"></i>
296
+ </button>
297
+ </div>
298
+ <p class="mt-4 text-center">
299
+ Don't have an account? <a href="/register" class="text-[hsl(var(--primary))] hover:underline">Register</a>
300
+ </p>
301
+ <p id="errorMsg" class="error-message mt-4 hidden"></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  </div>
 
 
 
 
 
 
 
 
 
 
303
  </div>
304
+
305
+ <div class="wave-divider"></div>
306
+
307
+ <footer class="footer py-12">
308
+ <div class="container">
309
+ <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6" style="animation: fadeIn 1s ease-out;">
310
+ <p class="mb-4 text-center">
311
+ Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-[hsl(var(--primary))] hover:underline">Mark Al-Asfar</a>
312
+ | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-[hsl(var(--primary))] hover:underline">MGZon AI</a>
313
+ </p>
314
+ <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
315
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('email')">
316
+ <i class="bx bx-mail-send text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
317
+ <h4 class="font-semibold mb-1">Email Us</h4>
318
+ <p><a href="mailto:support@mgzon.com" class="text-[hsl(var(--primary))] hover:underline">support@mgzon.com</a></p>
319
+ <div id="email-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
320
+ <p>Reach out to our support team for any inquiries or assistance.</p>
321
+ <button onclick="closeCardDetails('email')" class="login-button mt-2">Close</button>
322
+ </div>
323
+ </div>
324
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
325
+ <i class="bx bx-phone text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
326
+ <h4 class="font-semibold mb-1">Phone Support</h4>
327
+ <p>+20 1212444617</p>
328
+ <div id="phone-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
329
+ <p>Contact our support team via phone for immediate assistance.</p>
330
+ <button onclick="closeCardDetails('phone')" class="login-button mt-2">Close</button>
331
+ </div>
332
+ </div>
333
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('community')">
334
+ <i class="bx bx-group text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
335
+ <h4 class="font-semibold mb-1">Community</h4>
336
+ <p><a href="https://hager-zon.vercel.app/community" class="text-[hsl(var(--primary))] hover:underline">Join us</a></p>
337
+ <div id="community-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
338
+ <p>Join our vibrant community to share ideas and collaborate.</p>
339
+ <button onclick="closeCardDetails('community')" class="login-button mt-2">Close</button>
340
+ </div>
341
+ </div>
342
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
343
+ <i class="bx bx-code-alt text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
344
+ <h4 class="font-semibold mb-1">API Docs</h4>
345
+ <p><a href="/docs" class="text-[hsl(var(--primary))] hover:underline">Explore Docs</a></p>
346
+ <div id="api-docs-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
347
+ <p>Explore our API documentation for seamless integration.</p>
348
+ <button onclick="closeCardDetails('api-docs')" class="login-button mt-2">Close</button>
349
+ </div>
350
+ </div>
351
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
352
+ <i class="bx bx-help-circle text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
353
+ <h4 class="font-semibold mb-1">FAQ</h4>
354
+ <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-[hsl(var(--primary))] hover:underline">Read FAQ</a></p>
355
+ <div id="faq-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
356
+ <p>Find answers to common questions in our FAQ section.</p>
357
+ <button onclick="closeCardDetails('faq')" class="login-button mt-2">Close</button>
358
+ </div>
359
+ </div>
360
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
361
+ <i class="bx bx-book text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
362
+ <h4 class="font-semibold mb-1">Documentation</h4>
363
+ <p><a href="/docs" class="text-[hsl(var(--primary))] hover:underline">Full Docs</a></p>
364
+ <div id="docs-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
365
+ <p>Access comprehensive documentation for MGZon Chatbot.</p>
366
+ <button onclick="closeCardDetails('docs')" class="login-button mt-2">Close</button>
367
+ </div>
368
+ </div>
369
+ </div>
370
+ <div class="flex justify-center gap-6 mt-6">
371
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-github"></i></a>
372
+ <a href="https://x.com/MGZon" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-twitter"></i></a>
373
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-facebook"></i></a>
374
+ </div>
375
+ <p class="mt-6 text-center">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
376
+ </div>
377
+ <button id="installAppBtn" style="display: none;" class="fixed bottom-4 right-4 bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] text-[hsl(var(--primary-foreground))] px-6 py-3 rounded-full shadow-lg z-50">
378
+ 📲 Install MG Chat
379
+ </button>
380
+ </footer>
381
+
382
+ <script>
383
+ // Particles.js initialization
384
+ particlesJS('particles-js', {
385
+ particles: {
386
+ number: { value: 80, density: { enable: true, value_area: 800 } },
387
+ color: { value: ['#00f0ff', '#ff007a', '#6b21a8'] },
388
+ shape: { type: 'circle' },
389
+ opacity: { value: 0.5, random: true },
390
+ size: { value: 3, random: true },
391
+ line_linked: { enable: true, distance: 150, color: '#00f0ff', opacity: 0.4, width: 1 },
392
+ move: { enable: true, speed: 3, direction: 'none', random: true }
393
+ },
394
+ interactivity: {
395
+ detect_on: 'canvas',
396
+ events: { onhover: { enable: true, mode: 'repulse' }, onclick: { enable: true, mode: 'push' } },
397
+ modes: { repulse: { distance: 100 }, push: { particles_nb: 4 } }
398
+ },
399
+ retina_detect: true
400
  });
401
+
402
+ function toggleTheme() {
403
+ const html = document.documentElement;
404
+ const button = document.querySelector('.theme-toggle');
405
+ if (html.classList.contains('dark')) {
406
+ html.classList.remove('dark');
407
+ html.classList.add('light');
408
+ button.textContent = '☀️';
409
+ localStorage.setItem('theme', 'light');
410
+ } else {
411
+ html.classList.remove('light');
412
+ html.classList.add('dark');
413
+ button.textContent = '🌙';
414
+ localStorage.setItem('theme', 'dark');
415
+ }
416
  }
 
 
 
 
417
 
418
+ // Load saved theme preference or system preference
419
+ const savedTheme = localStorage.getItem('theme');
420
+ if (savedTheme) {
421
+ document.documentElement.classList.remove('dark', 'light');
422
+ document.documentElement.classList.add(savedTheme);
423
+ document.querySelector('.theme-toggle').textContent = savedTheme === 'dark' ? '🌙' : '☀️';
424
+ } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
425
+ document.documentElement.classList.remove('dark');
426
+ document.documentElement.classList.add('light');
427
+ document.querySelector('.theme-toggle').textContent = '☀️';
428
+ localStorage.setItem('theme', 'light');
 
 
 
 
 
 
 
 
 
 
429
  }
430
+
431
+ // Check authentication status on page load
432
+ async function checkAuthStatus() {
433
+ try {
434
+ const response = await fetch('/api/check-auth', {
435
+ method: 'GET',
436
+ credentials: 'include',
437
+ headers: { 'Accept': 'application/json' }
438
+ });
439
+ const data = await response.json();
440
+ if (data.is_authenticated) {
441
+ console.log('User is authenticated, redirecting to /chat');
442
+ window.location.href = '/chat';
443
+ }
444
+ } catch (error) {
445
+ console.error('Error checking auth status:', error);
446
+ }
447
+ }
448
+
449
+ // Handle email/password login
450
+ const loginForm = document.getElementById('loginForm');
451
+ const loginBtn = document.getElementById('loginBtn');
452
+ const spinner = document.getElementById('spinner');
453
+ const errorMsg = document.getElementById('errorMsg');
454
+ const googleLoginBtn = document.getElementById('googleLoginBtn');
455
+ const githubLoginBtn = document.getElementById('githubLoginBtn');
456
+
457
+ loginForm.addEventListener('submit', async (e) => {
458
+ e.preventDefault();
459
+ console.log('Login form submitted');
460
+ spinner.classList.remove('hidden');
461
+ errorMsg.classList.add('hidden');
462
+ const formData = new FormData(loginForm);
463
+ try {
464
+ const response = await fetch('/auth/jwt/login', {
465
+ method: 'POST',
466
+ body: formData
467
+ });
468
+ spinner.classList.add('hidden');
469
+ if (response.ok) {
470
+ console.log('Login successful, redirecting to /chat');
471
+ window.location.href = '/chat';
472
+ } else {
473
+ const error = await response.json();
474
+ errorMsg.textContent = error.detail || 'Login failed. Please try again.';
475
+ errorMsg.classList.remove('hidden');
476
+ console.error('Login failed:', error);
477
+ }
478
+ } catch (error) {
479
+ spinner.classList.add('hidden');
480
+ errorMsg.textContent = 'An error occurred. Please try again.';
481
+ errorMsg.classList.remove('hidden');
482
+ console.error('Error during login:', error);
483
+ }
484
+ });
485
+
486
+ // Handle Google OAuth login
487
+ googleLoginBtn.addEventListener('click', async (e) => {
488
+ e.preventDefault();
489
+ console.log('Google login button clicked');
490
+ spinner.classList.remove('hidden');
491
+ errorMsg.classList.add('hidden');
492
+ try {
493
+ const response = await fetch('/auth/google/authorize', {
494
+ method: 'GET',
495
+ headers: { 'Accept': 'application/json' }
496
  });
497
  if (!response.ok) {
498
+ throw new Error(`HTTP error! Status: ${response.status}`);
499
  }
500
  const data = await response.json();
501
  if (data.authorization_url) {
502
+ console.log('Redirecting to Google:', data.authorization_url);
503
+ window.location.href = data.authorization_url;
504
  } else {
505
+ throw new Error('No authorization URL received');
506
  }
507
+ } catch (error) {
508
  spinner.classList.add('hidden');
509
  errorMsg.textContent = 'Failed to initiate Google login. Please try again.';
510
  errorMsg.classList.remove('hidden');
511
  console.error('Error initiating Google login:', error);
512
+ }
513
+ });
514
+
515
+ // Handle GitHub OAuth login
516
+ githubLoginBtn.addEventListener('click', async (e) => {
517
+ e.preventDefault();
518
+ console.log('GitHub login button clicked');
519
+ spinner.classList.remove('hidden');
520
+ errorMsg.classList.add('hidden');
521
+ try {
522
+ const response = await fetch('/auth/github/authorize', {
523
+ method: 'GET',
524
+ headers: { 'Accept': 'application/json' }
525
  });
526
  if (!response.ok) {
527
+ throw new Error(`HTTP error! Status: ${response.status}`);
528
  }
529
  const data = await response.json();
530
  if (data.authorization_url) {
531
+ console.log('Redirecting to GitHub:', data.authorization_url);
532
+ window.location.href = data.authorization_url;
533
  } else {
534
+ throw new Error('No authorization URL received');
535
  }
536
+ } catch (error) {
537
  spinner.classList.add('hidden');
538
  errorMsg.textContent = 'Failed to initiate GitHub login. Please try again.';
539
  errorMsg.classList.remove('hidden');
540
  console.error('Error initiating GitHub login:', error);
541
+ }
542
+ });
543
+
544
+ // Check for OAuth callback on load (for web)
545
+ window.addEventListener('load', async () => {
546
+ const urlParams = new URLSearchParams(window.location.search);
547
+ const code = urlParams.get('code');
548
+ const error = urlParams.get('error');
549
+ if (error) {
550
+ errorMsg.textContent = decodeURIComponent(error);
551
+ errorMsg.classList.remove('hidden');
552
+ console.error('OAuth error from URL:', error);
553
+ } else if (code) {
554
+ console.log('OAuth code detected in URL, processing callback');
555
+ const provider = window.location.pathname.includes('google') ? 'google' : 'github';
556
+ const callbackEndpoint = `/auth/${provider}/callback?code=${code}`;
557
+ try {
558
+ const response = await fetch(callbackEndpoint, {
559
+ method: 'GET',
560
+ headers: { 'Accept': 'application/json' }
561
+ });
562
+ if (response.ok) {
563
+ const data = await response.json();
564
+ if (data.access_token) {
565
+ localStorage.setItem('token', data.access_token); // Store token in localStorage for web
566
+ console.log(`${provider} login successful, token saved`);
567
+ window.location.href = '/chat'; // Redirect to server's /chat
568
+ } else {
569
+ throw new Error('No access token received');
570
+ }
571
+ } else {
572
+ const errorData = await response.json();
573
+ errorMsg.textContent = errorData.detail || `Failed to complete ${provider} login`;
574
  errorMsg.classList.remove('hidden');
575
+ console.error(`Failed to complete ${provider} login:`, errorData);
 
 
 
 
576
  }
577
+ } catch (error) {
578
+ errorMsg.textContent = `Failed to process ${provider} login. Please try again.`;
579
+ errorMsg.classList.remove('hidden');
580
+ console.error(`Error processing ${provider} callback:`, error);
 
 
581
  }
582
+ }
583
+ });
584
 
585
+ // Handle card details toggle
586
+ function showCardDetails(cardId) {
587
+ console.log('Showing card details:', cardId);
588
+ document.getElementById(`${cardId}-details`).classList.remove('hidden');
589
+ }
590
 
591
+ function closeCardDetails(cardId) {
592
+ console.log('Closing card details:', cardId);
593
+ document.getElementById(`${cardId}-details`).classList.add('hidden');
594
+ }
 
 
 
595
 
596
+ // Service Worker for PWA
597
+ if ('serviceWorker' in navigator) {
598
+ console.log('Registering service worker');
599
+ navigator.serviceWorker.register('/static/js/sw.js')
600
+ .then(reg => console.log('✅ Service Worker Registered', reg))
601
+ .catch(err => console.error('❌ Service Worker registration failed', err));
602
+ }
603
+
604
+ // Handle PWA install prompt
605
+ let deferredPrompt;
606
+ window.addEventListener('beforeinstallprompt', (e) => {
607
+ console.log('Before install prompt triggered');
608
+ e.preventDefault();
609
+ deferredPrompt = e;
610
+ const installBtn = document.getElementById('installAppBtn');
611
+ if (installBtn) {
612
+ installBtn.style.display = 'block';
613
+ installBtn.addEventListener('click', () => {
614
+ console.log('Install button clicked');
615
+ deferredPrompt.prompt();
616
+ deferredPrompt.userChoice.then(choice => {
617
+ if (choice.outcome === 'accepted') {
618
+ console.log('✅ User accepted the install prompt');
619
+ } else {
620
+ console.log('❌ User dismissed the install prompt');
621
+ }
622
+ deferredPrompt = null;
623
+ });
624
+ });
625
  }
 
 
626
  });
627
+ </script>
 
 
 
628
  </body>
629
+ </html>
 
templates/register.html CHANGED
@@ -1,222 +1,512 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign up with email, Google, or GitHub.">
7
- <meta name="keywords" content="MGZon Chatbot, register, sign up, AI assistant, code generation, e-commerce, Mark Al-Asfar">
8
- <meta name="author" content="Mark Al-Asfar">
9
- <meta name="robots" content="index, follow">
10
- <title>Register - MGZon Chatbot</title>
11
- <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
- <link rel="apple-touch-icon" href="/static/images/mg.svg">
13
- <!-- Open Graph -->
14
- <meta property="og:title" content="Register - MGZon Chatbot">
15
- <meta property="og:description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
16
- <meta property="og:image" content="/static/images/mg.svg">
17
- <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/register">
18
- <meta property="og:type" content="website">
19
- <!-- Twitter Card -->
20
- <meta name="twitter:card" content="summary_large_image">
21
- <meta name="twitter:title" content="Register - MGZon Chatbot">
22
- <meta name="twitter:description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
23
- <meta name="twitter:image" content="/static/images/mg.svg">
24
- <!-- JSON-LD -->
25
- <script type="application/ld+json">
26
- {
27
- "@context": "https://schema.org",
28
- "@type": "WebPage",
29
- "name": "Register - MGZon Chatbot",
30
- "url": "https://mgzon-mgzon-app.hf.space/register",
31
- "description": "Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign up with email, Google, or GitHub.",
32
- "keywords": ["MGZon Chatbot", "register", "sign up", "AI chatbot", "code generation", "e-commerce", "Mark Al-Asfar", "MGZon", "MGZon AI", "E-commerce chatbot", "Python AI chatbot", "FastAPI integration"],
33
- "isPartOf": {
34
- "@type": "WebSite",
35
- "name": "MGZon Chatbot",
36
- "url": "https://mgzon-mgzon-app.hf.space/"
37
- }
38
- }
39
- </script>
40
- @keyframes gradientShift {
41
- 0% { background-position: 0% 50%; }
42
- 50% { background-position: 100% 50%; }
43
- 100% { background-position: 0% 50%; }
44
- }
45
- body {
46
- background: linear-gradient(135deg, #0f172a, #0e7490, #065f46, #064e3b);
47
- background-size: 400% 400%;
48
- animation: gradientShift 15s ease infinite;
49
- font-family: system-ui, sans-serif;
50
- }
51
- .glass {
52
- background: rgba(255, 255, 255, 0.07);
53
- border-radius: 1rem;
54
- border: 1px solid rgba(255, 255, 255, 0.12);
55
- backdrop-filter: blur(12px);
56
- -webkit-backdrop-filter: blur(12px);
57
- }
58
- .loading {
59
- display: inline-block;
60
- width: 1rem;
61
- height: 1rem;
62
- border: 2px solid currentColor;
63
- border-top-color: transparent;
64
- border-radius: 50%;
65
- animation: spin 0.8s linear infinite;
66
- margin-left: 0.5rem;
67
- }
68
- @keyframes spin {
69
- to { transform: rotate(360deg); }
70
- }
71
- .glass:hover {
72
- transform: scale(1.05);
73
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
74
- background: rgba(255, 255, 255, 0.15);
75
  }
76
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </head>
78
- <body class="text-white min-h-screen flex flex-col justify-center items-center">
79
- <div class="container max-w-md mx-auto text-center py-12">
80
- <img src="/static/images/mg.svg" alt="MGZon Chatbot Logo by Mark Al-Asfar" class="w-32 h-32 mx-auto mb-6 animate-bounce">
81
- <h1 class="text-4xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-teal-300 to-emerald-400">
82
- Register for MGZon Chatbot
83
- </h1>
84
- <div class="glass p-8">
85
- <form id="registerForm" action="/auth/register" method="POST" class="flex flex-col gap-4">
86
- <input type="text" name="username" id="username" placeholder="Username" class="p-3 rounded-lg bg-gray-800/60 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500" required>
87
- <input type="email" name="email" id="email" placeholder="Email" class="p-3 rounded-lg bg-gray-800/60 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500" required>
88
- <input type="password" name="password" id="password" placeholder="Password" class="p-3 rounded-lg bg-gray-800/60 text-white border border-gray-700 focus:outline-none focus:ring-2 focus:ring-emerald-500" required>
89
- <button type="submit" id="registerBtn" class="bg-gradient-to-r from-emerald-500 to-teal-600 text-white px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
90
- Register <i class="bx bx-user-plus ml-2"></i>
91
- <span id="spinner" class="loading hidden"></span>
92
- </button>
93
- </form>
94
- <div class="flex justify-center gap-4 mt-4 flex-wrap">
95
- <a href="/auth/google/authorize" class="inline-flex items-center bg-gradient-to-r from-white to-gray-200 text-gray-800 px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
96
- Sign Up with Google <i class="bx bxl-google ml-2"></i>
97
- </a>
98
- <a href="/auth/github/authorize" class="inline-flex items-center bg-gradient-to-r from-gray-800 to-black text-white px-6 py-3 rounded-full font-semibold hover:scale-105 transition-transform">
99
- Sign Up with GitHub <i class="bx bxl-github ml-2"></i>
100
- </a>
101
- </div>
102
- <p class="mt-4">Already have an account? <a href="/login" class="text-emerald-300 hover:underline">Login</a></p>
103
- <p id="errorMsg" class="text-red-500 mt-4 hidden"></p>
104
- </div>
105
- </div>
106
- <footer class="bg-gradient-to-r from-teal-900 to-emerald-900 py-12 mt-8 w-full">
107
- <div class="container max-w-6xl mx-auto text-center">
108
- <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6 animate-pulse">
109
- <p class="mb-4">
110
- Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-emerald-300 hover:underline">Mark Al-Asfar</a>
111
- | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-emerald-300 hover:underline">MGZon AI</a>
112
- </p>
113
- <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
114
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('email')">
115
- <i class="bx bx-mail-send text-3xl text-emerald-300 mb-2"></i>
116
- <h4 class="font-semibold mb-1">Email Us</h4>
117
- <p><a href="mailto:support@mgzon.com" class="text-emerald-300 hover:underline">support@mgzon.com</a></p>
118
- <div id="email-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
119
- <p>Reach out to our support team for any inquiries or assistance.</p>
120
- <button onclick="closeCardDetails('email')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
121
- </div>
122
- </div>
123
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
124
- <i class="bx bx-phone text-3xl text-emerald-300 mb-2"></i>
125
- <h4 class="font-semibold mb-1">Phone Support</h4>
126
- <p>+1-800-123-4567</p>
127
- <div id="phone-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
128
- <p>Contact our support team via phone for immediate assistance.</p>
129
- <button onclick="closeCardDetails('phone')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
130
- </div>
131
- </div>
132
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('community')">
133
- <i class="bx bx-group text-3xl text-emerald-300 mb-2"></i>
134
- <h4 class="font-semibold mb-1">Community</h4>
135
- <p><a href="https://hager-zon.vercel.app/community" class="text-emerald-300 hover:underline">Join us</a></p>
136
- <div id="community-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
137
- <p>Join our vibrant community to share ideas and collaborate.</p>
138
- <button onclick="closeCardDetails('community')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
139
- </div>
140
- </div>
141
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
142
- <i class="bx bx-code-alt text-3xl text-emerald-300 mb-2"></i>
143
- <h4 class="font-semibold mb-1">API Docs</h4>
144
- <p><a href="/docs" class="text-emerald-300 hover:underline">Explore Docs</a></p>
145
- <div id="api-docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
146
- <p>Explore our API documentation for seamless integration.</p>
147
- <button onclick="closeCardDetails('api-docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
148
- </div>
149
- </div>
150
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
151
- <i class="bx bx-help-circle text-3xl text-emerald-300 mb-2"></i>
152
- <h4 class="font-semibold mb-1">FAQ</h4>
153
- <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-emerald-300 hover:underline">Read FAQ</a></p>
154
- <div id="faq-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
155
- <p>Find answers to common questions in our FAQ section.</p>
156
- <button onclick="closeCardDetails('faq')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
157
- </div>
158
  </div>
159
- <div class="glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
160
- <i class="bx bx-book text-3xl text-emerald-300 mb-2"></i>
161
- <h4 class="font-semibold mb-1">Documentation</h4>
162
- <p><a href="/docs" class="text-emerald-300 hover:underline">Full Docs</a></p>
163
- <div id="docs-details" class="hidden mt-4 p-4 bg-gray-700/80 rounded-lg">
164
- <p>Access comprehensive documentation for MGZon Chatbot.</p>
165
- <button onclick="closeCardDetails('docs')" class="bg-emerald-500 text-white px-4 py-2 rounded-lg mt-2">Close</button>
166
- </div>
167
- </div>
168
- </div>
169
- <div class="flex justify-center gap-6 mt-6">
170
- <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-github"></i></a>
171
- <a href="https://x.com/MGZon" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-twitter"></i></a>
172
- <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-white hover:text-emerald-300 transition"><i class="bx bxl-facebook"></i></a>
173
- </div>
174
- <p class="mt-6">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
175
  </div>
176
- </footer>
177
- <script>
178
- const registerForm = document.getElementById('registerForm');
179
- const registerBtn = document.getElementById('registerBtn');
180
- const spinner = document.getElementById('spinner');
181
- const errorMsg = document.getElementById('errorMsg');
182
- registerForm.addEventListener('submit', async (e) => {
183
- e.preventDefault();
184
- spinner.classList.remove('hidden');
185
- errorMsg.classList.add('hidden');
186
- const formData = new FormData(registerForm);
187
- try {
188
- const response = await fetch('/auth/register', {
189
- method: 'POST',
190
- body: formData
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  });
192
- spinner.classList.add('hidden');
193
- if (response.ok) {
194
- window.location.href = '/chat';
195
- } else {
196
- const error = await response.json();
197
- errorMsg.textContent = error.detail || 'Registration failed. Please try again.';
198
- errorMsg.classList.remove('hidden');
199
- }
200
- } catch (error) {
201
- spinner.classList.add('hidden');
202
- errorMsg.textContent = 'An error occurred. Please try again.';
203
- errorMsg.classList.remove('hidden');
204
- }
205
- });
206
- function showCardDetails(cardId) {
207
- document.getElementById(`${cardId}-details`).classList.remove('hidden');
208
- }
209
- function closeCardDetails(cardId) {
210
- document.getElementById(`${cardId}-details`).classList.add('hidden');
211
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  if ('serviceWorker' in navigator) {
213
- navigator.serviceWorker.register('/static/js/sw.js')
214
- .then(function(reg) {
215
- console.log('✅ Service Worker Registered', reg);
216
- }).catch(function(err) {
217
- console.error('❌ Service Worker registration failed', err);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  });
219
- }
220
- </script>
221
  </body>
222
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign up with email, Google, or GitHub.">
7
+ <meta name="keywords" content="MGZon Chatbot, register, sign up, AI assistant, code generation, e-commerce, Mark Al-Asfar">
8
+ <meta name="author" content="Mark Al-Asfar">
9
+ <meta name="robots" content="index, follow">
10
+ <title>Register - MGZon Chatbot</title>
11
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
12
+ <link rel="apple-touch-icon" href="/static/images/mg.svg">
13
+ <link rel="manifest" href="/static/manifest.json">
14
+ <meta name="apple-mobile-web-app-capable" content="yes">
15
+ <meta name="apple-mobile-web-app-title" content="MGZon">
16
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
17
+ <meta name="theme-color" content="#00f0ff">
18
+ <meta property="og:title" content="Register - MGZon Chatbot">
19
+ <meta property="og:description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
20
+ <meta property="og:image" content="/static/images/mg.svg">
21
+ <meta property="og:url" content="https://mgzon-mgzon-app.hf.space/register">
22
+ <meta property="og:type" content="website">
23
+ <meta name="twitter:card" content="summary_large_image">
24
+ <meta name="twitter:title" content="Register - MGZon Chatbot">
25
+ <meta name="twitter:description" content="Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools.">
26
+ <meta name="twitter:image" content="/static/images/mg.svg">
27
+ <script type="application/ld+json">
28
+ {
29
+ "@context": "https://schema.org",
30
+ "@type": "WebPage",
31
+ "name": "Register - MGZon Chatbot",
32
+ "url": "https://mgzon-mgzon-app.hf.space/register",
33
+ "description": "Register for MGZon Chatbot to access AI-powered code generation and e-commerce tools. Sign up with email, Google, or GitHub.",
34
+ "keywords": ["MGZon Chatbot", "register", "sign up", "AI chatbot", "code generation", "e-commerce", "Mark Al-Asfar", "MGZon", "MGZon AI", "E-commerce chatbot", "Python AI chatbot", "FastAPI integration"],
35
+ "isPartOf": {
36
+ "@type": "WebSite",
37
+ "name": "MGZon Chatbot",
38
+ "url": "https://mgzon-mgzon-app.hf.space/"
39
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
+ </script>
42
+ <script src="https://cdn.tailwindcss.com"></script>
43
+ <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet">
44
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700&family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
45
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/particles.js/2.0.0/particles.min.js"></script>
46
+ <style>
47
+ :root {
48
+ --font-sans: 'Poppins', sans-serif;
49
+ --font-mono: 'Orbitron', monospace;
50
+ --radius: 1rem;
51
+ }
52
+
53
+ :root.dark {
54
+ --background: 220 70% 10%;
55
+ --foreground: 0 0% 95%;
56
+ --card: 220 70% 15%;
57
+ --card-foreground: 0 0% 90%;
58
+ --primary: 180 100% 50%;
59
+ --primary-foreground: 0 0% 0%;
60
+ --secondary: 260 80% 30%;
61
+ --secondary-foreground: 0 0% 95%;
62
+ --muted: 220 50% 20%;
63
+ --muted-foreground: 0 0% 70%;
64
+ --accent: 320 100% 60%;
65
+ --accent-foreground: 0 0% 95%;
66
+ --border: 220 50% 25%;
67
+ }
68
+
69
+ :root.light {
70
+ --background: 0 0% 100%;
71
+ --foreground: 220 70% 10%;
72
+ --card: 0 0% 95%;
73
+ --card-foreground: 220 70% 15%;
74
+ --primary: 180 100% 50%;
75
+ --primary-foreground: 0 0% 100%;
76
+ --secondary: 260 80% 40%;
77
+ --secondary-foreground: 0 0% 10%;
78
+ --muted: 0 0% 90%;
79
+ --muted-foreground: 0 0% 40%;
80
+ --accent: 320 100% 50%;
81
+ --accent-foreground: 0 0% 10%;
82
+ --border: 0 0% 80%;
83
+ }
84
+
85
+ * {
86
+ margin: 0;
87
+ padding: 0;
88
+ box-sizing: border-box;
89
+ }
90
+
91
+ body {
92
+ font-family: var(--font-sans);
93
+ background: hsl(var(--background));
94
+ color: hsl(var(--foreground));
95
+ line-height: 1.6;
96
+ min-height: 100vh;
97
+ position: relative;
98
+ overflow-x: hidden;
99
+ }
100
+
101
+ #particles-js {
102
+ position: fixed;
103
+ top: 0;
104
+ left: 0;
105
+ width: 100%;
106
+ height: 100%;
107
+ z-index: -1;
108
+ }
109
+
110
+ .container {
111
+ max-width: 1280px;
112
+ margin: 0 auto;
113
+ padding: 0 2rem;
114
+ }
115
+
116
+ .glass {
117
+ background: rgba(255, 255, 255, 0.07);
118
+ border-radius: var(--radius);
119
+ border: 1px solid rgba(255, 255, 255, 0.12);
120
+ backdrop-filter: blur(12px);
121
+ -webkit-backdrop-filter: blur(12px);
122
+ transition: all 0.3s ease;
123
+ }
124
+
125
+ .glass:hover {
126
+ transform: scale(1.05);
127
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);
128
+ background: rgba(255, 255, 255, 0.15);
129
+ }
130
+
131
+ .register-button {
132
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
133
+ color: hsl(var(--primary-foreground));
134
+ border: none;
135
+ padding: 1rem 2rem;
136
+ border-radius: var(--radius);
137
+ font-family: var(--font-mono);
138
+ font-weight: 600;
139
+ transition: all 0.3s ease;
140
+ position: relative;
141
+ overflow: hidden;
142
+ }
143
+
144
+ .register-button:hover {
145
+ transform: translateY(-5px) scale(1.05);
146
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
147
+ }
148
+
149
+ .register-button::before {
150
+ content: '';
151
+ position: absolute;
152
+ top: 0;
153
+ left: -100%;
154
+ width: 100%;
155
+ height: 100%;
156
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
157
+ transition: left 0.5s;
158
+ }
159
+
160
+ .register-button:hover::before {
161
+ left: 100%;
162
+ }
163
+
164
+ .input-field {
165
+ background: hsl(var(--muted));
166
+ border: 1px solid hsl(var(--border));
167
+ color: hsl(var(--foreground));
168
+ padding: 0.75rem;
169
+ border-radius: var(--radius);
170
+ font-family: var(--font-sans);
171
+ transition: all 0.3s ease;
172
+ }
173
+
174
+ .input-field:focus {
175
+ outline: none;
176
+ border-color: hsl(var(--primary));
177
+ box-shadow: 0 0 10px hsl(var(--primary) / 0.5);
178
+ }
179
+
180
+ .theme-toggle {
181
+ position: fixed;
182
+ top: 2rem;
183
+ right: 2rem;
184
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--muted)));
185
+ border: 1px solid hsl(var(--border));
186
+ color: hsl(var(--card-foreground));
187
+ padding: 1rem;
188
+ border-radius: var(--radius);
189
+ cursor: pointer;
190
+ font-size: 1.5rem;
191
+ transition: all 0.3s ease;
192
+ z-index: 1000;
193
+ }
194
+
195
+ .theme-toggle:hover {
196
+ background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--accent)));
197
+ transform: scale(1.2) rotate(360deg);
198
+ box-shadow: 0 10px 20px hsl(var(--primary) / 0.5);
199
+ }
200
+
201
+ .error-message {
202
+ background: hsl(var(--muted));
203
+ border-left: 5px solid hsl(var(--accent));
204
+ padding: 1rem;
205
+ border-radius: var(--radius);
206
+ color: hsl(var(--accent-foreground));
207
+ }
208
+
209
+ .footer-card {
210
+ transition: all 0.3s ease;
211
+ box-shadow: 0 5px 15px hsl(var(--foreground) / 0.2);
212
+ }
213
+
214
+ .footer-card:hover {
215
+ transform: translateY(-10px) scale(1.05);
216
+ box-shadow: 0 15px 30px hsl(var(--primary) / 0.4);
217
+ }
218
+
219
+ .footer-card-icon {
220
+ transition: transform 0.3s ease;
221
+ }
222
+
223
+ .footer-card:hover .footer-card-icon {
224
+ transform: scale(1.2) rotate(5deg);
225
+ }
226
+
227
+ .wave-divider {
228
+ height: 120px;
229
+ background: transparent;
230
+ position: relative;
231
+ overflow: hidden;
232
+ }
233
+
234
+ .wave-divider::before {
235
+ content: '';
236
+ position: absolute;
237
+ bottom: 0;
238
+ left: 0;
239
+ width: 200%;
240
+ height: 100%;
241
+ background: linear-gradient(135deg, hsl(var(--card)), hsl(var(--background)));
242
+ border-radius: 50%;
243
+ animation: wave 10s ease-in-out infinite;
244
+ }
245
+
246
+ @keyframes wave {
247
+ 0%, 100% { transform: translateX(-50%) translateY(70%); }
248
+ 50% { transform: translateX(-50%) translateY(50%); }
249
+ }
250
+
251
+ @keyframes fadeIn {
252
+ from { opacity: 0; transform: translateY(40px); }
253
+ to { opacity: 1; transform: translateY(0); }
254
+ }
255
+
256
+ .footer {
257
+ text-align: center;
258
+ }
259
+
260
+ .footer p {
261
+ margin-left: auto;
262
+ margin-right: auto;
263
+ }
264
+
265
+ @media (max-width: 768px) {
266
+ .container {
267
+ padding: 0 1.5rem;
268
+ }
269
+ }
270
+ </style>
271
  </head>
272
+ <body>
273
+ <div id="particles-js"></div>
274
+
275
+ <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
276
+
277
+ <div class="container flex flex-col justify-center items-center min-h-screen">
278
+ <img src="/static/images/mg.svg" alt="MGZon Chatbot Logo by Mark Al-Asfar" class="w-32 h-32 mx-auto mb-6" style="animation: fadeIn 1s ease-out;">
279
+ <h1 class="text-4xl font-bold mb-4 font-[var(--font-mono)] bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] bg-clip-text text-transparent" style="animation: fadeIn 1s ease-out 0.3s both;">
280
+ Register for MGZon Chatbot
281
+ </h1>
282
+ <div class="glass p-8 max-w-md w-full" style="animation: fadeIn 1s ease-out 0.6s both;">
283
+ <form id="registerForm" action="/auth/register" method="POST" class="flex flex-col gap-4">
284
+ <input type="text" name="username" id="username" placeholder="Username" class="input-field" required>
285
+ <input type="email" name="email" id="email" placeholder="Email" class="input-field" required>
286
+ <input type="password" name="password" id="password" placeholder="Password" class="input-field" required>
287
+ <button type="submit" id="registerBtn" class="register-button">
288
+ Register <i class="bx bx-user-plus ml-2"></i>
289
+ <span id="spinner" class="loading hidden"></span>
290
+ </button>
291
+ </form>
292
+ <div class="flex justify-center gap-4 mt-4 flex-wrap">
293
+ <a href="/auth/google/authorize" class="register-button inline-flex items-center">
294
+ Sign Up with Google <i class="bx bxl-google ml-2"></i>
295
+ </a>
296
+ <a href="/auth/github/authorize" class="register-button inline-flex items-center">
297
+ Sign Up with GitHub <i class="bx bxl-github ml-2"></i>
298
+ </a>
299
+ </div>
300
+ <p class="mt-4 text-center">
301
+ Already have an account? <a href="/login" class="text-[hsl(var(--primary))] hover:underline">Login</a>
302
+ </p>
303
+ <p id="errorMsg" class="error-message mt-4 hidden"></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  </div>
306
+
307
+ <div class="wave-divider"></div>
308
+
309
+ <footer class="footer py-12">
310
+ <div class="container">
311
+ <img src="/static/images/mg.svg" alt="MGZon Logo" class="w-24 h-24 mx-auto mb-6" style="animation: fadeIn 1s ease-out;">
312
+ <p class="mb-4 text-center">
313
+ Developed by <a href="https://mark-elasfar.web.app/" target="_blank" class="text-[hsl(var(--primary))] hover:underline">Mark Al-Asfar</a>
314
+ | Powered by <a href="https://hager-zon.vercel.app/" target="_blank" class="text-[hsl(var(--primary))] hover:underline">MGZon AI</a>
315
+ </p>
316
+ <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
317
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('email')">
318
+ <i class="bx bx-mail-send text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
319
+ <h4 class="font-semibold mb-1">Email Us</h4>
320
+ <p><a href="mailto:support@mgzon.com" class="text-[hsl(var(--primary))] hover:underline">support@mgzon.com</a></p>
321
+ <div id="email-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
322
+ <p>Reach out to our support team for any inquiries or assistance.</p>
323
+ <button onclick="closeCardDetails('email')" class="register-button mt-2">Close</button>
324
+ </div>
325
+ </div>
326
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('phone')">
327
+ <i class="bx bx-phone text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
328
+ <h4 class="font-semibold mb-1">Phone Support</h4>
329
+ <p>20 1212444617</p>
330
+ <div id="phone-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
331
+ <p>Contact our support team via phone for immediate assistance.</p>
332
+ <button onclick="closeCardDetails('phone')" class="register-button mt-2">Close</button>
333
+ </div>
334
+ </div>
335
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('community')">
336
+ <i class="bx bx-group text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
337
+ <h4 class="font-semibold mb-1">Community</h4>
338
+ <p><a href="https://hager-zon.vercel.app/community" class="text-[hsl(var(--primary))] hover:underline">Join us</a></p>
339
+ <div id="community-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
340
+ <p>Join our vibrant community to share ideas and collaborate.</p>
341
+ <button onclick="closeCardDetails('community')" class="register-button mt-2">Close</button>
342
+ </div>
343
+ </div>
344
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('api-docs')">
345
+ <i class="bx bx-code-alt text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
346
+ <h4 class="font-semibold mb-1">API Docs</h4>
347
+ <p><a href="/docs" class="text-[hsl(var(--primary))] hover:underline">Explore Docs</a></p>
348
+ <div id="api-docs-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
349
+ <p>Explore our API documentation for seamless integration.</p>
350
+ <button onclick="closeCardDetails('api-docs')" class="register-button mt-2">Close</button>
351
+ </div>
352
+ </div>
353
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('faq')">
354
+ <i class="bx bx-help-circle text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
355
+ <h4 class="font-semibold mb-1">FAQ</h4>
356
+ <p><a href="https://hager-zon.vercel.app/faq" target="_blank" class="text-[hsl(var(--primary))] hover:underline">Read FAQ</a></p>
357
+ <div id="faq-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
358
+ <p>Find answers to common questions in our FAQ section.</p>
359
+ <button onclick="closeCardDetails('faq')" class="register-button mt-2">Close</button>
360
+ </div>
361
+ </div>
362
+ <div class="footer-card glass p-4 cursor-pointer" onclick="showCardDetails('docs')">
363
+ <i class="bx bx-book text-3xl text-[hsl(var(--primary))] mb-2 footer-card-icon"></i>
364
+ <h4 class="font-semibold mb-1">Documentation</h4>
365
+ <p><a href="/docs" class="text-[hsl(var(--primary))] hover:underline">Full Docs</a></p>
366
+ <div id="docs-details" class="hidden mt-4 p-4 bg-[hsl(var(--muted))] rounded-lg">
367
+ <p>Access comprehensive documentation for MGZon Chatbot.</p>
368
+ <button onclick="closeCardDetails('docs')" class="register-button mt-2">Close</button>
369
+ </div>
370
+ </div>
371
+ </div>
372
+ <div class="flex justify-center gap-6 mt-6">
373
+ <a href="https://github.com/Mark-Lasfar/MGZon" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-github"></i></a>
374
+ <a href="https://x.com/MGZon" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-twitter"></i></a>
375
+ <a href="https://www.facebook.com/people/Mark-Al-Asfar/pfbid02GMisUQ8AqWkNZjoKtWFHH1tbdHuVscN1cjcFnZWy9HkRaAsmanBfT6mhySAyqpg4l/" class="text-2xl text-[hsl(var(--foreground))] hover:text-[hsl(var(--primary))] transition"><i class="bx bxl-facebook"></i></a>
376
+ </div>
377
+ <p class="mt-6 text-center">© 2025 Mark Al-Asfar & MGZon AI. All rights reserved.</p>
378
+ </div>
379
+ <button id="installAppBtn" style="display: none;" class="fixed bottom-4 right-4 bg-gradient-to-r from-[hsl(var(--primary))] to-[hsl(var(--accent))] text-[hsl(var(--primary-foreground))] px-6 py-3 rounded-full shadow-lg z-50">
380
+ 📲 Install MG Chat
381
+ </button>
382
+ </footer>
383
+
384
+ <script>
385
+ // Particles.js initialization
386
+ particlesJS('particles-js', {
387
+ particles: {
388
+ number: { value: 80, density: { enable: true, value_area: 800 } },
389
+ color: { value: ['#00f0ff', '#ff007a', '#6b21a8'] },
390
+ shape: { type: 'circle' },
391
+ opacity: { value: 0.5, random: true },
392
+ size: { value: 3, random: true },
393
+ line_linked: { enable: true, distance: 150, color: '#00f0ff', opacity: 0.4, width: 1 },
394
+ move: { enable: true, speed: 3, direction: 'none', random: true }
395
+ },
396
+ interactivity: {
397
+ detect_on: 'canvas',
398
+ events: { onhover: { enable: true, mode: 'repulse' }, onclick: { enable: true, mode: 'push' } },
399
+ modes: { repulse: { distance: 100 }, push: { particles_nb: 4 } }
400
+ },
401
+ retina_detect: true
402
  });
403
+
404
+ function toggleTheme() {
405
+ const html = document.documentElement;
406
+ const button = document.querySelector('.theme-toggle');
407
+ if (html.classList.contains('dark')) {
408
+ html.classList.remove('dark');
409
+ html.classList.add('light');
410
+ button.textContent = '☀️';
411
+ localStorage.setItem('theme', 'light');
412
+ } else {
413
+ html.classList.remove('light');
414
+ html.classList.add('dark');
415
+ button.textContent = '🌙';
416
+ localStorage.setItem('theme', 'dark');
417
+ }
418
+ }
419
+
420
+ // Load saved theme preference or system preference
421
+ const savedTheme = localStorage.getItem('theme');
422
+ if (savedTheme) {
423
+ document.documentElement.classList.remove('dark', 'light');
424
+ document.documentElement.classList.add(savedTheme);
425
+ document.querySelector('.theme-toggle').textContent = savedTheme === 'dark' ? '🌙' : '☀️';
426
+ } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
427
+ document.documentElement.classList.remove('dark');
428
+ document.documentElement.classList.add('light');
429
+ document.querySelector('.theme-toggle').textContent = '☀️';
430
+ localStorage.setItem('theme', 'light');
431
+ }
432
+
433
+ // Handle form submission
434
+ const registerForm = document.getElementById('registerForm');
435
+ const registerBtn = document.getElementById('registerBtn');
436
+ const spinner = document.getElementById('spinner');
437
+ const errorMsg = document.getElementById('errorMsg');
438
+
439
+ registerForm.addEventListener('submit', async (e) => {
440
+ e.preventDefault();
441
+ console.log('Register form submitted');
442
+ spinner.classList.remove('hidden');
443
+ errorMsg.classList.add('hidden');
444
+ const formData = new FormData(registerForm);
445
+ try {
446
+ const response = await fetch('/auth/register', {
447
+ method: 'POST',
448
+ body: formData
449
+ });
450
+ spinner.classList.add('hidden');
451
+ if (response.ok) {
452
+ console.log('Registration successful, redirecting to /chat');
453
+ window.location.href = '/chat';
454
+ } else {
455
+ const error = await response.json();
456
+ errorMsg.textContent = error.detail || 'Registration failed. Please try again.';
457
+ errorMsg.classList.remove('hidden');
458
+ console.error('Registration failed:', error);
459
+ }
460
+ } catch (error) {
461
+ spinner.classList.add('hidden');
462
+ errorMsg.textContent = 'An error occurred. Please try again.';
463
+ errorMsg.classList.remove('hidden');
464
+ console.error('Error during registration:', error);
465
+ }
466
+ });
467
+
468
+ // Handle card details toggle
469
+ function showCardDetails(cardId) {
470
+ console.log('Showing card details:', cardId);
471
+ document.getElementById(`${cardId}-details`).classList.remove('hidden');
472
+ }
473
+
474
+ function closeCardDetails(cardId) {
475
+ console.log('Closing card details:', cardId);
476
+ document.getElementById(`${cardId}-details`).classList.add('hidden');
477
+ }
478
+
479
+ // Service Worker for PWA
480
  if ('serviceWorker' in navigator) {
481
+ console.log('Registering service worker');
482
+ navigator.serviceWorker.register('/static/js/sw.js')
483
+ .then(reg => console.log('✅ Service Worker Registered', reg))
484
+ .catch(err => console.error('❌ Service Worker registration failed', err));
485
+ }
486
+
487
+ // Handle PWA install prompt
488
+ let deferredPrompt;
489
+ window.addEventListener('beforeinstallprompt', (e) => {
490
+ console.log('Before install prompt triggered');
491
+ e.preventDefault();
492
+ deferredPrompt = e;
493
+ const installBtn = document.getElementById('installAppBtn');
494
+ if (installBtn) {
495
+ installBtn.style.display = 'block';
496
+ installBtn.addEventListener('click', () => {
497
+ console.log('Install button clicked');
498
+ deferredPrompt.prompt();
499
+ deferredPrompt.userChoice.then(choice => {
500
+ if (choice.outcome === 'accepted') {
501
+ console.log('✅ User accepted the install prompt');
502
+ } else {
503
+ console.log('❌ User dismissed the install prompt');
504
+ }
505
+ deferredPrompt = null;
506
+ });
507
+ });
508
+ }
509
  });
510
+ </script>
 
511
  </body>
512
  </html>
test_models.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ import whisper
3
+ import time
4
+ from gtts import gTTS
5
+ import os
6
+
7
+ # اختبار 1: DistilGPT2 (نصي)
8
+ def test_distilgpt2():
9
+ print("\n=== اختبار DistilGPT2 ===")
10
+ start_time = time.time()
11
+ generator = pipeline('text-generation', model='distilgpt2')
12
+
13
+ # اختبار بالإنجليزية
14
+ prompt_en = "What's the capital of France?"
15
+ result_en = generator(
16
+ prompt_en,
17
+ max_new_tokens=50,
18
+ truncation=True,
19
+ do_sample=True,
20
+ top_p=0.9,
21
+ top_k=50, # إضافة top_k لتحسين التنوع
22
+ temperature=0.7 # لتقليل العشوائية
23
+ )
24
+ print(f"الرد (إنجليزي): {result_en[0]['generated_text']}")
25
+
26
+ # اختبار بالعربية
27
+ prompt_ar = "ما عاصمة فرنسا؟"
28
+ result_ar = generator(
29
+ prompt_ar,
30
+ max_new_tokens=50,
31
+ truncation=True,
32
+ do_sample=True,
33
+ top_p=0.9,
34
+ top_k=50,
35
+ temperature=0.7
36
+ )
37
+ print(f"الرد (عربي): {result_ar[0]['generated_text']}")
38
+
39
+ print(f"الوقت: {time.time() - start_time:.2f} ثانية")
40
+
41
+ # اختبار 2: Qwen2-0.5B-Instruct (نصي، دعم أفضل للعربية)
42
+ def test_qwen2():
43
+ print("\n=== اختبار Qwen2-0.5B-Instruct ===")
44
+ start_time = time.time()
45
+ generator = pipeline('text-generation', model='Qwen/Qwen2-0.5B-Instruct')
46
+
47
+ # اختبار بالإنجليزية
48
+ prompt_en = "What's the capital of France?"
49
+ result_en = generator(
50
+ prompt_en,
51
+ max_new_tokens=50,
52
+ truncation=True,
53
+ do_sample=True,
54
+ top_p=0.9,
55
+ top_k=50,
56
+ temperature=0.7
57
+ )
58
+ print(f"الرد (إنجليزي): {result_en[0]['generated_text']}")
59
+
60
+ # اختبار بالعربية
61
+ prompt_ar = "ما عاصمة فرنسا؟"
62
+ result_ar = generator(
63
+ prompt_ar,
64
+ max_new_tokens=50,
65
+ truncation=True,
66
+ do_sample=True,
67
+ top_p=0.9,
68
+ top_k=50,
69
+ temperature=0.7
70
+ )
71
+ print(f"الرد (عربي): {result_ar[0]['generated_text']}")
72
+
73
+ print(f"الوقت: {time.time() - start_time:.2f} ثانية")
74
+
75
+ # اختبار 3: Whisper-tiny (صوتي)
76
+ def test_whisper_tiny():
77
+ print("\n=== اختبار Whisper-tiny ===")
78
+ start_time = time.time()
79
+
80
+ # إنشاء ملف صوتي مؤقت باستخدام gTTS
81
+ text = "Hello world, this is a test audio."
82
+ tts = gTTS(text=text, lang='en')
83
+ audio_file = "test_audio.wav"
84
+ tts.save(audio_file)
85
+
86
+ # تحميل واختبار Whisper-tiny
87
+ model = whisper.load_model("tiny")
88
+ result = model.transcribe(audio_file, fp16=False)
89
+ print(f"النص المترجم: {result['text']}")
90
+ print(f"الوقت: {time.time() - start_time:.2f} ثانية")
91
+
92
+ # تنظيف الملف المؤقت
93
+ if os.path.exists(audio_file):
94
+ os.remove(audio_file)
95
+
96
+ if __name__ == "__main__":
97
+ test_distilgpt2()
98
+ test_qwen2()
99
+ test_whisper_tiny()