rinogeek commited on
Commit
a026242
·
1 Parent(s): 7ef0739
backend/.env.production ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================================
2
+ # CONFIGURATION PRODUCTION - HUGGING FACE SPACES
3
+ # ==============================================
4
+
5
+ # Django Settings
6
+ DEBUG=False
7
+ SECRET_KEY=django-insecure-xdNTqmUzzdJbmHZ8fLr6B6v1NfShmDZM
8
+ ALLOWED_HOSTS=localhost,127.0.0.1,.hf.space
9
+
10
+ # CORS - Autoriser le frontend Hugging Face
11
+ CORS_ALLOWED_ORIGINS=https://rinogeek-edulabfrontend.hf.space
12
+
13
+ # CSRF - Autoriser les origines de confiance
14
+ CSRF_TRUSTED_ORIGINS=https://rinogeek-edulabfrontend.hf.space,https://rinogeek-edulabbackend.hf.space
15
+
16
+ # Database - SQLite par défaut (pas de DB_HOST = utilise SQLite)
17
+ # Pour PostgreSQL, décommentez et configurez :
18
+ # DB_NAME=educonnect_db
19
+ # DB_USER=postgres
20
+ # DB_PASSWORD=your_db_password
21
+ # DB_HOST=your_db_host
22
+ # DB_PORT=5432
23
+
24
+ # Redis (pour Celery et Channels) - Désactivé sur HF Spaces gratuit
25
+ # REDIS_HOST=localhost
26
+ # CELERY_BROKER_URL=redis://localhost:6379/0
27
+ # CELERY_RESULT_BACKEND=redis://localhost:6379/0
28
+
29
+ # Email Configuration
30
+ EMAIL_HOST=smtp.gmail.com
31
+ EMAIL_PORT=587
32
+ EMAIL_HOST_USER=
33
+ EMAIL_HOST_PASSWORD=
34
+ DEFAULT_FROM_EMAIL=noreply@edulab.africa
35
+
36
+ # AI APIs
37
+ GEMINI_API_KEY=AIzaSyD-hnYdbQudiK8nfFtML05Mmlo26nLzxWQ
38
+
39
+ # Logging
40
+ DJANGO_LOG_LEVEL=INFO
41
+
42
+ # Security - HF gère SSL au niveau proxy
43
+ SECURE_SSL_REDIRECT=False
backend/.gitignore ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # Django stuff:
28
+ *.log
29
+ *.pot
30
+ *.pyc
31
+ local_settings.py
32
+ db.sqlite3
33
+ db.sqlite3-journal
34
+
35
+ # Media files
36
+ media/
37
+
38
+ # Static files (collectstatic output)
39
+ staticfiles/
40
+
41
+ # Environment
42
+ .env
43
+ .env.local
44
+ venv/
45
+ ENV/
46
+ env/
47
+ .venv/
48
+
49
+ # IDE
50
+ .idea/
51
+ .vscode/
52
+ *.swp
53
+ *.swo
54
+
55
+ # Logs
56
+ logs/
57
+ *.log
58
+
59
+ # OS
60
+ .DS_Store
61
+ Thumbs.db
62
+
63
+ # Celery
64
+ celerybeat-schedule
65
+ celerybeat.pid
66
+
67
+ # Coverage
68
+ .coverage
69
+ htmlcov/
70
+
71
+ # pytest
72
+ .pytest_cache/
73
+
74
+ # mypy
75
+ .mypy_cache/
backend/Dockerfile CHANGED
@@ -12,20 +12,49 @@ RUN apt-get update && apt-get install -y \
12
  libpq-dev \
