davidegato1 commited on
Commit
af4847e
·
verified ·
1 Parent(s): fce4bd0

Je souhaite développer une application de gestion et d’exécution de **commandes de transfert d’agents**. L’objectif est de permettre à des utilisateurs de créer une commande de transfert (ou de dépôt / paiement de facture, etc.), puis de la diffuser en **temps réel** vers des clients (les *devices*) qui l’exécuteront automatiquement. Lors de la création d’une commande, l’application publie un événement via **SignalR** (ou via une API REST si nécessaire) ; les devices (smartphones Android/iOS) connectés reçoivent cet événement, traitent la commande et renvoient une confirmation d’exécution (par SignalR ou par appel d’API).

Browse files

Chaque commande contient les informations nécessaires à l’exécution :

* nom du bénéficiaire,
* montant,
* numéro de téléphone,
* type de service (dépôt, transfert, paiement de facture — électricité, autres).

Le traitement côté device est entièrement automatisé : la réception du message déclenche l’exécution et l’envoi d’un accusé de réception/confirmation vers le serveur.

Concernant l’architecture logicielle (implémentation .NET) :

* **Projet Core / Modèles** : contient les entités persistées en base (dossier `Models/Entities`).
* **Projets de Repository** : pattern Repository, chaque repository a sa propre interface. Un `IBaseRepository` générique est disponible pour les implémentations par défaut. (Dossier `Repositories`/`Interfaces`.)
* **Projet Service** : regroupe la logique métier — implémentations de services, interfaces, jobs/background services (dossier `Jobs`), ainsi que les modèles de transferts, DTOs, requests et responses (dossier `Models`).
* **Projet BackOffice** : interface utilisateur (vues, tableaux de bord, compteurs) ; dépendances sur les projets `Service` et `Core`.

Les communications en temps réel sont assurées par SignalR pour la diffusion des commandes et la réception des confirmations ; une API REST complète les scénarios (exécution par polling ou pour clients non connectés en temps réel). Les jobs côté serveur prennent en charge le traitement asynchrone, la gestion des retries et la persistance des états des commandes en utilisant hangfire.

Met en place la fonctionnalité de connection des utilisateurs avec Role.
Met en place en Seeder pour User; email: stidjani@proconsulting-info.com password: Pr@Const2007
Met en place un seeder pour role; Voici les role: Super, Cashier, Accountant, User

Il y doit avoir un dashbord bien fait avec les statistique, et un filtre par plage de date

Une page pour lister les commanndes et leur états


#### **1. Principes Clés de l'Adaptation**

1. **Utilisation de Hangfire** : La garantie de non-perte est obtenue en créant la commande et en mettant en file d'attente le job Hangfire **dans la même transaction de base de données**. Hangfire supporte ce comportement, assurant que le job n'est visible par les workers qu'après le `COMMIT` de la transaction.

2. **Rôles Clairs** :
* **API REST** : Reçoit la requête, crée la commande et le job Hangfire (transactionnel).
* **Hangfire** : Exécute le job de diffusion de manière fiable (avec des retries automatiques en cas d'échec). C'est lui qui appelle SignalR.
* **SignalR** : Canal de notification en temps réel, mais sans garantie de livraison. Le système ne dépend pas de son succès immédiat.
* **Jobs de Maintenance (Hangfire)** : Des jobs récurrents peuvent surveiller les commandes bloquées (`InProgress` depuis trop longtemps).

#### **2. Modèle de Données (DDL) Révisé**

Nous allons simplifier le schéma. La table `Outbox` disparaît. Nous fusionnons les tentatives et les résultats dans une seule table `CommandExecutions`.

```sql
-- Commands (table principale, légèrement modifiée)
CREATE TABLE Commands (
Id UUID PRIMARY KEY,
ExternalId VARCHAR(100) UNIQUE,
CreatedAt TIMESTAMP NOT NULL DEFAULT now(),
Type VARCHAR(50) NOT NULL, -- TRANSFER, DEPOSIT, BILL_PAY...
ClientName VARCHAR(255) NULL,
Amount Float NOT NULL,
Phone VARCHAR(50) NOT NULL,
CountryCode VARCHAR(5) NULL,
Status VARCHAR(20) NOT NULL DEFAULT 'Pending',-- Pending, Dispatched, InProgress, Completed, Failed, DeadLetter
AttemptCount INT NOT NULL DEFAULT 0,
MaxAttempts INT NOT NULL DEFAULT 5,
-- Colonnes pour le locking atomique
LockedByDeviceId UUID NULL,
LockedAt TIMESTAMP NULL,
-- Suivi
DispatchedAt TIMESTAMP NULL, -- Quand le job Hangfire a-t-il notifié les devices ?
ProcessedAt TIMESTAMP NULL, -- Quand le résultat final a-t-il été reçu ?
HangfireJobId VARCHAR(100) NULL, -- Lien vers le job Hangfire pour le dispatch
RowVersion BIGINT NOT NULL DEFAULT 0,
CONSTRAINT chk_status CHECK (Status IN ('Pending','Dispatched','InProgress','Completed','Failed','DeadLetter'))
);

CREATE INDEX idx_commands_status_lockedat ON Commands(Status, LockedAt);

-- CommandExecutions (fusion de CommandAttempts et CommandResults)
CREATE TABLE CommandExecutions (
Id UUID PRIMARY KEY,
CommandId UUID NOT NULL REFERENCES Commands(Id),
DeviceId UUID NULL REFERENCES Devices(Id),
ExecutedAt TIMESTAMP NOT NULL DEFAULT now(),
IsFinalAttempt BOOLEAN NOT NULL DEFAULT FALSE, -- Indique si c'est cette exécution qui a clos la commande
Success BOOLEAN NOT NULL,
ResultType VARCHAR(50), -- SUCCESS, FAILURE, TIMEOUT, CANCELED
Details JSONB NULL -- Logs, messages d'erreur, preuve d'exécution
);

-- La table CommandExecutions a maintenant une contrainte unique pour le résultat final
CREATE UNIQUE INDEX uq_commandexecutions_final ON CommandExecutions(CommandId) WHERE IsFinalAttempt = TRUE;


-- Devices (inchangée)
CREATE TABLE Devices (
Id UUID PRIMARY KEY,
Name VARCHAR(200),
Type VARCHAR(20), -- Android / iOS
LastSeen TIMESTAMP NULL
);

-- DeviceConnections (inchangée)
CREATE TABLE DeviceConnections (
ConnectionId VARCHAR(200) PRIMARY KEY,
DeviceId UUID NOT NULL REFERENCES Devices(Id),
ConnectedAt TIMESTAMP NOT NULL DEFAULT now()
);

-- DeadLetters (inchangée, toujours très utile)
CREATE TABLE DeadLetters (
Id UUID PRIMARY KEY,
CommandId UUID NOT NULL REFERENCES Commands(Id),
Reason TEXT,
CreatedAt TIMESTAMP NOT NULL DEFAULT now()
);

-- SUPPRIMÉE : La table 'Outbox' n'est plus nécessaire.
```

#### **3. Flux de Traitement de Bout en Bout (Revu avec Hangfire)**

1. **Création de la Commande (Atomique)**
* Un client appelle l'API `POST /api/commands`.
* Le service commence une transaction de base de données.
* **Étape 1 :** Il insère une nouvelle ligne dans la table `Commands` avec le statut `'Pending'`.
* **Étape 2 :** Il met en file d'attente un job Hangfire : `BackgroundJob.Enqueue<ICommandDispatcher>(dispatcher => dispatcher.DispatchCommand(commandId))`.
* **Étape 3 :** Il sauvegarde l'`Id` du job Hangfire dans la colonne `Commands.HangfireJobId`.
* La transaction est validée (`COMMIT`).
* **Garantie :** Si le `COMMIT` échoue, la commande ET le job sont annulés. Si le `COMMIT` réussit, la commande existe ET le job est garanti d'être exécuté par Hangfire. La perte de données est évitée.

2. **Dispatch de la Commande (Job Hangfire)**
* Un worker Hangfire prend en charge le job `DispatchCommand`.
* Le job récupère la commande en base (`Status = 'Pending'`).
* Il utilise le `HubContext` de SignalR pour envoyer l'événement à tous les clients connectés (ou à un groupe spécifique).
* Il met à jour le statut de la commande à `'Dispatched'` et `DispatchedAt = now()`.
* **Garantie :** Si le hub SignalR est indisponible ou qu'une erreur se produit, Hangfire réessaiera automatiquement le job selon sa politique de retry.

3. **Acquisition par un Device (Claim)**
* Les devices reçoivent la notification SignalR.
* Un (ou plusieurs) device appelle l'API `POST /api/commands/{id}/claim`.
* Le serveur exécute la **mise à jour atomique** (inchangée par rapport à la proposition 1, car c'est une excellente pratique) :
```sql
UPDATE Commands
SET Status = 'InProgress', LockedByDeviceId = @DeviceId, LockedAt = now(), AttemptCount = AttemptCount + 1
WHERE Id = @CommandId AND Status = 'Dispatched' -- Seules les commandes dispatchées peuvent être acquises
RETURNING Id;
```
* Si la requête affecte 1 ligne, le device a le "verrou" et peut procéder. Sinon, un autre l'a déjà pris.

4. **Confirmation d'Exécution**
* Le device termine son traitement.
* Il appelle `POST /api/commands/{id}/complete` avec le résultat (`success`, `details`, etc.).
* Le serveur, dans une transaction :
* Vérifie que la commande est bien en `'InProgress'` et verrouillée par ce device.
* Met à jour la commande : `Status = 'Completed'` (ou `'Failed'`), `ProcessedAt = now()`.
* Insère le résultat final dans `CommandExecutions` avec `IsFinalAttempt = TRUE`.
* **Garantie d'idempotence :** La vérification du statut `'InProgress'` et la contrainte `UNIQUE` sur `CommandExecutions(CommandId) WHERE IsFinalAttempt = TRUE` empêchent l'enregistrement de plusieurs résultats finaux.

5. **Gestion des Échecs et des Commandes Bloquées**
* **Échec de dispatch :** Géré par les retries automatiques de Hangfire.
* **Échec d'exécution (device) :** Si le device renvoie un échec, la commande passe en statut `'Failed'`. Le système peut décider de la remettre en `'Pending'` pour un nouvel essai ou de la marquer comme `DeadLetter` si `AttemptCount >= MaxAttempts`.
* **Device qui ne répond plus :** Un job récurrent Hangfire (`RecurringJob.AddOrUpdate`) s'exécute toutes les N minutes.
```csharp
// Job pour nettoyer les commandes bloquées
public void FindAndResetStalledCommands() {
var stalledCommands = db.Commands
.Where(c => c.Status == "InProgress" && c.LockedAt < DateTime.UtcNow.AddMinutes(-5)) // Ex: bloqué depuis > 5 min
.ToList();

foreach(var cmd in stalledCommands) {

Files changed (4) hide show
  1. README.md +8 -5
  2. dashboard.html +370 -0
  3. index.html +419 -18
  4. login.html +136 -0
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Transferflow Pro Command Management System
3
- emoji: 👁
4
- colorFrom: purple
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: TransferFlow Pro - Command Management System 🚀
3
+ colorFrom: pink
4
+ colorTo: blue
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
dashboard.html ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <title>Dashboard - TransferFlow Pro</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
12
+ <script>
13
+ tailwind.config = {
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#3B82F6',
18
+ secondary: '#10B981',
19
+ accent: '#8B5CF6',
20
+ dark: '#1F2937',
21
+ light: '#F9FAFB'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ </script>
27
+ <style>
28
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
29
+
30
+ body {
31
+ font-family: 'Inter', sans-serif;
32
+ }
33
+
34
+ .sidebar {
35
+ transition: all 0.3s ease;
36
+ }
37
+
38
+ .card-hover {
39
+ transition: all 0.3s ease;
40
+ }
41
+
42
+ .card-hover:hover {
43
+ transform: translateY(-5px);
44
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
45
+ }
46
+
47
+ .stat-card {
48
+ transition: all 0.3s ease;
49
+ }
50
+
51
+ .stat-card:hover {
52
+ transform: scale(1.05);
53
+ }
54
+
55
+ @media (max-width: 768px) {
56
+ .sidebar {
57
+ transform: translateX(-100%);
58
+ }
59
+
60
+ .sidebar.open {
61
+ transform: translateX(0);
62
+ }
63
+ }
64
+ </style>
65
+ </head>
66
+ <body class="bg-gray-100">
67
+ <div class="flex h-screen">
68
+ <!-- Sidebar -->
69
+ <div class="sidebar bg-white w-64 space-y-6 py-7 px-2 absolute inset-y-0 left-0 transform -translate-x-full md:relative md:translate-x-0 transition duration-200 ease-in-out z-30">
70
+ <div class="flex items-center space-x-2 px-4">
71
+ <i data-feather="send" class="text-primary h-8 w-8"></i>
72
+ <span class="text-2xl font-extrabold text-dark">TransferFlow</span>
73
+ </div>
74
+
75
+ <nav>
76
+ <a href="dashboard.html" class="block py-2.5 px-4 rounded transition duration-200 bg-primary text-white">
77
+ <i data-feather="home" class="inline-block w-5 h-5 mr-2"></i>
78
+ Dashboard
79
+ </a>
80
+ <a href="commands.html" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-100 text-gray-600">
81
+ <i data-feather="list" class="inline-block w-5 h-5 mr-2"></i>
82
+ Commands
83
+ </a>
84
+ <a href="devices.html" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-100 text-gray-600">
85
+ <i data-feather="smartphone" class="inline-block w-5 h-5 mr-2"></i>
86
+ Devices
87
+ </a>
88
+ <a href="analytics.html" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-100 text-gray-600">
89
+ <i data-feather="bar-chart-2" class="inline-block w-5 h-5 mr-2"></i>
90
+ Analytics
91
+ </a>
92
+ <a href="users.html" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-100 text-gray-600">
93
+ <i data-feather="users" class="inline-block w-5 h-5 mr-2"></i>
94
+ Users
95
+ </a>
96
+ <a href="settings.html" class="block py-2.5 px-4 rounded transition duration-200 hover:bg-gray-100 text-gray-600">
97
+ <i data-feather="settings" class="inline-block w-5 h-5 mr-2"></i>
98
+ Settings
99
+ </a>
100
+ </nav>
101
+ </div>
102
+
103
+ <!-- Main content -->
104
+ <div class="flex-1 flex flex-col overflow-hidden">
105
+ <!-- Header -->
106
+ <header class="flex items-center justify-between px-6 py-4 bg-white border-b">
107
+ <div class="flex items-center">
108
+ <button class="text-gray-500 focus:outline-none lg:hidden" id="menu-toggle">
109
+ <i data-feather="menu" class="h-6 w-6"></i>
110
+ </button>
111
+
112
+ <!-- Date Filter -->
113
+ <div class="ml-4 flex items-center space-x-4">
114
+ <span class="text-sm text-gray-600">Filter by:</span>
115
+ <div class="flex space-x-2">
116
+ <select class="border rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary">
117
+ <option>Today</option>
118
+ <option>Last 7 days</option>
119
+ <option>Last 30 days</option>
120
+ <option selected>Custom Range</option>
121
+ </select>
122
+ <input type="date" class="border rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary">
123
+ <input type="date" class="border rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-primary">
124
+ </div>
125
+ </div>
126
+ </div>
127
+
128
+ <div class="flex items-center space-x-4">
129
+ <div class="relative">
130
+ <button class="text-gray-500 focus:outline-none">
131
+ <i data-feather="bell" class="h-6 w-6"></i>
132
+ <span class="absolute top-0 right-0 h-2 w-2 rounded-full bg-red-500"></span>
133
+ </button>
134
+ </div>
135
+ <div class="relative">
136
+ <button class="flex items-center text-sm focus:outline-none">
137
+ <div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-white font-semibold">S</div>
138
+ <span class="ml-2 text-gray-700">stidjani@proconsulting-info.com</span>
139
+ <i data-feather="chevron-down" class="ml-1 h-4 w-4 text-gray-500"></i>
140
+ </button>
141
+ </div>
142
+ </div>
143
+ </header>
144
+
145
+ <!-- Main content area -->
146
+ <main class="flex-1 overflow-x-hidden overflow-y-auto bg-gray-100 p-6">
147
+ <div class="mb-6">
148
+ <h1 class="text-2xl font-semibold text-gray-800">Dashboard</h1>
149
+ <p class="text-gray-600">Welcome back! Here's what's happening with your commands today.</p>
150
+ </div>
151
+
152
+ <!-- Stats Cards -->
153
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
154
+ <div class="bg-white rounded-lg shadow stat-card p-6">
155
+ <div class="flex items-center">
156
+ <div class="p-3 rounded-full bg-blue-100 text-blue-500">
157
+ <i data-feather="send" class="h-6 w-6"></i>
158
+ </div>
159
+ <div class="ml-4">
160
+ <h2 class="text-sm font-medium text-gray-500">Total Commands</h2>
161
+ <p class="text-2xl font-semibold text-gray-700">1,234</p>
162
+ </div>
163
+ </div>
164
+ <div class="mt-4">
165
+ <div class="flex items-center text-sm text-green-500">
166
+ <i data-feather="trending-up" class="h-4 w-4 mr-1"></i>
167
+ <span>12% increase</span>
168
+ </div>
169
+ </div>
170
+ </div>
171
+
172
+ <div class="bg-white rounded-lg shadow stat-card p-6">
173
+ <div class="flex items-center">
174
+ <div class="p-3 rounded-full bg-green-100 text-green-500">
175
+ <i data-feather="check-circle" class="h-6 w-6"></i>
176
+ </div>
177
+ <div class="ml-4">
178
+ <h2 class="text-sm font-medium text-gray-500">Completed</h2>
179
+ <p class="text-2xl font-semibold text-gray-700">987</p>
180
+ </div>
181
+ </div>
182
+ <div class="mt-4">
183
+ <div class="flex items-center text-sm text-green-500">
184
+ <i data-feather="trending-up" class="h-4 w-4 mr-1"></i>
185
+ <span>8% increase</span>
186
+ </div>
187
+ </div>
188
+ </div>
189
+
190
+ <div class="bg-white rounded-lg shadow stat-card p-6">
191
+ <div class="flex items-center">
192
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-500">
193
+ <i data-feather="clock" class="h-6 w-6"></i>
194
+ </div>
195
+ <div class="ml-4">
196
+ <h2 class="text-sm font-medium text-gray-500">In Progress</h2>
197
+ <p class="text-2xl font-semibold text-gray-700">123</p>
198
+ </div>
199
+ </div>
200
+ <div class="mt-4">
201
+ <div class="flex items-center text-sm text-red-500">
202
+ <i data-feather="trending-down" class="h-4 w-4 mr-1"></i>
203
+ <span>3% decrease</span>
204
+ </div>
205
+ </div>
206
+ </div>
207
+
208
+ <div class="bg-white rounded-lg shadow stat-card p-6">
209
+ <div class="flex items-center">
210
+ <div class="p-3 rounded-full bg-purple-100 text-purple-500">
211
+ <i data-feather="smartphone" class="h-6 w-6"></i>
212
+ </div>
213
+ <div class="ml-4">
214
+ <h2 class="text-sm font-medium text-gray-500">Active Devices</h2>
215
+ <p class="text-2xl font-semibold text-gray-700">42</p>
216
+ </div>
217
+ </div>
218
+ <div class="mt-4">
219
+ <div class="flex items-center text-sm text-green-500">
220
+ <i data-feather="trending-up" class="h-4 w-4 mr-1"></i>
221
+ <span>15% increase</span>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </div>
226
+
227
+ <!-- Charts and Recent Activity -->
228
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
229
+ <!-- Command Status Chart -->
230
+ <div class="bg-white rounded-lg shadow p-6">
231
+ <h2 class="text-lg font-semibold text-gray-800 mb-4">Command Status Distribution</h2>
232
+ <div class="h-64">
233
+ <canvas id="statusChart"></canvas>
234
+ </div>
235
+ </div>
236
+
237
+ <!-- Recent Activity -->
238
+ <div class="bg-white rounded-lg shadow p-6">
239
+ <h2 class="text-lg font-semibold text-gray-800 mb-4">Recent Activity</h2>
240
+ <div class="space-y-4">
241
+ <div class="flex items-start">
242
+ <div class="flex-shrink-0">
243
+ <div class="h-8 w-8 rounded-full bg-green-100 flex items-center justify-center">
244
+ <i data-feather="check-circle" class="h-4 w-4 text-green-600"></i>
245
+ </div>
246
+ </div>
247
+ <div class="ml-3">
248
+ <p class="text-sm font-medium text-gray-900">Transfer command completed</p>
249
+ <p class="text-sm text-gray-500">Transfer of $150 to John Doe was successfully processed</p>
250
+ <p class="text-xs text-gray-400">2 minutes ago</p>
251
+ </div>
252
+ </div>
253
+ <div class="flex items-start">
254
+ <div class="flex-shrink-0">
255
+ <div class="h-8 w-8 rounded-full bg-yellow-100 flex items-center justify-center">
256
+ <i data-feather="clock" class="h-4 w-4 text-yellow-600"></i>
257
+ </div>
258
+ </div>
259
+ <div class="ml-3">
260
+ <p class="text-sm font-medium text-gray-900">Bill payment in progress</p>
261
+ <p class="text-sm text-gray-500">Electricity bill payment for account 123456 is being processed</p>
262
+ <p class="text-xs text-gray-400">5 minutes ago</p>
263
+ </div>
264
+ </div>
265
+ <div class="flex items-start">
266
+ <div class="flex-shrink-0">
267
+ <div class="h-8 w-8 rounded-full bg-blue-100 flex items-center justify-center">
268
+ <i data-feather="send" class="h-4 w-4 text-blue-600"></i>
269
+ </div>
270
+ </div>
271
+ <div class="ml-3">
272
+ <p class="text-sm font-medium text-gray-900">New transfer command</p>
273
+ <p class="text-sm text-gray-500">New transfer of $200 to Jane Smith has been created</p>
274
+ <p class="text-xs text-gray-400">10 minutes ago</p>
275
+ </div>
276
+ </div>
277
+ <div class="flex items-start">
278
+ <div class="flex-shrink-0">
279
+ <div class="h-8 w-8 rounded-full bg-red-100 flex items-center justify-center">
280
+ <i data-feather="x-circle" class="h-4 w-4 text-red-600"></i>
281
+ </div>
282
+ </div>
283
+ <div class="ml-3">
284
+ <p class="text-sm font-medium text-gray-900">Command failed</p>
285
+ <p class="text-sm text-gray-500">Deposit command failed due to insufficient funds</p>
286
+ <p class="text-xs text-gray-400">15 minutes ago</p>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ </div>
291
+ </div>
292
+
293
+ <!-- Command Types Breakdown -->
294
+ <div class="mt-6 bg-white rounded-lg shadow p-6">
295
+ <h2 class="text-lg font-semibold text-gray-800 mb-4">Command Types Breakdown</h2>
296
+ <div class="h-64">
297
+ <canvas id="typeChart"></canvas>
298
+ </div>
299
+ </div>
300
+ </main>
301
+ </div>
302
+ </div>
303
+
304
+ <script>
305
+ // Initialize Feather icons
306
+ feather.replace();
307
+
308
+ // Mobile menu toggle
309
+ document.getElementById('menu-toggle').addEventListener('click', function() {
310
+ document.querySelector('.sidebar').classList.toggle('open');
311
+ });
312
+
313
+ // Initialize charts
314
+ document.addEventListener('DOMContentLoaded', function() {
315
+ // Command Status Chart
316
+ const statusCtx = document.getElementById('statusChart').getContext('2d');
317
+ const statusChart = new Chart(statusCtx, {
318
+ type: 'doughnut',
319
+ data: {
320
+ labels: ['Completed', 'In Progress', 'Pending', 'Failed'],
321
+ datasets: [{
322
+ data: [65, 15, 15, 5],
323
+ backgroundColor: [
324
+ '#10B981',
325
+ '#F59E0B',
326
+ '#3B82F6',
327
+ '#EF4444'
328
+ ],
329
+ borderWidth: 0
330
+ }]
331
+ },
332
+ options: {
333
+ responsive: true,
334
+ maintainAspectRatio: false,
335
+ plugins: {
336
+ legend: {
337
+ position: 'bottom'
338
+ }
339
+ }
340
+ }
341
+ });
342
+
343
+ // Command Types Chart
344
+ const typeCtx = document.getElementById('typeChart').getContext('2d');
345
+ const typeChart = new Chart(typeCtx, {
346
+ type: 'bar',
347
+ data: {
348
+ labels: ['Transfer', 'Deposit', 'Bill Payment', 'Other'],
349
+ datasets: [{
350
+ label: 'Count',
351
+ data: [65, 59, 80, 30],
352
+ backgroundColor: '#3B82F6',
353
+ borderColor: '#3B82F6',
354
+ borderWidth: 1
355
+ }]
356
+ },
357
+ options: {
358
+ responsive: true,
359
+ maintainAspectRatio: false,
360
+ scales: {
361
+ y: {
362
+ beginAtZero: true
363
+ }
364
+ }
365
+ }
366
+ });
367
+ });
368
+ </script>
369
+ </body>
370
+ </html>
index.html CHANGED
@@ -1,19 +1,420 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
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
+ <title>TransferFlow Pro - Command Management System</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
12
+ <script>
13
+ tailwind.config = {
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#3B82F6',
18
+ secondary: '#10B981',
19
+ accent: '#8B5CF6',
20
+ dark: '#1F2937',
21
+ light: '#F9FAFB'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ </script>
27
+ <style>
28
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
29
+
30
+ body {
31
+ font-family: 'Inter', sans-serif;
32
+ }
33
+
34
+ .gradient-bg {
35
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
36
+ }
37
+
38
+ .card-hover {
39
+ transition: all 0.3s ease;
40
+ }
41
+
42
+ .card-hover:hover {
43
+ transform: translateY(-5px);
44
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
45
+ }
46
+
47
+ .stat-card {
48
+ transition: all 0.3s ease;
49
+ }
50
+
51
+ .stat-card:hover {
52
+ transform: scale(1.05);
53
+ }
54
+ </style>
55
+ </head>
56
+ <body class="bg-light">
57
+ <!-- Navigation -->
58
+ <nav class="bg-white shadow-sm sticky top-0 z-50">
59
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
60
+ <div class="flex justify-between h-16">
61
+ <div class="flex items-center">
62
+ <div class="flex-shrink-0 flex items-center">
63
+ <i data-feather="send" class="text-primary h-8 w-8"></i>
64
+ <span class="ml-2 text-xl font-bold text-dark">TransferFlow Pro</span>
65
+ </div>
66
+ <div class="hidden sm:ml-6 sm:flex sm:space-x-8">
67
+ <a href="#" class="border-primary text-dark inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Dashboard</a>
68
+ <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Commands</a>
69
+ <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Analytics</a>
70
+ <a href="#" class="border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium">Devices</a>
71
+ </div>
72
+ </div>
73
+ <div class="hidden sm:ml-6 sm:flex sm:items-center">
74
+ <div class="ml-3 relative">
75
+ <div>
76
+ <button type="button" class="bg-white rounded-full flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary" id="user-menu-button" aria-expanded="false" aria-haspopup="true">
77
+ <span class="sr-only">Open user menu</span>
78
+ <div class="h-8 w-8 rounded-full bg-primary flex items-center justify-center text-white font-semibold">S</div>
79
+ </button>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ <div class="-mr-2 flex items-center sm:hidden">
84
+ <button type="button" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-primary" aria-controls="mobile-menu" aria-expanded="false">
85
+ <span class="sr-only">Open main menu</span>
86
+ <i data-feather="menu" class="block h-6 w-6"></i>
87
+ <i data-feather="x" class="hidden h-6 w-6"></i>
88
+ </button>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- Mobile menu, show/hide based on menu state. -->
94
+ <div class="sm:hidden hidden" id="mobile-menu">
95
+ <div class="pt-2 pb-3 space-y-1">
96
+ <a href="#" class="bg-primary bg-opacity-10 border-primary text-dark block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Dashboard</a>
97
+ <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Commands</a>
98
+ <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Analytics</a>
99
+ <a href="#" class="border-transparent text-gray-500 hover:bg-gray-50 hover:border-gray-300 hover:text-gray-700 block pl-3 pr-4 py-2 border-l-4 text-base font-medium">Devices</a>
100
+ </div>
101
+ <div class="pt-4 pb-3 border-t border-gray-200">
102
+ <div class="flex items-center px-4">
103
+ <div class="flex-shrink-0">
104
+ <div class="h-10 w-10 rounded-full bg-primary flex items-center justify-center text-white font-semibold">S</div>
105
+ </div>
106
+ <div class="ml-3">
107
+ <div class="text-base font-medium text-gray-800">stidjani@proconsulting-info.com</div>
108
+ <div class="text-sm font-medium text-gray-500">Super Admin</div>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ </nav>
114
+
115
+ <!-- Hero Section -->
116
+ <div class="relative gradient-bg overflow-hidden">
117
+ <div class="max-w-7xl mx-auto">
118
+ <div class="relative z-10 pb-8 bg-transparent sm:pb-16 md:pb-20 lg:max-w-2xl lg:w-full lg:pb-28 xl:pb-32">
119
+ <svg class="hidden lg:block absolute right-0 inset-y-0 h-full w-48 text-white transform translate-x-1/2" fill="currentColor" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
120
+ <polygon points="50,0 100,0 50,100 0,100" />
121
+ </svg>
122
+
123
+ <div class="pt-10 mx-auto max-w-7xl px-4 sm:pt-12 sm:px-6 md:pt-16 lg:pt-20 lg:px-8 xl:pt-28">
124
+ <div class="sm:text-center lg:text-left">
125
+ <h1 class="text-4xl tracking-tight font-extrabold text-white sm:text-5xl md:text-6xl">
126
+ <span class="block">Manage Transfer</span>
127
+ <span class="block text-accent">Commands Efficiently</span>
128
+ </h1>
129
+ <p class="mt-3 text-base text-gray-200 sm:mt-5 sm:text-lg sm:max-w-xl sm:mx-auto md:mt-5 md:text-xl lg:mx-0">
130
+ TransferFlow Pro enables real-time command distribution and execution tracking for seamless money transfer operations across multiple devices.
131
+ </p>
132
+ <div class="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
133
+ <div class="rounded-md shadow">
134
+ <a href="#" class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-primary hover:bg-blue-700 md:py-4 md:text-lg md:px-10">
135
+ Get Started
136
+ </a>
137
+ </div>
138
+ <div class="mt-3 sm:mt-0 sm:ml-3">
139
+ <a href="#" class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-primary bg-white hover:bg-gray-50 md:py-4 md:text-lg md:px-10">
140
+ Live Demo
141
+ </a>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ <div class="lg:absolute lg:inset-y-0 lg:right-0 lg:w-1/2">
149
+ <div id="vanta-globe" class="h-56 w-full bg-transparent sm:h-72 md:h-96 lg:w-full lg:h-full"></div>
150
+ </div>
151
+ </div>
152
+
153
+ <!-- Stats Section -->
154
+ <div class="relative bg-white py-12 sm:py-16 lg:py-20">
155
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
156
+ <div class="max-w-4xl mx-auto text-center">
157
+ <h2 class="text-3xl font-extrabold text-dark sm:text-4xl">
158
+ Real-time Command Management
159
+ </h2>
160
+ <p class="mt-3 text-xl text-gray-500 sm:mt-4">
161
+ Track and manage your transfer commands with our advanced real-time system.
162
+ </p>
163
+ </div>
164
+ <div class="mt-10">
165
+ <div class="grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-4">
166
+ <!-- Card 1 -->
167
+ <div class="bg-white overflow-hidden shadow rounded-lg stat-card">
168
+ <div class="p-5">
169
+ <div class="flex items-center">
170
+ <div class="flex-shrink-0">
171
+ <i data-feather="send" class="h-6 w-6 text-primary"></i>
172
+ </div>
173
+ <div class="ml-5 w-0 flex-1">
174
+ <dl>
175
+ <dt class="text-sm font-medium text-gray-500 truncate">Total Commands</dt>
176
+ <dd>
177
+ <div class="text-lg font-medium text-gray-900">1,234</div>
178
+ </dd>
179
+ </dl>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ <div class="bg-gray-50 px-5 py-3">
184
+ <div class="text-sm">
185
+ <span class="text-green-600 font-medium">+12% </span>
186
+ <span class="text-gray-500">from last month</span>
187
+ </div>
188
+ </div>
189
+ </div>
190
+
191
+ <!-- Card 2 -->
192
+ <div class="bg-white overflow-hidden shadow rounded-lg stat-card">
193
+ <div class="p-5">
194
+ <div class="flex items-center">
195
+ <div class="flex-shrink-0">
196
+ <i data-feather="check-circle" class="h-6 w-6 text-green-500"></i>
197
+ </div>
198
+ <div class="ml-5 w-0 flex-1">
199
+ <dl>
200
+ <dt class="text-sm font-medium text-gray-500 truncate">Completed</dt>
201
+ <dd>
202
+ <div class="text-lg font-medium text-gray-900">987</div>
203
+ </dd>
204
+ </dl>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ <div class="bg-gray-50 px-5 py-3">
209
+ <div class="text-sm">
210
+ <span class="text-green-600 font-medium">+8% </span>
211
+ <span class="text-gray-500">from last month</span>
212
+ </div>
213
+ </div>
214
+ </div>
215
+
216
+ <!-- Card 3 -->
217
+ <div class="bg-white overflow-hidden shadow rounded-lg stat-card">
218
+ <div class="p-5">
219
+ <div class="flex items-center">
220
+ <div class="flex-shrink-0">
221
+ <i data-feather="clock" class="h-6 w-6 text-yellow-500"></i>
222
+ </div>
223
+ <div class="ml-5 w-0 flex-1">
224
+ <dl>
225
+ <dt class="text-sm font-medium text-gray-500 truncate">In Progress</dt>
226
+ <dd>
227
+ <div class="text-lg font-medium text-gray-900">123</div>
228
+ </dd>
229
+ </dl>
230
+ </div>
231
+ </div>
232
+ </div>
233
+ <div class="bg-gray-50 px-5 py-3">
234
+ <div class="text-sm">
235
+ <span class="text-red-600 font-medium">-3% </span>
236
+ <span class="text-gray-500">from last month</span>
237
+ </div>
238
+ </div>
239
+ </div>
240
+
241
+ <!-- Card 4 -->
242
+ <div class="bg-white overflow-hidden shadow rounded-lg stat-card">
243
+ <div class="p-5">
244
+ <div class="flex items-center">
245
+ <div class="flex-shrink-0">
246
+ <i data-feather="smartphone" class="h-6 w-6 text-secondary"></i>
247
+ </div>
248
+ <div class="ml-5 w-0 flex-1">
249
+ <dl>
250
+ <dt class="text-sm font-medium text-gray-500 truncate">Active Devices</dt>
251
+ <dd>
252
+ <div class="text-lg font-medium text-gray-900">42</div>
253
+ </dd>
254
+ </dl>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ <div class="bg-gray-50 px-5 py-3">
259
+ <div class="text-sm">
260
+ <span class="text-green-600 font-medium">+15% </span>
261
+ <span class="text-gray-500">from last month</span>
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </div>
267
+ </div>
268
+ </div>
269
+
270
+ <!-- Features Section -->
271
+ <div class="py-12 bg-gray-50">
272
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
273
+ <div class="lg:text-center">
274
+ <h2 class="text-base text-primary font-semibold tracking-wide uppercase">Features</h2>
275
+ <p class="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-dark sm:text-4xl">
276
+ A better way to manage transfers
277
+ </p>
278
+ <p class="mt-4 max-w-2xl text-xl text-gray-500 lg:mx-auto">
279
+ TransferFlow Pro provides seamless integration between command creation and device execution with real-time tracking.
280
+ </p>
281
+ </div>
282
+
283
+ <div class="mt-10">
284
+ <div class="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10">
285
+ <div class="card-hover bg-white p-6 rounded-lg shadow">
286
+ <div class="flex items-center justify-center h-12 w-12 rounded-md bg-primary text-white">
287
+ <i data-feather="zap" class="h-6 w-6"></i>
288
+ </div>
289
+ <div class="mt-5">
290
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Real-time Distribution</h3>
291
+ <p class="mt-2 text-base text-gray-500">
292
+ Commands are distributed instantly to connected devices via SignalR, ensuring minimal latency in execution.
293
+ </p>
294
+ </div>
295
+ </div>
296
+
297
+ <div class="card-hover bg-white p-6 rounded-lg shadow">
298
+ <div class="flex items-center justify-center h-12 w-12 rounded-md bg-secondary text-white">
299
+ <i data-feather="shield" class="h-6 w-6"></i>
300
+ </div>
301
+ <div class="mt-5">
302
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Secure Execution</h3>
303
+ <p class="mt-2 text-base text-gray-500">
304
+ Each command is securely processed with device authentication and execution confirmation.
305
+ </p>
306
+ </div>
307
+ </div>
308
+
309
+ <div class="card-hover bg-white p-6 rounded-lg shadow">
310
+ <div class="flex items-center justify-center h-12 w-12 rounded-md bg-accent text-white">
311
+ <i data-feather="trending-up" class="h-6 w-6"></i>
312
+ </div>
313
+ <div class="mt-5">
314
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Performance Analytics</h3>
315
+ <p class="mt-2 text-base text-gray-500">
316
+ Track command execution times, success rates, and device performance with detailed analytics.
317
+ </p>
318
+ </div>
319
+ </div>
320
+
321
+ <div class="card-hover bg-white p-6 rounded-lg shadow">
322
+ <div class="flex items-center justify-center h-12 w-12 rounded-md bg-purple-500 text-white">
323
+ <i data-feather="repeat" class="h-6 w-6"></i>
324
+ </div>
325
+ <div class="mt-5">
326
+ <h3 class="text-lg leading-6 font-medium text-gray-900">Automatic Retry System</h3>
327
+ <p class="mt-2 text-base text-gray-500">
328
+ Failed commands are automatically retried with configurable retry policies and dead letter handling.
329
+ </p>
330
+ </div>
331
+ </div>
332
+ </div>
333
+ </div>
334
+ </div>
335
+ </div>
336
+
337
+ <!-- CTA Section -->
338
+ <div class="bg-primary">
339
+ <div class="max-w-7xl mx-auto py-12 px-4 sm:px-6 lg:py-16 lg:px-8 lg:flex lg:items-center lg:justify-between">
340
+ <h2 class="text-3xl font-extrabold tracking-tight text-white sm:text-4xl">
341
+ <span class="block">Ready to get started?</span>
342
+ <span class="block text-accent">Start managing your transfer commands today.</span>
343
+ </h2>
344
+ <div class="mt-8 flex lg:mt-0 lg:flex-shrink-0">
345
+ <div class="inline-flex rounded-md shadow">
346
+ <a href="#" class="inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-primary bg-white hover:bg-gray-50">
347
+ Get started
348
+ </a>
349
+ </div>
350
+ <div class="ml-3 inline-flex rounded-md shadow">
351
+ <a href="#" class="inline-flex items-center justify-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-primary bg-opacity-20 hover:bg-opacity-30">
352
+ Contact sales
353
+ </a>
354
+ </div>
355
+ </div>
356
+ </div>
357
+ </div>
358
+
359
+ <!-- Footer -->
360
+ <footer class="bg-dark">
361
+ <div class="max-w-7xl mx-auto py-12 px-4 sm:px-6 md:flex md:items-center md:justify-between lg:px-8">
362
+ <div class="flex justify-center space-x-6 md:order-2">
363
+ <a href="#" class="text-gray-400 hover:text-gray-300">
364
+ <span class="sr-only">Facebook</span>
365
+ <i data-feather="facebook" class="h-6 w-6"></i>
366
+ </a>
367
+ <a href="#" class="text-gray-400 hover:text-gray-300">
368
+ <span class="sr-only">Twitter</span>
369
+ <i data-feather="twitter" class="h-6 w-6"></i>
370
+ </a>
371
+ <a href="#" class="text-gray-400 hover:text-gray-300">
372
+ <span class="sr-only">GitHub</span>
373
+ <i data-feather="github" class="h-6 w-6"></i>
374
+ </a>
375
+ </div>
376
+ <div class="mt-8 md:mt-0 md:order-1">
377
+ <p class="text-center text-base text-gray-400">
378
+ &copy; 2023 TransferFlow Pro. All rights reserved.
379
+ </p>
380
+ </div>
381
+ </div>
382
+ </footer>
383
+
384
+ <script>
385
+ // Initialize Vanta.js globe animation
386
+ VANTA.GLOBE({
387
+ el: "#vanta-globe",
388
+ mouseControls: true,
389
+ touchControls: true,
390
+ gyroControls: false,
391
+ minHeight: 200.00,
392
+ minWidth: 200.00,
393
+ scale: 1.00,
394
+ scaleMobile: 1.00,
395
+ color: 0x3b82f6,
396
+ color2: 0x8b5cf6,
397
+ size: 1.00,
398
+ backgroundColor: 0x667eea
399
+ });
400
+
401
+ // Initialize Feather icons
402
+ feather.replace();
403
+
404
+ // Mobile menu toggle
405
+ document.querySelector('[aria-controls="mobile-menu"]').addEventListener('click', function() {
406
+ const menu = document.getElementById('mobile-menu');
407
+ menu.classList.toggle('hidden');
408
+
409
+ const menuIcon = this.querySelector('i[data-feather="menu"]');
410
+ const closeIcon = this.querySelector('i[data-feather="x"]');
411
+
412
+ menuIcon.classList.toggle('hidden');
413
+ closeIcon.classList.toggle('hidden');
414
+
415
+ // Re-initialize icons after toggle
416
+ feather.replace();
417
+ });
418
+ </script>
419
+ </body>
420
  </html>
login.html ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <title>Login - TransferFlow Pro</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script>
12
+ tailwind.config = {
13
+ theme: {
14
+ extend: {
15
+ colors: {
16
+ primary: '#3B82F6',
17
+ secondary: '#10B981',
18
+ accent: '#8B5CF6',
19
+ dark: '#1F2937',
20
+ light: '#F9FAFB'
21
+ }
22
+ }
23
+ }
24
+ }
25
+ </script>
26
+ <style>
27
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
28
+
29
+ body {
30
+ font-family: 'Inter', sans-serif;
31
+ }
32
+
33
+ .gradient-bg {
34
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
35
+ }
36
+
37
+ .login-card {
38
+ backdrop-filter: blur(10px);
39
+ background: rgba(255, 255, 255, 0.1);
40
+ }
41
+ </style>
42
+ </head>
43
+ <body class="gradient-bg min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
44
+ <div class="max-w-md w-full space-y-8">
45
+ <div>
46
+ <div class="mx-auto h-12 w-12 flex items-center justify-center rounded-full bg-white">
47
+ <i data-feather="send" class="text-primary h-8 w-8"></i>
48
+ </div>
49
+ <h2 class="mt-6 text-center text-3xl font-extrabold text-white">
50
+ Sign in to your account
51
+ </h2>
52
+ <p class="mt-2 text-center text-sm text-gray-200">
53
+ Or
54
+ <a href="#" class="font-medium text-accent hover:text-purple-300">
55
+ start your 14-day free trial
56
+ </a>
57
+ </p>
58
+ </div>
59
+ <form class="mt-8 space-y-6 login-card p-8 rounded-2xl shadow-2xl" action="#" method="POST">
60
+ <input type="hidden" name="remember" value="true">
61
+ <div class="rounded-md shadow-sm -space-y-px">
62
+ <div>
63
+ <label for="email-address" class="sr-only">Email address</label>
64
+ <input id="email-address" name="email" type="email" autocomplete="email" required class="relative block w-full px-3 py-3 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-t-md focus:outline-none focus:ring-primary focus:border-primary focus:z-10 sm:text-sm" placeholder="Email address" value="stidjani@proconsulting-info.com">
65
+ </div>
66
+ <div>
67
+ <label for="password" class="sr-only">Password</label>
68
+ <input id="password" name="password" type="password" autocomplete="current-password" required class="relative block w-full px-3 py-3 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-primary focus:border-primary focus:z-10 sm:text-sm" placeholder="Password" value="Pr@Const2007">
69
+ </div>
70
+ </div>
71
+
72
+ <div class="flex items-center justify-between">
73
+ <div class="flex items-center">
74
+ <input id="remember-me" name="remember-me" type="checkbox" class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
75
+ <label for="remember-me" class="ml-2 block text-sm text-white">
76
+ Remember me
77
+ </label>
78
+ </div>
79
+
80
+ <div class="text-sm">
81
+ <a href="#" class="font-medium text-accent hover:text-purple-300">
82
+ Forgot your password?
83
+ </a>
84
+ </div>
85
+ </div>
86
+
87
+ <div>
88
+ <button type="submit" class="group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-primary hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition-all duration-300">
89
+ <span class="absolute left-0 inset-y-0 flex items-center pl-3">
90
+ <i data-feather="lock" class="h-5 w-5 text-blue-300 group-hover:text-blue-200"></i>
91
+ </span>
92
+ Sign in
93
+ </button>
94
+ </div>
95
+
96
+ <div class="mt-6">
97
+ <div class="relative">
98
+ <div class="absolute inset-0 flex items-center">
99
+ <div class="w-full border-t border-gray-300"></div>
100
+ </div>
101
+ <div class="relative flex justify-center text-sm">
102
+ <span class="px-2 bg-transparent text-white">Or continue with</span>
103
+ </div>
104
+ </div>
105
+
106
+ <div class="mt-6 grid grid-cols-3 gap-3">
107
+ <div>
108
+ <a href="#" class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
109
+ <span class="sr-only">Sign in with Facebook</span>
110
+ <i data-feather="facebook" class="h-5 w-5 text-blue-600"></i>
111
+ </a>
112
+ </div>
113
+
114
+ <div>
115
+ <a href="#" class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
116
+ <span class="sr-only">Sign in with Twitter</span>
117
+ <i data-feather="twitter" class="h-5 w-5 text-blue-400"></i>
118
+ </a>
119
+ </div>
120
+
121
+ <div>
122
+ <a href="#" class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-500 hover:bg-gray-50">
123
+ <span class="sr-only">Sign in with GitHub</span>
124
+ <i data-feather="github" class="h-5 w-5 text-gray-800"></i>
125
+ </a>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </form>
130
+ </div>
131
+
132
+ <script>
133
+ feather.replace();
134
+ </script>
135
+ </body>
136
+ </html>