13
  && rm -rf /var/lib/apt/lists/*
14
 
15
- # Copier requirements
 
 
 
 
 
 
 
16
  COPY requirements.txt /app/
17
- RUN pip install --upgrade pip
18
- RUN pip install -r requirements.txt
 
 
 
 
 
 
 
19
 
20
- # Copier le projet
21
- COPY . /app/
22
 
23
- # Créer les dossiers
24
- RUN mkdir -p logs media staticfiles
 
 
 
 
 
25
 
26
  # Collecter les fichiers statiques
27
  RUN python manage.py collectstatic --noinput
28
 
29
- EXPOSE 8000
 
 
 
 
 
 
 
 
 
30
 
31
- CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "educonnect.wsgi:application"]
 
 
12
  libpq-dev \
13
  && rm -rf /var/lib/apt/lists/*
14
 
15
+ # Créer un utilisateur non-root pour Hugging Face Spaces (UID 1000)
16
+ RUN useradd -m -u 1000 user
17
+
18
+ # Créer les dossiers nécessaires avec les bonnes permissions AVANT de changer d'utilisateur
19
+ RUN mkdir -p /app/logs /app/media /app/staticfiles && \
20
+ chown -R user:user /app
21
+
22
+ # Copier requirements et installer les dépendances (en tant que root pour pip)
23
  COPY requirements.txt /app/
24
+ RUN pip install --no-cache-dir --upgrade pip && \
25
+ pip install --no-cache-dir -r requirements.txt
26
+
27
+ # Maintenant passer à l'utilisateur non-root
28
+ USER user
29
+ ENV PATH="/home/user/.local/bin:${PATH}"
30
+
31
+ # Copier le reste du projet avec les bonnes permissions
32
+ COPY --chown=user:user . /app/
33
 
34
+ # Copier le fichier .env.production comme .env pour la production
35
+ RUN cp /app/.env.production /app/.env || true
36
 
37
+ # Appliquer les migrations de base de données
38
+ RUN python manage.py migrate --noinput
39
+
40
+ # Initialiser les données par défaut (social links, stats, tools, testimonials, badges, opportunities)
41
+ RUN python manage.py init_data
42
+
43
+ RUN python manage.py create_superuser --email admin@edulab.africa --password rinogeek --name "Rino Admin"
44
 
45
  # Collecter les fichiers statiques
46
  RUN python manage.py collectstatic --noinput
47
 
48
+ RUN echo '#!/bin/bash\n\
49
+ echo "=== Application Startup ===" \n\
50
+ python manage.py migrate --noinput\n\
51
+ python manage.py init_data\n\
52
+ python manage.py create_superuser --email admin@edulab.africa --password rinogeek --name "Rino Admin"\n\
53
+ exec gunicorn --bind 0.0.0.0:7860 --workers 2 --timeout 120 educonnect.wsgi:application\n\
54
+ ' > /app/start.sh && chmod +x /app/start.sh
55
+
56
+ # Exposer le port par défaut de Hugging Face Spaces
57
+ EXPOSE 7860
58
 
59
+ # Démarrer avec le script
60
+ CMD ["/app/start.sh"]
backend/README.md CHANGED
@@ -1,194 +1,38 @@
1
- # EduConnect Africa API
 
 
 
 
 
 
 
2
 
3
- API REST Django pour la plateforme EduConnect Africa - Initiative Hypee (Bénin)
4
 
5
- ## 🚀 Technologies
6
-
7
- - **Django 4.2** + **Django REST Framework 3.14**
8
- - **PostgreSQL 15** (Base de données)
9
- - **Redis** (Cache & Celery)
10
- - **Channels** (WebSockets pour le chat)
11
- - **JWT** (Authentification)
12
- - **Celery** (Tâches asynchrones)
13
- - **Docker** (Containerisation)
14
-
15
- ## 📋 Prérequis
16
-
17
- - Python 3.11+
18
- - PostgreSQL 15+
19
- - Redis 7+
20
- - Docker & Docker Compose (optionnel)
21
-
22
- ## ⚙️ Installation
23
-
24
- ### Méthode 1: Installation locale
25
-
26
- 1. **Cloner le projet**
27
- ```bash
28
- git clone <repo-url>
29
- cd educonnect-api
30
- ```
31
-
32
- 2. **Créer un environnement virtuel**
33
- ```bash
34
- python -m venv venv
35
- source venv/bin/activate # Linux/Mac
36
- # ou
37
- venv\\Scripts\\activate # Windows
38
- ```
39
-
40
- 3. **Installer les dépendances**
41
- ```bash
42
- pip install -r requirements.txt
43
- ```
44
-
45
- 4. **Configuration**
46
- ```bash
47
- cp .env.example .env
48
- # Éditer .env avec vos paramètres
49
- ```
50
-
51
- 5. **Créer la base de données**
52
- ```bash
53
- createdb educonnect_db
54
- ```
55
-
56
- 6. **Migrations**
57
- ```bash
58
- python manage.py makemigrations
59
- python manage.py migrate
60
- ```
61
-
62
- 7. **Initialiser les données**
63
- ```bash
64
- python manage.py init_db
65
- python manage.py create_test_data --users 20
66
- ```
67
-
68
- 8. **Créer un superuser**
69
- ```bash
70
- python manage.py createsuperuser
71
- ```
72
-
73
- 9. **Lancer le serveur**
74
- ```bash
75
- python manage.py runserver
76
- ```
77
-
78
- ### Méthode 2: Avec Docker
79
-
80
- ```bash
81
- docker-compose up --build
82
- docker-compose exec web python manage.py migrate
83
- docker-compose exec web python manage.py init_db
84
- docker-compose exec web python manage.py createsuperuser
85
- ```
86
-
87
- ## 📚 Documentation API
88
 
89
- Une fois le serveur lancé:
90
- - **Swagger UI**: http://localhost:8000/api/docs/
91
- - **ReDoc**: http://localhost:8000/api/redoc/
92
- - **Admin Django**: http://localhost:8000/admin/
93
-
94
- ## 🔑 Endpoints Principaux
95
-
96
- ### Authentification
97
- - `POST /api/auth/register/` - Inscription
98
- - `POST /api/auth/login/` - Connexion
99
- - `GET /api/auth/me/` - Profil actuel
100
- - `PATCH /api/auth/update_profile/` - Mise à jour profil
101
-
102
- ### Mentors
103
- - `GET /api/mentors/` - Liste des mentors
104
- - `GET /api/mentors/{id}/` - Détail mentor
105
- - `PATCH /api/mentors/my_profile/` - Mise à jour profil mentor
106
-
107
- ### Forum
108
- - `GET /api/forum/questions/` - Liste questions
109
- - `POST /api/forum/questions/` - Créer question
110
- - `POST /api/forum/questions/{id}/vote/` - Voter
111
- - `POST /api/forum/questions/{id}/answers/` - Répondre
112
-
113
- ### Réservations
114
- - `POST /api/bookings/` - Créer réservation
115
- - `GET /api/bookings/mentor_requests/` - Demandes reçues
116
- - `PATCH /api/bookings/{id}/update_status/` - Accepter/Refuser
117
-
118
- ### Gamification
119
- - `GET /api/gamification/leaderboard/` - Classement
120
- - `GET /api/gamification/my_badges/` - Mes badges
121
- - `GET /api/gamification/stats/` - Statistiques
122
-
123
- ### Messagerie
124
- - `GET /api/messages/conversations/` - Conversations
125
- - `POST /api/messages/conversations/{id}/send_message/` - Envoyer message
126
- - WebSocket: `ws://localhost:8001/ws/chat/{conversation_id}/`
127
-
128
- ### Notifications
129
- - `GET /api/notifications/` - Mes notifications
130
- - `POST /api/notifications/mark_all_read/` - Tout marquer lu
131
-
132
- ### Opportunités
133
- - `GET /api/opportunities/` - Liste opportunités
134
-
135
- ### IA
136
- - `POST /api/ai/tutor/` - Tuteur IA
137
-
138
- ## 🧪 Tests
139
-
140
- ```bash
141
- pytest
142
- pytest --cov=apps
143
- ```
144
-
145
- ## 🏗️ Structure du Projet
146
-
147
- ```
148
- educonnect-api/
149
- ├── apps/
150
- │ ├── users/ # Authentification & Utilisateurs
151
- │ ├── mentors/ # Gestion mentors
152
- │ ├── bookings/ # Système de réservation
153
- │ ├── forum/ # Questions & Réponses
154
- │ ├── gamification/ # Points & Badges
155
- │ ├── messaging/ # Chat en temps réel
156
- │ ├── notifications/ # Notifications
157
- │ ├── opportunities/ # Opportunités
158
- │ ├── ai_tools/ # Tuteur IA
159
- │ ├── analytics/ # Analytics
160
- │ └── core/ # Mixins, utilities
161
- ├── educonnect_api/ # Configuration Django
162
- ├── requirements.txt
163
- ├── Dockerfile
164
- └── docker-compose.yml
165
- ```
166
-
167
- ## 🔒 Sécurité
168
-
169
- - Tokens JWT avec refresh
170
- - Rate limiting
171
- - CORS configuré
172
- - Validation des entrées
173
- - Soft delete pour traçabilité
174
- - HTTPS obligatoire en production
175
-
176
- ## 📊 Monitoring
177
 
178
- Intégration Sentry pour le monitoring des erreurs en production.
 
 
 
 
179
 
180
- ## 🤝 Contribution
181
 
182
- 1. Fork le projet
183
- 2. Créer une branche (`git checkout -b feature/AmazingFeature`)
184
- 3. Commit (`git commit -m 'Add AmazingFeature'`)
185
- 4. Push (`git push origin feature/AmazingFeature`)
186
- 5. Pull Request
 
 
187
 
188
- ## 📝 Licence
189
 
190
- Propriétaire - Initiative Hypee Bénin
191
 
192
- ## 👥 Équipe
193
 
194
- Initiative Hypee - Bénin
 
1
+ ---
2
+ title: EduLab Backend
3
+ emoji: 🎓
4
+ colorFrom: blue
5
+ colorTo: indigo
6
+ sdk: docker
7
+ app_port: 7860
8
+ ---
9
 
10
+ # EduLab Africa - Backend API
11
 
12
+ Backend Django REST API pour la plateforme éducative EduLab Africa.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
+ ## 🚀 Technologies
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ - **Django 4.2** - Framework web Python
17
+ - **Django REST Framework** - API REST
18
+ - **SQLite** - Base de données (par défaut)
19
+ - **Gunicorn** - Serveur WSGI
20
+ - **JWT** - Authentification
21
 
22
+ ## 📡 API Endpoints
23
 
24
+ - `/api/users/` - Gestion des utilisateurs
25
+ - `/api/mentors/` - Profils mentors
26
+ - `/api/bookings/` - Réservations de sessions
27
+ - `/api/forum/` - Forum communautaire
28
+ - `/api/opportunities/` - Opportunités éducatives
29
+ - `/api/ai-tools/` - Outils IA
30
+ - `/api/gamification/` - Système de badges et points
31
 
32
+ ## 🔗 Frontend
33
 
34
+ Ce backend est connecté au frontend : [EdulabFrontend](https://huggingface.co/spaces/rinogeek/EdulabFrontend)
35
 
36
+ ## 👨‍💻 Développeur
37
 
38
+ Développé par **Marino ATOHOUN** pour **Hypee**
backend/apps/users/management/commands/create_superuser.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Commande pour créer un superutilisateur par défaut
3
+ """
4
+ from django.core.management.base import BaseCommand
5
+ from django.contrib.auth import get_user_model
6
+ from apps.users.models import UserProfile
7
+
8
+ User = get_user_model()
9
+
10
+
11
+ class Command(BaseCommand):
12
+ help = 'Créer un superutilisateur par défaut si aucun n\'existe'
13
+
14
+ def add_arguments(self, parser):
15
+ parser.add_argument(
16
+ '--email',
17
+ default='admin@edulab.africa',
18
+ help='Email du superuser'
19
+ )
20
+ parser.add_argument(
21
+ '--password',
22
+ default='rinogeek',
23
+ help='Mot de passe du superuser'
24
+ )
25
+ parser.add_argument(
26
+ '--name',
27
+ default='Rino Admin',
28
+ help='Nom complet du superuser'
29
+ )
30
+
31
+ def handle(self, *args, **options):
32
+ email = options['email']
33
+ password = options['password']
34
+ name = options['name']
35
+
36
+ # Vérifier si un superuser existe déjà
37
+ if User.objects.filter(is_superuser=True).exists():
38
+ self.stdout.write(
39
+ self.style.WARNING(f'Un superutilisateur existe déjà. Ignoré.')
40
+ )
41
+ return
42
+
43
+ # Vérifier si l'utilisateur existe déjà
44
+ if User.objects.filter(email=email).exists():
45
+ user = User.objects.get(email=email)
46
+ if not user.is_superuser:
47
+ user.is_superuser = True
48
+ user.is_staff = True
49
+ user.role = 'ADMIN'
50
+ user.save()
51
+ self.stdout.write(
52
+ self.style.SUCCESS(f'Utilisateur "{email}" promu superutilisateur.')
53
+ )
54
+ else:
55
+ self.stdout.write(
56
+ self.style.WARNING(f'Utilisateur "{email}" existe déjà.')
57
+ )
58
+ return
59
+
60
+ # Créer le superutilisateur
61
+ user = User.objects.create_superuser(
62
+ email=email,
63
+ password=password
64
+ )
65
+
66
+ # Créer le profil utilisateur
67
+ UserProfile.objects.create(
68
+ user=user,
69
+ name=name,
70
+ is_current=True
71
+ )
72
+
73
+ self.stdout.write(
74
+ self.style.SUCCESS(
75
+ f'✓ Superutilisateur créé avec succès!\n'
76
+ f' Email: {email}\n'
77
+ f' Name: {name}\n'
78
+ f' Password: {password}'
79
+ )
80
+ )
backend/educonnect/settings.py CHANGED
@@ -11,7 +11,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
11
  # SECURITY
12
  SECRET_KEY = config('SECRET_KEY', default='django-insecure-6tmj-j5auz5kd)bda)acc0!*j+8-)knr7wsp(lqs=46$alpd5j')
13
  DEBUG = config('DEBUG', default=False, cast=bool)
14
- ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='localhost,127.0.0.1').split(',')
15
 
16
  # Application definition
17
  INSTALLED_APPS = [
@@ -182,9 +182,17 @@ SIMPLE_JWT = {
182
  # CORS Configuration
183
  CORS_ALLOWED_ORIGINS = config(
184
  'CORS_ALLOWED_ORIGINS',
185
- default='http://localhost:3000,http://localhost:5173,http://localhost:3001'
186
  ).split(',')
187
  CORS_ALLOW_CREDENTIALS = True
 
 
 
 
 
 
 
 
188
  CORS_ALLOW_HEADERS = [
189
  'accept',
190
  'accept-encoding',
@@ -196,6 +204,14 @@ CORS_ALLOW_HEADERS = [
196
  'x-csrftoken',
197
  'x-requested-with',
198
  ]
 
 
 
 
 
 
 
 
199
 
200
  # Channels Configuration (WebSockets)
201
  CHANNEL_LAYERS = {
@@ -270,15 +286,20 @@ LOGGING = {
270
 
271
  # Security Settings for Production
272
  if not DEBUG:
273
- SECURE_SSL_REDIRECT = True
 
274
  SESSION_COOKIE_SECURE = True
275
  CSRF_COOKIE_SECURE = True
276
  SECURE_BROWSER_XSS_FILTER = True
277
  SECURE_CONTENT_TYPE_NOSNIFF = True
278
- X_FRAME_OPTIONS = 'DENY'
279
  SECURE_HSTS_SECONDS = 31536000
280
  SECURE_HSTS_INCLUDE_SUBDOMAINS = True
281
  SECURE_HSTS_PRELOAD = True
 
 
 
 
282
 
283
  # Gamification Settings
284
  GAMIFICATION_POINTS = {
 
11
  # SECURITY
12
  SECRET_KEY = config('SECRET_KEY', default='django-insecure-6tmj-j5auz5kd)bda)acc0!*j+8-)knr7wsp(lqs=46$alpd5j')
13
  DEBUG = config('DEBUG', default=False, cast=bool)
14
+ ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='localhost,127.0.0.1,.hf.space').split(',')
15
 
16
  # Application definition
17
  INSTALLED_APPS = [
 
182
  # CORS Configuration
183
  CORS_ALLOWED_ORIGINS = config(
184
  'CORS_ALLOWED_ORIGINS',
185
+ default='http://localhost:3000,http://localhost:5173,http://localhost:3001,https://rinogeek-edulabfrontend.hf.space'
186
  ).split(',')
187
  CORS_ALLOW_CREDENTIALS = True
188
+ CORS_ALLOW_METHODS = [
189
+ 'DELETE',
190
+ 'GET',
191
+ 'OPTIONS',
192
+ 'PATCH',
193
+ 'POST',
194
+ 'PUT',
195
+ ]
196
  CORS_ALLOW_HEADERS = [
197
  'accept',
198
  'accept-encoding',
 
204
  'x-csrftoken',
205
  'x-requested-with',
206
  ]
207
+ # Allow preflight requests to be cached
208
+ CORS_PREFLIGHT_MAX_AGE = 86400
209
+
210
+ # CSRF Configuration - Trust frontend origins
211
+ CSRF_TRUSTED_ORIGINS = config(
212
+ 'CSRF_TRUSTED_ORIGINS',
213
+ default='http://localhost:3000,http://localhost:5173,https://rinogeek-edulabfrontend.hf.space,https://rinogeek-edulabbackend.hf.space'
214
+ ).split(',')
215
 
216
  # Channels Configuration (WebSockets)
217
  CHANNEL_LAYERS = {
 
286
 
287
  # Security Settings for Production
288
  if not DEBUG:
289
+ # Hugging Face handles SSL at the proxy level, so we don't necessarily need redirect
290
+ SECURE_SSL_REDIRECT = config('SECURE_SSL_REDIRECT', default=False, cast=bool)
291
  SESSION_COOKIE_SECURE = True
292
  CSRF_COOKIE_SECURE = True
293
  SECURE_BROWSER_XSS_FILTER = True
294
  SECURE_CONTENT_TYPE_NOSNIFF = True
295
+ X_FRAME_OPTIONS = 'ALLOWALL' # Allow HF Space to embed
296
  SECURE_HSTS_SECONDS = 31536000
297
  SECURE_HSTS_INCLUDE_SUBDOMAINS = True
298
  SECURE_HSTS_PRELOAD = True
299
+
300
+ # HF Spaces specific headers
301
+ USE_X_FORWARDED_HOST = True
302
+ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
303
 
304
  # Gamification Settings
305
  GAMIFICATION_POINTS = {
frontend/.env.production ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # ==============================================
2
+ # CONFIGURATION PRODUCTION - HUGGING FACE SPACES
3
+ # ==============================================
4
+
5
+ # API Backend URL (Hugging Face Space)
6
+ VITE_API_URL=https://rinogeek-edulabbackend.hf.space/api/
7
+
8
+ # Gemini API Key (si utilisé côté client)
9
+ GEMINI_API_KEY=AIzaSyD-hnYdbQudiK8nfFtML05Mmlo26nLzxWQ
frontend/.gitignore CHANGED
@@ -1,24 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # Logs
2
- logs
3
  *.log
4
  npm-debug.log*
5
  yarn-debug.log*
6
  yarn-error.log*
7
- pnpm-debug.log*
8
- lerna-debug.log*
9
 
10
- node_modules
11
- dist
12
- dist-ssr
13
- *.local
14
 
15
- # Editor directories and files
16
- .vscode/*
17
- !.vscode/extensions.json
18
- .idea
19
- .DS_Store
20
- *.suo
21
- *.ntvs*
22
- *.njsproj
23
- *.sln
24
- *.sw?
 
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Build output
7
+ dist/
8
+ build/
9
+
10
+ # Environment files (local only)
11
+ .env
12
+ .env.local
13
+ .env.*.local
14
+
15
+ # IDE
16
+ .idea/
17
+ .vscode/
18
+ *.swp
19
+ *.swo
20
+
21
+ # OS
22
+ .DS_Store
23
+ Thumbs.db
24
+
25
  # Logs
 
26
  *.log
27
  npm-debug.log*
28
  yarn-debug.log*
29
  yarn-error.log*
 
 
30
 
31
+ # Testing
32
+ coverage/
 
 
33
 
34
+ # Cache
35
+ .cache/
36
+ .parcel-cache/
 
 
 
 
 
 
 
frontend/Dockerfile CHANGED
@@ -1,7 +1,6 @@
1
- # Utiliser une image Node.js légère
2
- FROM node:20-slim
3
 
4
- # Définir le répertoire de travail
5
  WORKDIR /app
6
 
7
  # Copier les fichiers de package
@@ -13,8 +12,27 @@ RUN npm install
13
  # Copier le reste des fichiers du projet
14
  COPY . .
15
 
16
- # Exposer le port par défaut de Vite
17
- EXPOSE 3000
 
18
 
19
- # Lancer l'application en mode développement
20
- CMD ["npm", "run", "dev", "--", "--host"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Build stage
2
+ FROM node:20-slim AS build
3
 
 
4
  WORKDIR /app
5
 
6
  # Copier les fichiers de package
 
12
  # Copier le reste des fichiers du projet
13
  COPY . .
14
 
15
+ # Argument pour l'URL de l'API (passé lors du build ou défini ici par défaut)
16
+ ARG VITE_API_URL=https://rinogeek-edulabbackend.hf.space/api/
17
+ ENV VITE_API_URL=$VITE_API_URL
18
 
19
+ # Copier le fichier .env.production comme .env pour la production
20
+ RUN cp .env.production .env || true
21
+
22
+ # Builder l'application
23
+ RUN npm run build
24
+
25
+ # Serve stage
26
+ FROM nginx:alpine
27
+
28
+ # Copier les fichiers buildés vers nginx
29
+ COPY --from=build /app/dist /usr/share/nginx/html
30
+
31
+ # Copier une configuration nginx personnalisée pour gérer le routing SPA
32
+ COPY nginx.conf /etc/nginx/conf.d/default.conf
33
+
34
+ # Exposer le port 7860 (Hugging Face Spaces)
35
+ EXPOSE 7860
36
+
37
+ # Démarrer Nginx
38
+ CMD ["nginx", "-g", "daemon off;"]
frontend/README.md CHANGED
@@ -1,20 +1,35 @@
1
- <div align="center">
2
- <img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
3
- </div>
 
 
 
 
 
4
 
5
- # Run and deploy your AI Studio app
6
 
7
- This contains everything you need to run your app locally.
8
 
9
- View your app in AI Studio: https://ai.studio/apps/drive/1nYNrweThond9PXE0XK3nRB7R-rZlQ3Lp
10
 
11
- ## Run Locally
 
 
 
12
 
13
- **Prerequisites:** Node.js
14
 
 
 
 
 
 
15
 
16
- 1. Install dependencies:
17
- `npm install`
18
- 2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
19
- 3. Run the app:
20
- `npm run dev`
 
 
 
1
+ ---
2
+ title: EduLab Frontend
3
+ emoji: 📚
4
+ colorFrom: green
5
+ colorTo: blue
6
+ sdk: docker
7
+ app_port: 7860
8
+ ---
9
 
10
+ # EduLab Africa - Frontend
11
 
12
+ Interface utilisateur React pour la plateforme éducative EduLab Africa.
13
 
14
+ ## 🚀 Technologies
15
 
16
+ - **React 19** - Bibliothèque UI
17
+ - **Vite** - Build tool
18
+ - **TypeScript** - Typage statique
19
+ - **Nginx** - Serveur web (production)
20
 
21
+ ## ✨ Fonctionnalités
22
 
23
+ - 🎓 **Tuteur IA** - Assistant pédagogique intelligent
24
+ - 👨‍🏫 **Mentorat** - Connexion avec des mentors
25
+ - 💬 **Forum** - Questions & réponses communautaires
26
+ - 🏆 **Gamification** - Badges et points de progression
27
+ - 🎯 **Opportunités** - Bourses et stages
28
 
29
+ ## 🔗 Backend
30
+
31
+ Ce frontend est connecté au backend : [EdulabBackend](https://huggingface.co/spaces/rinogeek/EdulabBackend)
32
+
33
+ ## 👨‍💻 Développeur
34
+
35
+ Développé par **Marino ATOHOUN** pour **Hypee**
frontend/nginx.conf ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ server {
2
+ listen 7860;
3
+ server_name localhost;
4
+
5
+ location / {
6
+ root /usr/share/nginx/html;
7
+ index index.html index.htm;
8
+ try_files $uri $uri/ /index.html;
9
+ }
10
+
11
+ # Configuration pour le cache des fichiers statiques
12
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
13
+ root /usr/share/nginx/html;
14
+ expires 30d;
15
+ add_header Cache-Control "public, no-transform";
16
+ }
17
+
18
+ error_page 500 502 503 504 /50x.html;
19
+ location = /50x.html {
20
+ root /usr/share/nginx/html;
21
+ }
22
+ }
frontend/services/api.ts CHANGED
@@ -2,7 +2,7 @@ import axios from 'axios';
2
 
3
  // Configuration de l'API
4
  // Développé par Marino ATOHOUN pour Hypee
5
- const API_URL = 'http://127.0.0.1:8000/api/';
6
 
7
  const api = axios.create({
8
  baseURL: API_URL,
 
2
 
3
  // Configuration de l'API
4
  // Développé par Marino ATOHOUN pour Hypee
5
+ const API_URL = import.meta.env.VITE_API_URL || 'http://127.0.0.1:8000/api/';
6
 
7
  const api = axios.create({
8
  baseURL: API_URL,
frontend/vite.config.ts CHANGED
@@ -12,7 +12,8 @@ export default defineConfig(({ mode }) => {
12
  plugins: [react()],
13
  define: {
14
  'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
15
- 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
 
16
  },
17
  resolve: {
18
  alias: {
 
12
  plugins: [react()],
13
  define: {
14
  'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
15
+ 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
16
+ 'import.meta.env.VITE_API_URL': JSON.stringify(env.VITE_API_URL || 'https://rinogeek-edulabbackend.hf.space/api/')
17
  },
18
  resolve: {
19
  alias: {