almortamoh commited on
Commit
9db7576
·
verified ·
1 Parent(s): 2ee33e8

Upload 36 files

Browse files
.gitignore ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+
9
+ # Runtime data
10
+ pids
11
+ *.pid
12
+ *.seed
13
+ *.pid.lock
14
+
15
+ # Directory for instrumented libs generated by jscoverage/JSCover
16
+ lib-cov
17
+
18
+ # Coverage directory used by tools like istanbul
19
+ coverage
20
+ *.lcov
21
+
22
+ # nyc test coverage
23
+ .nyc_output
24
+
25
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
26
+ .grunt
27
+
28
+ # Bower dependency directory (https://bower.io/)
29
+ bower_components
30
+
31
+ # node-waf configuration
32
+ .lock-wscript
33
+
34
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
35
+ build/Release
36
+
37
+ # Dependency directories
38
+ node_modules/
39
+ jspm_packages/
40
+
41
+ # TypeScript v1 declaration files
42
+ typings/
43
+
44
+ # TypeScript cache
45
+ *.tsbuildinfo
46
+
47
+ # Optional npm cache directory
48
+ .npm
49
+
50
+ # Optional eslint cache
51
+ .eslintcache
52
+
53
+ # Microbundle cache
54
+ .rpt2_cache/
55
+ .rts2_cache_cjs/
56
+ .rts2_cache_es/
57
+ .rts2_cache_umd/
58
+
59
+ # Optional REPL history
60
+ .node_repl_history
61
+
62
+ # Output of 'npm pack'
63
+ *.tgz
64
+
65
+ # Yarn Integrity file
66
+ .yarn-integrity
67
+
68
+ # dotenv environment variables file
69
+ .env
70
+ .env.test
71
+
72
+ # parcel-bundler cache (https://parceljs.org/)
73
+ .cache
74
+ .parcel-cache
75
+
76
+ # Next.js build output
77
+ .next
78
+
79
+ # Nuxt.js build / generate output
80
+ .nuxt
81
+ dist
82
+
83
+ # Gatsby files
84
+ .cache/
85
+ # Comment in the public line in if your project uses Gatsby and *not* Next.js
86
+ # https://nextjs.org/blog/next-9-1#public-directory-support
87
+ # public
88
+
89
+ # vuepress build output
90
+ .vuepress/dist
91
+
92
+ # Serverless directories
93
+ .serverless/
94
+
95
+ # FuseBox cache
96
+ .fusebox/
97
+
98
+ # DynamoDB Local files
99
+ .dynamodb/
100
+
101
+ # TernJS port file
102
+ .tern-port
103
+
104
+ # Capacitor
105
+ .capacitor/
106
+ capacitor.config.json
107
+
108
+ # Android
109
+ android/app/build/
110
+ android/build/
111
+ android/.gradle/
112
+ android/local.properties
113
+ android/app/release/
114
+ android/app/debug/
115
+ android/gradle/
116
+ android/gradlew
117
+ android/gradlew.bat
118
+
119
+ # iOS
120
+ ios/build/
121
+ ios/App/Pods/
122
+ ios/App/App.xcworkspace/xcuserdata/
123
+ ios/App/App.xcodeproj/xcuserdata/
124
+ ios/App/App.xcodeproj/project.xcworkspace/xcuserdata/
125
+
126
+ # Editor directories and files
127
+ .vscode/
128
+ .idea/
129
+ *.swp
130
+ *.swo
131
+ *~
132
+
133
+ # OS generated files
134
+ .DS_Store
135
+ .DS_Store?
136
+ ._*
137
+ .Spotlight-V100
138
+ .Trashes
139
+ ehthumbs.db
140
+ Thumbs.db
141
+
142
+ # Local development
143
+ *.local
144
+
145
+ # Build outputs
146
+ build/
147
+ dist/
148
+ www/build/
149
+
150
+ # Temporary files
151
+ tmp/
152
+ temp/
ANDROID_STUDIO_GUIDE.md ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📱 دليل بناء APK باستخدام Android Studio
2
+
3
+ ## 🎯 **الهدف:** تحويل المشروع إلى ملف APK قابل للتثبيت
4
+
5
+ ---
6
+
7
+ ## 📋 **الخطوات المفصلة:**
8
+
9
+ ### **الخطوة 1: فتح المشروع** ⏱️ (2-3 دقائق)
10
+
11
+ 1. **افتح Android Studio**
12
+ 2. **اختر "Open an Existing Project"** أو **"Open"**
13
+ 3. **انتقل إلى مجلد المشروع:**
14
+ ```
15
+ E:\almada\android
16
+ ```
17
+ 4. **اختر مجلد `android`** (وليس المجلد الرئيسي)
18
+ 5. **اضغط "OK"**
19
+
20
+ ### **الخطوة 2: انتظار المزامنة** ⏱️ (5-10 دقائق)
21
+
22
+ عند فتح المشروع لأول مرة، سيقوم Android Studio بـ:
23
+ - 📥 **تحميل Gradle** (إذا لم يكن مثبت)
24
+ - 📦 **تحميل التبعيات** (Dependencies)
25
+ - 🔄 **مزامنة المشروع** (Sync)
26
+
27
+ **انتظر حتى تكتمل العملية!** ستظهر رسالة في الأسفل:
28
+ ```
29
+ ✅ Gradle sync finished
30
+ ```
31
+
32
+ ### **الخطوة 3: حل المشاكل المحتملة** ⏱️ (2-5 دقائق)
33
+
34
+ إذا ظهرت أي رسائل خطأ:
35
+
36
+ #### **مشكلة SDK:**
37
+ ```
38
+ SDK location not found
39
+ ```
40
+ **الحل:**
41
+ - اذهب إلى **File > Project Structure**
42
+ - اختر **SDK Location**
43
+ - تأكد من مسار Android SDK
44
+
45
+ #### **مشكلة Gradle:**
46
+ ```
47
+ Gradle version not supported
48
+ ```
49
+ **الحل:**
50
+ - اضغط على **"Update Gradle"** في الرسالة
51
+ - أو اذهب إلى **File > Project Structure > Project**
52
+
53
+ ### **الخطوة 4: بناء APK** ⏱️ (3-5 دقائق)
54
+
55
+ 1. **في شريط القوائم، اختر:**
56
+ ```
57
+ Build > Build Bundle(s) / APK(s) > Build APK(s)
58
+ ```
59
+
60
+ 2. **انتظر اكتمال البناء** - ستظهر رسالة في الأسفل:
61
+ ```
62
+ ⏳ Building APK...
63
+ ✅ APK(s) generated successfully
64
+ ```
65
+
66
+ 3. **عند اكتمال البناء، ستظهر نافذة:**
67
+ ```
68
+ APK(s) generated successfully.
69
+
70
+ [locate] [analyze]
71
+ ```
72
+
73
+ 4. **اضغط "locate"** للذهاب إلى مجلد APK
74
+
75
+ ### **الخطوة 5: العثور على ملف APK** ⏱️ (1 دقيقة)
76
+
77
+ ملف APK سيكون في:
78
+ ```
79
+ E:\almada\android\app\build\outputs\apk\debug\app-debug.apk
80
+ ```
81
+
82
+ **معلومات الملف:**
83
+ - **الاسم:** `app-debug.apk`
84
+ - **الحجم:** ~15-20 MB
85
+ - **النوع:** Debug APK (للاختبار)
86
+
87
+ ---
88
+
89
+ ## 🔧 **استكشاف الأخطاء:**
90
+
91
+ ### **خطأ: "SDK not found"**
92
+ ```bash
93
+ # الحل:
94
+ 1. اذهب إلى File > Settings
95
+ 2. اختر Appearance & Behavior > System Settings > Android SDK
96
+ 3. تأكد من تثبيت Android SDK
97
+ ```
98
+
99
+ ### **خطأ: "Gradle sync failed"**
100
+ ```bash
101
+ # الحل:
102
+ 1. اضغط "Try Again"
103
+ 2. أو اذهب إلى File > Sync Project with Gradle Files
104
+ ```
105
+
106
+ ### **خطأ: "Build failed"**
107
+ ```bash
108
+ # الحل:
109
+ 1. اذهب إلى Build > Clean Project
110
+ 2. ثم Build > Rebuild Project
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 📱 **اختبار التطبيق:**
116
+
117
+ ### **الطريقة 1: على الكمبيوتر (محاكي)**
118
+ 1. **إنشاء محاكي:**
119
+ - اذهب إلى **Tools > AVD Manager**
120
+ - اضغط **"Create Virtual Device"**
121
+ - اختر جهاز (مثل Pixel 4)
122
+ - اختر نظام Android (API 30+)
123
+
124
+ 2. **تشغيل التطبيق:**
125
+ - اضغط **Run** (الزر الأخضر)
126
+ - اختر المحاكي
127
+ - انتظر تشغيل التطبيق
128
+
129
+ ### **الطريقة 2: على الهاتف الحقيقي**
130
+ 1. **تفعيل Developer Options:**
131
+ - اذهب إلى **Settings > About Phone**
132
+ - اضغط على **Build Number** 7 مرات
133
+ - ارجع إلى Settings وادخل **Developer Options**
134
+ - فعل **USB Debugging**
135
+
136
+ 2. **توصيل الهاتف:**
137
+ - وصل الهاتف بـ USB
138
+ - اختر **File Transfer** في الهاتف
139
+ - في Android Studio، اختر جهازك من القائمة
140
+ - اضغط **Run**
141
+
142
+ ### **الطريقة 3: تثبيت APK يدوياً**
143
+ 1. **نسخ APK إلى الهاتف**
144
+ 2. **في الهاتف:**
145
+ - اذهب إلى **Settings > Security**
146
+ - فعل **"Install from Unknown Sources"**
147
+ - افتح ملف APK واضغط **Install**
148
+
149
+ ---
150
+
151
+ ## 🎯 **بيانات التجربة:**
152
+
153
+ بعد تثبيت التطبيق، استخدم:
154
+ - **رقم الهاتف:** `777123456`
155
+ - **رمز PIN:** `1234`
156
+
157
+ ---
158
+
159
+ ## 📊 **معلومات التطبيق:**
160
+
161
+ | المعلومة | القيمة |
162
+ |---------|--------|
163
+ | **اسم التطبيق** | محفظتي الموحدة |
164
+ | **Package Name** | com.almada.unifiedwallet |
165
+ | **الإصدار** | 1.0.0 |
166
+ | **حجم APK** | ~15-20 MB |
167
+ | **الحد الأدنى** | Android 7.0 (API 24) |
168
+
169
+ ---
170
+
171
+ ## 🎉 **النجاح!**
172
+
173
+ عند اكتمال جميع الخطوات، ستحصل على:
174
+ - ✅ **ملف APK** جاهز للتثبيت
175
+ - ✅ **تطبيق يعمل** على الأندرويد
176
+ - ✅ **واجهة عربية** كاملة
177
+ - ✅ **جميع الميزات** متاحة
178
+
179
+ ---
180
+
181
+ ## 💡 **نصائح مهمة:**
182
+
183
+ ### **ل��بناء الناجح:**
184
+ - تأكد من **اتصال الإنترنت** أثناء أول مزامنة
185
+ - **لا تغلق** Android Studio أثناء التحميل
186
+ - **انتظر** اكتمال جميع العمليات
187
+
188
+ ### **للاختبار:**
189
+ - اختبر على **أجهزة مختلفة** إن أمكن
190
+ - تأكد من **جميع الميزات** تعمل
191
+ - اختبر **تسجيل الدخول** والتنقل
192
+
193
+ ### **للمشاكل:**
194
+ - راجع **Build Output** في الأسفل
195
+ - استخدم **"Clean Project"** عند المشاكل
196
+ - أعد تشغيل **Android Studio** إذا لزم الأمر
197
+
198
+ ---
199
+
200
+ **🚀 مبروك! تطبيقك جاهز للعالم!**
APK_BUILD_GUIDE.md ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # دليل بناء APK - محفظتي الموحدة
2
+
3
+ ## 🎯 **الوضع الحالي**
4
+
5
+ ✅ **تم إنجازه:**
6
+ - ✅ إعداد مشروع Capacitor كامل
7
+ - ✅ تثبيت Java JDK 11
8
+ - ✅ إضافة منصة الأندرويد
9
+ - ✅ نسخ ملفات التطبيق إلى مجلد www
10
+ - ✅ إضافة الأذونات المطلوبة
11
+ - ✅ إعداد ملفات التكوين
12
+
13
+ ❌ **المطلوب لإكمال البناء:**
14
+ - ❌ تثبيت Android SDK
15
+ - ❌ إعداد متغيرات البيئة
16
+ - ❌ بناء APK
17
+
18
+ ---
19
+
20
+ ## 📋 **خطوات إكمال بناء APK**
21
+
22
+ ### **الطريقة 1: استخدام Android Studio (الأسهل)**
23
+
24
+ #### 1. تحميل وتثبيت Android Studio:
25
+ ```
26
+ https://developer.android.com/studio
27
+ ```
28
+
29
+ #### 2. فتح المشروع:
30
+ ```bash
31
+ cd E:\almada\android
32
+ # ثم فتح المجلد في Android Studio
33
+ ```
34
+
35
+ #### 3. بناء APK:
36
+ - في Android Studio: **Build > Build Bundle(s) / APK(s) > Build APK(s)**
37
+ - انتظار اكتمال البناء
38
+ - ستجد APK في: `android/app/build/outputs/apk/debug/`
39
+
40
+ ---
41
+
42
+ ### **الطريقة 2: سطر الأوامر (متقدم)**
43
+
44
+ #### 1. تثبيت Android SDK:
45
+ ```bash
46
+ # تحميل Command Line Tools من:
47
+ # https://developer.android.com/studio#command-tools
48
+
49
+ # استخراج إلى مجلد مثل:
50
+ # C:\Android\cmdline-tools\latest\
51
+ ```
52
+
53
+ #### 2. إعداد متغيرات البيئة:
54
+ ```bash
55
+ # إضافة إلى متغيرات البيئة:
56
+ ANDROID_HOME=C:\Android
57
+ ANDROID_SDK_ROOT=C:\Android
58
+ PATH=%PATH%;%ANDROID_HOME%\cmdline-tools\latest\bin
59
+ PATH=%PATH%;%ANDROID_HOME%\platform-tools
60
+ ```
61
+
62
+ #### 3. تثبيت SDK Components:
63
+ ```bash
64
+ sdkmanager "platform-tools" "platforms;android-33" "build-tools;33.0.0"
65
+ ```
66
+
67
+ #### 4. بناء APK:
68
+ ```bash
69
+ cd E:\almada\android
70
+ .\gradlew assembleDebug
71
+ ```
72
+
73
+ ---
74
+
75
+ ### **الطريقة 3: استخدام Ionic CLI (الأبسط)**
76
+
77
+ #### 1. تثبيت Android Studio أولاً (للحصول على SDK)
78
+
79
+ #### 2. استخدام Ionic:
80
+ ```bash
81
+ cd E:\almada
82
+ ionic cap build android
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 📱 **ملفات APK المتوقعة**
88
+
89
+ بعد البناء الناجح ستجد:
90
+
91
+ ### **APK للتطوير:**
92
+ ```
93
+ android/app/build/outputs/apk/debug/app-debug.apk
94
+ ```
95
+
96
+ ### **APK للإنتاج:**
97
+ ```
98
+ android/app/build/outputs/apk/release/app-release.apk
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 🔧 **إعدادات إضافية للتطبيق**
104
+
105
+ ### **الأذونات المضافة:**
106
+ ```xml
107
+ <!-- الأذونات الأساسية -->
108
+ <uses-permission android:name="android.permission.INTERNET" />
109
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
110
+ <uses-permission android:name="android.permission.CAMERA" />
111
+ <uses-permission android:name="android.permission.VIBRATE" />
112
+
113
+ <!-- أذونات SMS (للمستقبل) -->
114
+ <uses-permission android:name="android.permission.READ_SMS" />
115
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
116
+
117
+ <!-- أذونات البصمة -->
118
+ <uses-permission android:name="android.permission.USE_FINGERPRINT" />
119
+ <uses-permission android:name="android.permission.USE_BIOMETRIC" />
120
+ ```
121
+
122
+ ### **معلومات التطبيق:**
123
+ - **اسم التطبيق:** محفظتي الموحدة
124
+ - **Package ID:** com.almada.unifiedwallet
125
+ - **الإصدار:** 1.0.0
126
+
127
+ ---
128
+
129
+ ## 🚀 **اختبار التطبيق**
130
+
131
+ ### **تثبيت APK على الهاتف:**
132
+ ```bash
133
+ # تفعيل Developer Options و USB Debugging
134
+ # ثم:
135
+ adb install app-debug.apk
136
+ ```
137
+
138
+ ### **أو نسخ APK إلى الهاتف وتثبيته يدوياً**
139
+
140
+ ---
141
+
142
+ ## 📊 **الميزات المتاحة في التطبيق**
143
+
144
+ ### **الصفحة الرئيسية:**
145
+ - تسجيل دخول برقم هاتف + PIN
146
+ - عرض المحافظ الـ6 (جوالي، ONE Cash، إلخ)
147
+ - عرض الأرصدة الموحدة
148
+
149
+ ### **الميزات المتقدمة:**
150
+ - واجهة عربية كاملة (RTL)
151
+ - تصميم متجاوب
152
+ - رسوم متحركة سلسة
153
+ - دعم الوضع الليلي
154
+
155
+ ### **الأمان:**
156
+ - تشفير البيانات محلياً
157
+ - حماية PIN
158
+ - جلسات آمنة
159
+
160
+ ---
161
+
162
+ ## 🎯 **الخطوات التالية بعد البناء**
163
+
164
+ ### **للاختبار:**
165
+ 1. تثبيت APK على الهاتف
166
+ 2. اختبار تسجيل الدخول (777123456 / 1234)
167
+ 3. اختبار جميع الميزات
168
+ 4. التأكد من الأداء
169
+
170
+ ### **للتطوير:**
171
+ 1. إضافة ميزات قراءة SMS
172
+ 2. تطوير نظام الإشعارات
173
+ 3. إضافة المزيد من المحافظ
174
+ 4. تحسين الأمان
175
+
176
+ ### **للنشر:**
177
+ 1. إنشاء حساب Google Play Developer
178
+ 2. إعداد التوقيع للإنتاج
179
+ 3. رفع التطبيق للمراجعة
180
+ 4. التسويق والترويج
181
+
182
+ ---
183
+
184
+ ## 💡 **نصائح مهمة**
185
+
186
+ ### **للبناء الناجح:**
187
+ - تأكد من تثبيت Java JDK 11+ ✅
188
+ - تأكد من تثبيت Android SDK
189
+ - تأكد من إعداد متغيرات البيئة
190
+ - استخدم Android Studio للسهولة
191
+
192
+ ### **للاختبار:**
193
+ - اختبر على أجهزة مختلفة
194
+ - اختبر جميع الميزات
195
+ - تأكد من الأداء والاستقرار
196
+
197
+ ### **للأمان:**
198
+ - لا تشارك ملفات التوقيع
199
+ - استخدم ProGuard للحماية
200
+ - اختبر الأمان بعناية
201
+
202
+ ---
203
+
204
+ **🎉 مبروك! تطبيقك جاهز للبناء والاختبار!**
205
+
206
+ للمساعدة في أي خطوة، راجع الوثائق أو تواصل مع فريق التطوير.
APK_README.md ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📱 محفظتي الموحدة - تطبيق APK جاهز!
2
+
3
+ ## 🎉 **تهانينا! تطبيقك جاهز للبناء**
4
+
5
+ تم إعداد مشروع **محفظتي الموحدة** بنجاح كتطبيق أندرويد باستخدام تقنية **Capacitor**.
6
+
7
+ ---
8
+
9
+ ## 🚀 **طرق بناء APK**
10
+
11
+ ### **الطريقة الأسهل: Android Studio**
12
+ 1. حمل وثبت [Android Studio](https://developer.android.com/studio)
13
+ 2. افتح مجلد `android` في Android Studio
14
+ 3. اختر **Build > Build APK**
15
+ 4. انتظر اكتمال البناء
16
+ 5. ستجد APK في: `android/app/build/outputs/apk/debug/`
17
+
18
+ ### **الطريقة السريعة: ملف BAT**
19
+ 1. شغل `INSTALL_ANDROID_SDK.bat` (مرة واحدة فقط)
20
+ 2. اتبع التعليمات لتثبيت Android SDK
21
+ 3. شغل `QUICK_APK_BUILD.bat`
22
+ 4. انتظر اكتمال البناء
23
+
24
+ ### **الطريقة اليدوية: سطر الأوامر**
25
+ ```bash
26
+ # تأكد من تثبيت Java و Android SDK
27
+ java -version
28
+ sdkmanager --version
29
+
30
+ # بناء APK
31
+ cd android
32
+ gradlew assembleDebug
33
+ ```
34
+
35
+ ---
36
+
37
+ ## 📋 **متطلبات البناء**
38
+
39
+ ### **مثبت بالفعل:**
40
+ ✅ **Node.js** و **npm**
41
+ ✅ **Capacitor** و **التبعيات**
42
+ ✅ **Java JDK 11**
43
+ ✅ **مشروع Android** جاهز
44
+
45
+ ### **مطلوب تثبيته:**
46
+ ❌ **Android SDK** (عبر Android Studio أو Command Line Tools)
47
+
48
+ ---
49
+
50
+ ## 📱 **معلومات التطبيق**
51
+
52
+ | المعلومة | القيمة |
53
+ |---------|--------|
54
+ | **اسم التطبيق** | محفظتي الموحدة |
55
+ | **Package ID** | com.almada.unifiedwallet |
56
+ | **الإصدار** | 1.0.0 |
57
+ | **الحد الأدنى للأندرويد** | API 24 (Android 7.0) |
58
+
59
+ ---
60
+
61
+ ## 🔑 **بيانات التجربة**
62
+
63
+ للدخول إلى التطبيق بعد التثبيت:
64
+ - **رقم الهاتف:** `777123456`
65
+ - **رمز PIN:** `1234`
66
+
67
+ ---
68
+
69
+ ## 🎯 **الميزات المتاحة**
70
+
71
+ ### **الأساسية:**
72
+ - ✅ تسجيل دخول آمن برقم الهاتف + PIN
73
+ - ✅ عرض 6 محافظ يمنية (جوالي، ONE Cash، إلخ)
74
+ - ✅ واجهة عربية كاملة (RTL)
75
+ - ✅ تصميم متجاوب وجذاب
76
+
77
+ ### **المتقدمة:**
78
+ - ✅ رسوم متحركة سلسة
79
+ - ✅ دعم الوضع الليلي
80
+ - ✅ حفظ البيانات محلياً
81
+ - ✅ أمان متعدد الطبقات
82
+
83
+ ### **المستقبلية (جاهزة للتطوير):**
84
+ - 🔄 قراءة رسائل SMS تلقائياً
85
+ - 🔄 مصادقة بيومترية (بصمة/وجه)
86
+ - 🔄 إشعارات ذكية
87
+ - 🔄 تحليل الإنفاق
88
+
89
+ ---
90
+
91
+ ## 📂 **هيكل الملفات**
92
+
93
+ ```
94
+ almada/
95
+ ├── 📱 android/ # مشروع الأندرويد
96
+ ├── 🌐 www/ # ملفات التطبيق
97
+ ├── 📄 capacitor.config.ts # إعدادات Capacitor
98
+ ├── 📦 package.json # تبعيات المشروع
99
+ ├── 🔨 QUICK_APK_BUILD.bat # بناء سريع
100
+ ├── ⚙️ INSTALL_ANDROID_SDK.bat # تثبيت SDK
101
+ └── 📖 APK_BUILD_GUIDE.md # دليل مفصل
102
+ ```
103
+
104
+ ---
105
+
106
+ ## 🛠️ **استكشاف الأخطاء**
107
+
108
+ ### **خطأ: Java غير موجود**
109
+ ```bash
110
+ # تحقق من تثبيت Java
111
+ java -version
112
+
113
+ # إذا لم يكن مثبت، حمل من:
114
+ # https://adoptium.net/
115
+ ```
116
+
117
+ ### **خطأ: Android SDK غير موجود**
118
+ ```bash
119
+ # شغل ملف التثبيت
120
+ INSTALL_ANDROID_SDK.bat
121
+
122
+ # أو ثبت Android Studio
123
+ ```
124
+
125
+ ### **خطأ: Gradle Build فشل**
126
+ ```bash
127
+ # نظف المشروع
128
+ cd android
129
+ gradlew clean
130
+
131
+ # أعد البناء
132
+ gradlew assembleDebug
133
+ ```
134
+
135
+ ---
136
+
137
+ ## 📲 **تثبيت APK على الهاتف**
138
+
139
+ ### **الطريقة 1: USB**
140
+ ```bash
141
+ # فعل USB Debugging في الهاتف
142
+ # ثم:
143
+ adb install app-debug.apk
144
+ ```
145
+
146
+ ### **الطريقة 2: يدوياً**
147
+ 1. انسخ ملف APK إلى الهاتف
148
+ 2. فعل "مصادر غير معروفة" في الإعدادات
149
+ 3. اضغط على ملف APK لتثبيته
150
+
151
+ ---
152
+
153
+ ## 🎯 **الخطوات التالية**
154
+
155
+ ### **للاختبار:**
156
+ 1. 📱 ثبت APK على الهاتف
157
+ 2. 🔐 جرب تسجيل الدخول
158
+ 3. 💳 استكشف المحافظ
159
+ 4. 🎨 جرب الميزات المختلفة
160
+
161
+ ### **للتطوير:**
162
+ 1. 📨 أضف قراءة SMS
163
+ 2. 🔔 طور الإشعارات
164
+ 3. 📊 أضف تحليل البيانات
165
+ 4. 🛡️ حسن الأمان
166
+
167
+ ### **للنشر:**
168
+ 1. 🏪 أنشئ حساب Google Play
169
+ 2. 🔏 أعد التوقيع للإنتاج
170
+ 3. 📤 ارفع للمراجعة
171
+ 4. 📢 سوق التطبيق
172
+
173
+ ---
174
+
175
+ ## 💡 **نصائح مهمة**
176
+
177
+ ### **للبناء الناجح:**
178
+ - استخدم **Android Studio** للسهولة
179
+ - تأكد من **اتصال الإنترنت** أثناء البناء
180
+ - **أعد تشغيل** Command Prompt بعد تثبيت SDK
181
+
182
+ ### **للاختبار:**
183
+ - اختبر على **أجهزة مختلفة**
184
+ - تأكد من **جميع الميزات**
185
+ - راقب **الأداء والاستقرار**
186
+
187
+ ---
188
+
189
+ ## 📞 **الدعم والمساعدة**
190
+
191
+ للحصول على المساعدة:
192
+ 1. راجع `APK_BUILD_GUIDE.md` للتفاصيل
193
+ 2. تحقق من `BUILD_INSTRUCTIONS.md` للتعليمات الكاملة
194
+ 3. تواصل مع فريق التطوير
195
+
196
+ ---
197
+
198
+ **🎊 مبروك! تطبيقك جاهز للعالم!**
199
+
200
+ *تطبيق محفظتي الموحدة - المدى للخدمات البرمجية التسويقية والإعلانية*
BUILD_APK_SIMPLE.bat ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ echo ========================================
3
+ echo محفظتي الموحدة - بناء APK مبسط
4
+ echo ========================================
5
+ echo.
6
+
7
+ echo 🔍 التحقق من المتطلبات...
8
+
9
+ :: التحقق من Java
10
+ java -version >nul 2>&1
11
+ if %errorlevel% neq 0 (
12
+ echo ❌ Java غير مثبت!
13
+ echo يرجى تثبيت Java JDK من: https://adoptium.net/
14
+ pause
15
+ exit /b 1
16
+ )
17
+ echo ✅ Java متوفر
18
+
19
+ :: التحقق من Node.js
20
+ node --version >nul 2>&1
21
+ if %errorlevel% neq 0 (
22
+ echo ❌ Node.js غير مثبت!
23
+ echo يرجى تثبيت Node.js من: https://nodejs.org/
24
+ pause
25
+ exit /b 1
26
+ )
27
+ echo ✅ Node.js متوفر
28
+
29
+ echo.
30
+ echo 📦 تثبيت أدوات البناء...
31
+ call npm install -g @ionic/cli @capacitor/cli
32
+
33
+ echo.
34
+ echo 🔄 مزامنة المشروع...
35
+ call cap sync android
36
+
37
+ echo.
38
+ echo 🏗️ بناء APK...
39
+ echo هذه العملية قد تستغرق 5-10 دقائق...
40
+ echo يرجى الانتظار...
41
+
42
+ cd android
43
+ call gradlew assembleDebug
44
+
45
+ if %errorlevel% equ 0 (
46
+ echo.
47
+ echo ========================================
48
+ echo 🎉 تم بناء APK بنجاح!
49
+ echo ========================================
50
+ echo.
51
+ echo 📱 ملف APK متوفر في:
52
+ echo android\app\build\outputs\apk\debug\app-debug.apk
53
+ echo.
54
+ echo 📋 معلومات التطبيق:
55
+ echo - الاسم: محفظتي الموحدة
56
+ echo - الحجم: ~15-20 MB
57
+ echo - النوع: Debug APK
58
+ echo.
59
+ echo 🔑 بيانات التجربة:
60
+ echo - رقم الهاتف: 777123456
61
+ echo - رمز PIN: 1234
62
+ echo.
63
+ echo 📲 لتثبيت التطبيق:
64
+ echo 1. انسخ ملف APK إلى هاتفك
65
+ echo 2. فعل "مصادر غير معروفة" في إعدادات الأمان
66
+ echo 3. اضغط على ملف APK لتثبيته
67
+ echo.
68
+
69
+ :: فتح مجلد APK
70
+ explorer "app\build\outputs\apk\debug\"
71
+
72
+ ) else (
73
+ echo.
74
+ echo ❌ فشل في بناء APK!
75
+ echo.
76
+ echo 🔧 الحلول المقترحة:
77
+ echo 1. تأكد من تثبيت Android SDK
78
+ echo 2. استخدم Android Studio للبناء
79
+ echo 3. راجع رسائل الخطأ أعلاه
80
+ echo.
81
+ )
82
+
83
+ echo.
84
+ pause
BUILD_FROM_GITHUB.bat ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ echo ========================================
3
+ echo بناء APK من GitHub - محفظتي الموحدة
4
+ echo ========================================
5
+ echo.
6
+
7
+ echo [1/6] التحقق من الأدوات المطلوبة...
8
+
9
+ :: التحقق من Git
10
+ git --version >nul 2>&1
11
+ if %errorlevel% neq 0 (
12
+ echo ❌ Git غير مثبت!
13
+ echo يرجى تثبيت Git من: https://git-scm.com/
14
+ pause
15
+ exit /b 1
16
+ )
17
+ echo ✅ Git متوفر
18
+
19
+ :: التحقق من Node.js
20
+ node --version >nul 2>&1
21
+ if %errorlevel% neq 0 (
22
+ echo ❌ Node.js غير مثبت!
23
+ echo يرجى تثبيت Node.js من: https://nodejs.org/
24
+ pause
25
+ exit /b 1
26
+ )
27
+ echo ✅ Node.js متوفر
28
+
29
+ :: التحقق من Java
30
+ java -version >nul 2>&1
31
+ if %errorlevel% neq 0 (
32
+ echo ❌ Java غير مثبت!
33
+ echo يرجى تثبيت Java JDK من: https://adoptium.net/
34
+ pause
35
+ exit /b 1
36
+ )
37
+ echo ✅ Java متوفر
38
+
39
+ echo.
40
+ echo [2/6] استنساخ المشروع من GitHub...
41
+ if exist "almada-unified-wallet" (
42
+ echo مجلد المشروع موجود، سيتم حذفه وإعادة الاستنساخ...
43
+ rmdir /s /q "almada-unified-wallet"
44
+ )
45
+
46
+ git clone https://github.com/moh77544/---.git almada-unified-wallet
47
+ if %errorlevel% neq 0 (
48
+ echo ❌ فشل في استنساخ المشروع!
49
+ pause
50
+ exit /b 1
51
+ )
52
+ echo ✅ تم استنساخ المشروع
53
+
54
+ echo.
55
+ echo [3/6] الانتقال إلى مجلد المشروع...
56
+ cd almada-unified-wallet
57
+
58
+ echo.
59
+ echo [4/6] تثبيت التبعيات...
60
+ call npm install
61
+ if %errorlevel% neq 0 (
62
+ echo ❌ فشل في تثبيت التبعيات!
63
+ pause
64
+ exit /b 1
65
+ )
66
+
67
+ call npm install -g @ionic/cli @capacitor/cli
68
+ echo ✅ تم تثبيت التبعيات
69
+
70
+ echo.
71
+ echo [5/6] إعداد ملفات الويب...
72
+ if not exist "www" mkdir www
73
+ copy index.html www\ >nul 2>&1
74
+ copy styles.css www\ >nul 2>&1
75
+ copy app.js www\ >nul 2>&1
76
+ copy auth.js www\ >nul 2>&1
77
+ copy wallets.js www\ >nul 2>&1
78
+ copy notifications.js www\ >nul 2>&1
79
+ copy demo.html www\ >nul 2>&1
80
+ copy src\manifest.json www\ >nul 2>&1
81
+ echo ✅ تم إعداد ملفات الويب
82
+
83
+ echo.
84
+ echo [6/6] مزامنة وبناء APK...
85
+ call npx cap sync android
86
+ if %errorlevel% neq 0 (
87
+ echo ❌ فشل في مزامنة Capacitor!
88
+ pause
89
+ exit /b 1
90
+ )
91
+
92
+ cd android
93
+ call gradlew assembleDebug
94
+ if %errorlevel% neq 0 (
95
+ echo ❌ فشل في بناء APK!
96
+ echo تأكد من تثبيت Android SDK
97
+ pause
98
+ exit /b 1
99
+ )
100
+
101
+ echo.
102
+ echo ========================================
103
+ echo 🎉 تم بناء APK بنجاح!
104
+ echo ========================================
105
+ echo.
106
+ echo 📱 ملف APK متوفر في:
107
+ echo %cd%\app\build\outputs\apk\debug\app-debug.apk
108
+ echo.
109
+ echo 📋 معلومات التطبيق:
110
+ echo - الاسم: محفظتي الموحدة
111
+ echo - الحجم: ~15-20 MB
112
+ echo - النوع: Debug APK
113
+ echo.
114
+ echo 🔑 بيانات التجربة:
115
+ echo - رقم الهاتف: 777123456
116
+ echo - رمز PIN: 1234
117
+ echo.
118
+ echo 📲 لتثبيت التطبيق:
119
+ echo 1. انسخ ملف APK إلى هاتفك
120
+ echo 2. فعل "مصادر غير معروفة" في إعدادات الأمان
121
+ echo 3. اضغط على ملف APK لتثبيته
122
+ echo.
123
+
124
+ :: فتح مجلد APK
125
+ explorer "app\build\outputs\apk\debug\"
126
+
127
+ echo.
128
+ pause
BUILD_INSTRUCTIONS.md ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # تعليمات بناء تطبيق محفظتي الموحدة
2
+
3
+ ## متطلبات النظام
4
+
5
+ ### الأدوات المطلوبة:
6
+ - **Node.js** (الإصدار 18 أو أحدث)
7
+ - **npm** أو **yarn**
8
+ - **Ionic CLI** (الإصدار 7 أو أحدث)
9
+ - **Angular CLI** (الإصدار 17 أو أحدث)
10
+ - **Capacitor CLI** (الإصدار 5 أو أحدث)
11
+
12
+ ### للأندرويد:
13
+ - **Android Studio** (أحدث إصدار)
14
+ - **Android SDK** (API Level 24 أو أحدث)
15
+ - **Java JDK** (الإصدار 11 أو أحدث)
16
+
17
+ ### لـ iOS:
18
+ - **Xcode** (أحدث إصدار)
19
+ - **iOS SDK** (iOS 13 أو أحدث)
20
+ - **macOS** (مطلوب لبناء تطبيقات iOS)
21
+
22
+ ## خطوات التثبيت
23
+
24
+ ### 1. تثبيت الأدوات العامة
25
+ ```bash
26
+ # تثبيت Node.js من https://nodejs.org
27
+
28
+ # تثبيت Ionic CLI
29
+ npm install -g @ionic/cli
30
+
31
+ # تثبيت Angular CLI
32
+ npm install -g @angular/cli
33
+
34
+ # تثبيت Capacitor CLI
35
+ npm install -g @capacitor/cli
36
+ ```
37
+
38
+ ### 2. إعداد المشروع
39
+ ```bash
40
+ # الانتقال إلى مجلد المشروع
41
+ cd almada
42
+
43
+ # تثبيت التبعيات
44
+ npm install
45
+
46
+ # أو باستخدام yarn
47
+ yarn install
48
+ ```
49
+
50
+ ### 3. إعداد Capacitor
51
+ ```bash
52
+ # تهيئة Capacitor
53
+ npx cap init "محفظتي الموحدة" "com.almada.unifiedwallet"
54
+
55
+ # إضافة منصات
56
+ npx cap add android
57
+ npx cap add ios
58
+ ```
59
+
60
+ ## بناء التطبيق
61
+
62
+ ### 1. بناء تطبيق الويب
63
+ ```bash
64
+ # بناء للتطوير
65
+ ionic build
66
+
67
+ # بناء للإنتاج
68
+ ionic build --prod
69
+ ```
70
+
71
+ ### 2. بناء تطبيق الأندرويد
72
+
73
+ #### أ. إعداد Android Studio
74
+ ```bash
75
+ # نسخ الملفات إلى مجلد الأندرويد
76
+ npx cap copy android
77
+
78
+ # مزامنة المشروع
79
+ npx cap sync android
80
+
81
+ # فتح في Android Studio
82
+ npx cap open android
83
+ ```
84
+
85
+ #### ب. بناء APK من سطر الأوامر
86
+ ```bash
87
+ # بناء APK للتطوير
88
+ cd android
89
+ ./gradlew assembleDebug
90
+
91
+ # بناء APK للإنتاج
92
+ ./gradlew assembleRelease
93
+
94
+ # بناء AAB للنشر في Google Play
95
+ ./gradlew bundleRelease
96
+ ```
97
+
98
+ #### ج. بناء APK من Android Studio
99
+ 1. افتح Android Studio
100
+ 2. اختر **Build > Build Bundle(s) / APK(s) > Build APK(s)**
101
+ 3. انتظر حتى اكتمال البناء
102
+ 4. ستجد ملف APK في: `android/app/build/outputs/apk/`
103
+
104
+ ### 3. بناء تطبيق iOS
105
+
106
+ #### أ. إعداد Xcode
107
+ ```bash
108
+ # نسخ الملفات إلى مجلد iOS
109
+ npx cap copy ios
110
+
111
+ # مزامنة المشروع
112
+ npx cap sync ios
113
+
114
+ # فتح في Xcode
115
+ npx cap open ios
116
+ ```
117
+
118
+ #### ب. بناء IPA من Xcode
119
+ 1. افتح Xcode
120
+ 2. اختر جهاز أو محاكي
121
+ 3. اختر **Product > Archive**
122
+ 4. بعد اكتمال الأرشفة، اختر **Distribute App**
123
+ 5. اتبع التعليمات لإنشاء ملف IPA
124
+
125
+ ## تشغيل التطبيق للتطوير
126
+
127
+ ### 1. تشغيل في المتصفح
128
+ ```bash
129
+ # تشغيل خادم التطوير
130
+ ionic serve
131
+
132
+ # تشغيل مع إعادة التحميل التلقائي
133
+ ionic serve --lab
134
+ ```
135
+
136
+ ### 2. تشغيل على الأندرويد
137
+ ```bash
138
+ # تشغيل على جهاز أو محاكي
139
+ ionic cap run android
140
+
141
+ # تشغيل مع إعادة التحميل المباشر
142
+ ionic cap run android --livereload --external
143
+ ```
144
+
145
+ ### 3. تشغيل على iOS
146
+ ```bash
147
+ # تشغيل على جهاز أو محاكي
148
+ ionic cap run ios
149
+
150
+ # تشغيل مع إعادة التحميل المباشر
151
+ ionic cap run ios --livereload --external
152
+ ```
153
+
154
+ ## إعدادات الإنتاج
155
+
156
+ ### 1. تحديث المتغيرات
157
+ قم بتحديث ملف `src/environments/environment.prod.ts`:
158
+ ```typescript
159
+ export const environment = {
160
+ production: true,
161
+ apiUrl: 'https://api.almada.com',
162
+ // ... باقي الإعدادات
163
+ };
164
+ ```
165
+
166
+ ### 2. إعداد الأيقونات والشاشات
167
+ ```bash
168
+ # إنشاء الأيقونات والشاشات تلقائياً
169
+ npm install -g cordova-res
170
+ cordova-res android --skip-config --copy
171
+ cordova-res ios --skip-config --copy
172
+ ```
173
+
174
+ ### 3. توقيع التطبيق للأندرويد
175
+ ```bash
176
+ # إنشاء مفتاح التوقيع
177
+ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
178
+
179
+ # إضافة إعدادات التوقيع في android/app/build.gradle
180
+ ```
181
+
182
+ ### 4. إعداد التوقيع لـ iOS
183
+ 1. افتح Xcode
184
+ 2. اذهب إلى **Signing & Capabilities**
185
+ 3. اختر **Team** و **Bundle Identifier**
186
+ 4. تأكد من إعداد **Provisioning Profile**
187
+
188
+ ## اختبار التطبيق
189
+
190
+ ### 1. اختبار الوحدة
191
+ ```bash
192
+ # تشغيل اختبارات الوحدة
193
+ npm test
194
+
195
+ # تشغيل مع المراقبة
196
+ npm test -- --watch
197
+ ```
198
+
199
+ ### 2. اختبار النهاية إلى النهاية
200
+ ```bash
201
+ # تشغيل اختبارات e2e
202
+ npm run e2e
203
+ ```
204
+
205
+ ### 3. اختبار على الأجهزة
206
+ ```bash
207
+ # تثبيت على جهاز أندرويد
208
+ adb install android/app/build/outputs/apk/debug/app-debug.apk
209
+
210
+ # عرض سجلات الأندرويد
211
+ adb logcat
212
+ ```
213
+
214
+ ## نشر التطبيق
215
+
216
+ ### 1. Google Play Store
217
+ 1. إنشاء حساب مطور في Google Play Console
218
+ 2. رفع ملف AAB
219
+ 3. ملء معلومات التطبيق
220
+ 4. إرسال للمراجعة
221
+
222
+ ### 2. Apple App Store
223
+ 1. إنشاء حساب مطور في App Store Connect
224
+ 2. رفع التطبيق عبر Xcode أو Application Loader
225
+ 3. ملء معلومات التطبيق
226
+ 4. إرسال للمراجعة
227
+
228
+ ## استكشاف الأخطاء
229
+
230
+ ### مشاكل شائعة:
231
+
232
+ #### 1. خطأ في بناء الأندرويد
233
+ ```bash
234
+ # تنظيف المشروع
235
+ cd android
236
+ ./gradlew clean
237
+
238
+ # إعادة بناء
239
+ ./gradlew build
240
+ ```
241
+
242
+ #### 2. مشاكل Capacitor
243
+ ```bash
244
+ # إعادة مزامنة
245
+ npx cap sync
246
+
247
+ # تحديث Capacitor
248
+ npm update @capacitor/core @capacitor/cli
249
+ ```
250
+
251
+ #### 3. مشاكل الأذونات
252
+ تأكد من إضافة الأذونات المطلوبة في:
253
+ - `android/app/src/main/AndroidManifest.xml` للأندرويد
254
+ - `ios/App/App/Info.plist` لـ iOS
255
+
256
+ ## الدعم والمساعدة
257
+
258
+ للحصول على المساعدة:
259
+ 1. راجع [وثائق Ionic](https://ionicframework.com/docs)
260
+ 2. راجع [وثائق Capacitor](https://capacitorjs.com/docs)
261
+ 3. تواصل مع فريق التطوير
262
+
263
+ ---
264
+
265
+ **ملاحظة**: تأكد من تحديث جميع التبعيات بانتظام للحصول على أحدث الميزات وإصلاحات الأمان.
CLOUD_BUILD_QUICK.md ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ☁️ البناء السحابي السريع - 15 دقيقة فقط!
2
+
3
+ ## 🚀 **الهدف:** APK جاهز من السحابة في 15 دقيقة!
4
+
5
+ ---
6
+
7
+ ## ⚡ **الخطوات السريعة:**
8
+
9
+ ### **1️⃣ إنشاء حساب GitHub** (2 دقيقة)
10
+ ```
11
+ 🌐 اذهب إلى: https://github.com
12
+ 📝 اضغط "Sign up" وأنشئ حساب
13
+ ✅ تأكد من البريد الإلكتروني
14
+ ```
15
+
16
+ ### **2️⃣ إنشاء Repository** (1 دقيقة)
17
+ ```
18
+ ➕ اضغط "New repository"
19
+ 📝 الاسم: almada-unified-wallet
20
+ 📄 الوصف: محفظتي الموحدة
21
+ 🌍 اختر "Public"
22
+ ✅ اضغط "Create repository"
23
+ ```
24
+
25
+ ### **3️⃣ رفع الملفات** (5 دقائق)
26
+ ```
27
+ 📁 اضغط "uploading an existing file"
28
+ 📤 اسحب وأفلت هذه الملفات:
29
+ ✅ .github/workflows/build-apk.yml
30
+ ✅ index.html
31
+ ✅ styles.css
32
+ ✅ app.js
33
+ ✅ auth.js
34
+ ✅ wallets.js
35
+ ✅ notifications.js
36
+ ✅ package.json
37
+ ✅ capacitor.config.ts
38
+ ✅ مجلد android كامل
39
+ 💬 رسالة: "Initial commit"
40
+ ✅ اضغط "Commit changes"
41
+ ```
42
+
43
+ ### **4️⃣ تشغيل البناء** (10 دقائق)
44
+ ```
45
+ 🔧 اذهب إلى تبويب "Actions"
46
+ 🚀 اضغط "Run workflow"
47
+ ⏰ انتظر 10-15 دقيقة
48
+ ✅ ابحث عن علامة ✅ خضراء
49
+ ```
50
+
51
+ ### **5️⃣ تحميل APK** (1 دقيقة)
52
+ ```
53
+ 📱 اضغط على Build الناجح
54
+ 📦 في الأسفل: "Artifacts"
55
+ ⬇️ حمل: almada-unified-wallet-apk
56
+ 📱 استخرج APK وثبته!
57
+ ```
58
+
59
+ ---
60
+
61
+ ## 🎯 **النتيجة:**
62
+
63
+ ✅ **ملف APK** جاهز للتثبيت
64
+ ✅ **بناء تلقائي** عند كل تحديث
65
+ ✅ **مجاني تماماً** مع GitHub
66
+ ✅ **رابط تحميل** مباشر
67
+
68
+ ---
69
+
70
+ ## 📱 **معلومات APK:**
71
+
72
+ | المعلومة | القيمة |
73
+ |---------|--------|
74
+ | **الاسم** | app-debug.apk |
75
+ | **الحجم** | ~15-20 MB |
76
+ | **بيانات التجربة** | 777123456 / 1234 |
77
+ | **متوافق مع** | Android 7.0+ |
78
+
79
+ ---
80
+
81
+ ## 🔄 **للتحديثات المستقبلية:**
82
+
83
+ ```
84
+ 1. عدل أي ملف في GitHub
85
+ 2. Commit التغييرات
86
+ 3. APK جديد سيُبنى تلقائياً!
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 🆘 **مشاكل شائعة:**
92
+
93
+ ### **❌ Build فشل:**
94
+ ```
95
+ ✅ تحقق من رفع جميع الملفات
96
+ ✅ راجع logs في Actions
97
+ ✅ تأكد من package.json صحيح
98
+ ```
99
+
100
+ ### **❌ لا يوجد APK:**
101
+ ```
102
+ ✅ انتظر اكتمال Build (علامة ✅)
103
+ ✅ ابحث في "Artifacts"
104
+ ✅ حدث الصفحة
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 🎊 **مبروك!**
110
+
111
+ عند اكتمال هذه الخطوات:
112
+ - 📱 **APK جاهز** للتثبيت
113
+ - ☁️ **بناء سحابي** مجاني
114
+ - 🔄 **تحديثات تلقائية**
115
+ - 🌍 **متاح للعالم**
116
+
117
+ ---
118
+
119
+ ## 📞 **تحتاج مساعدة؟**
120
+
121
+ راجع الدليل المفصل: `GITHUB_SETUP_GUIDE.md`
122
+
123
+ **🚀 تطبيقك على بُعد 15 دقيقة من الواقع!**
GITHUB_SETUP_GUIDE.md ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ☁️ دليل إعداد البناء السحابي - GitHub Actions
2
+
3
+ ## 🎯 **الهدف:** بناء APK تلقائياً في السحابة مجاناً!
4
+
5
+ ---
6
+
7
+ ## 📋 **الخطوات المطلوبة:**
8
+
9
+ ### **الخطوة 1: إنشاء حساب GitHub** ⏱️ (2 دقيقة)
10
+
11
+ 1. **اذهب إلى:** https://github.com
12
+ 2. **اضغط "Sign up"** وأنشئ حساب جديد
13
+ 3. **تأكد من البريد الإلكتروني**
14
+
15
+ ### **الخطوة 2: إنشاء Repository جديد** ⏱️ (1 دقيقة)
16
+
17
+ 1. **اضغط "New repository"** (الزر الأخضر)
18
+ 2. **اسم المستودع:** `almada-unified-wallet`
19
+ 3. **الوصف:** `محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية`
20
+ 4. **اختر "Public"** (مجاني)
21
+ 5. **فعل "Add a README file"**
22
+ 6. **اضغط "Create repository"**
23
+
24
+ ### **الخطوة 3: رفع الملفات** ⏱️ (5 دقائق)
25
+
26
+ #### **الطريقة الأسهل: عبر الموقع**
27
+
28
+ 1. **في صفحة Repository، اضغط "uploading an existing file"**
29
+ 2. **اسحب وأفلت الملفات التالية:**
30
+ ```
31
+ 📁 .github/workflows/build-apk.yml
32
+ 📄 index.html
33
+ 📄 styles.css
34
+ 📄 app.js
35
+ 📄 auth.js
36
+ 📄 wallets.js
37
+ 📄 notifications.js
38
+ 📄 demo.html
39
+ 📄 package.json
40
+ 📄 capacitor.config.ts
41
+ 📄 .gitignore
42
+ 📁 src/manifest.json
43
+ 📁 android/ (كامل)
44
+ ```
45
+ 3. **اكتب رسالة:** `Initial commit - محفظتي الموحدة`
46
+ 4. **اضغط "Commit changes"**
47
+
48
+ #### **الطريقة المتقدمة: Git Command Line**
49
+
50
+ ```bash
51
+ # في مجلد المشروع
52
+ git init
53
+ git add .
54
+ git commit -m "Initial commit - محفظتي الموحدة"
55
+ git branch -M main
56
+ git remote add origin https://github.com/USERNAME/almada-unified-wallet.git
57
+ git push -u origin main
58
+ ```
59
+
60
+ ### **الخطوة 4: تشغيل البناء التلقائي** ⏱️ (10-15 دقيقة)
61
+
62
+ 1. **اذهب إلى تبويب "Actions"** في Repository
63
+ 2. **ستجد workflow اسمه:** `🚀 Build APK - محفظتي الموحدة`
64
+ 3. **اضغط "Run workflow"** إذا لم يبدأ تلقائياً
65
+ 4. **انتظر اكتمال البناء** (10-15 دقيقة)
66
+
67
+ ### **الخطوة 5: تحميل APK** ⏱️ (1 دقيقة)
68
+
69
+ عند اكتمال البناء:
70
+
71
+ 1. **اضغط على Build الناجح** (علامة ✅ خضراء)
72
+ 2. **في الأسفل، ستجد "Artifacts"**
73
+ 3. **اضغط على:** `almada-unified-wallet-apk`
74
+ 4. **حمل ملف ZIP واستخرج APK منه**
75
+
76
+ ---
77
+
78
+ ## 🎯 **البدائل السحابية الأخرى:**
79
+
80
+ ### **Ionic Appflow (مجاني للمشاريع الصغيرة):**
81
+
82
+ ```bash
83
+ # تثبيت Ionic CLI
84
+ npm install -g @ionic/cli
85
+
86
+ # تسجيل الدخول
87
+ ionic login
88
+
89
+ # ربط المشروع
90
+ ionic link
91
+
92
+ # بناء في السحابة
93
+ ionic capacitor build android --prod
94
+ ```
95
+
96
+ ### **CodeMagic (مجاني 500 دقيقة/شهر):**
97
+
98
+ 1. اذهب إلى: https://codemagic.io
99
+ 2. ربط حساب GitHub
100
+ 3. اختر Repository
101
+ 4. إعداد workflow للأندرويد
102
+ 5. بناء تلقائي
103
+
104
+ ---
105
+
106
+ ## 📱 **ما ستحصل عليه:**
107
+
108
+ ### **من GitHub Actions:**
109
+ - ✅ **بناء تلقائي** عند كل تحديث
110
+ - ✅ **APK مجاني** بدون حدود
111
+ - ✅ **تاريخ الإصدارات** كامل
112
+ - ✅ **رابط تحميل** مباشر
113
+
114
+ ### **معلومات APK:**
115
+ - 📱 **الاسم:** `app-debug.apk`
116
+ - 💾 **الحجم:** ~15-20 MB
117
+ - 🔧 **النوع:** Debug APK
118
+ - 📲 **جاهز للتثبيت** على أي هاتف أندرويد
119
+
120
+ ---
121
+
122
+ ## 🔄 **التحديثات المستقبلية:**
123
+
124
+ ### **لإضافة ميزات جديدة:**
125
+ 1. **عدل الملفات** في Repository
126
+ 2. **Commit التغييرات**
127
+ 3. **APK جديد** سيُبنى تلقائياً!
128
+
129
+ ### **لإنشاء Release:**
130
+ ```bash
131
+ # إنشاء tag جديد
132
+ git tag v1.0.1
133
+ git push origin v1.0.1
134
+
135
+ # سيُنشئ Release تلقائياً مع APK
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 🆘 **حل المشاكل:**
141
+
142
+ ### **مشكلة: Build فشل**
143
+ ```
144
+ الحل:
145
+ 1. تحقق من logs في Actions
146
+ 2. تأكد من رفع جميع الملفات
147
+ 3. تحقق من package.json
148
+ ```
149
+
150
+ ### **مشكلة: لا يوجد Artifacts**
151
+ ```
152
+ الحل:
153
+ 1. تأكد من نجاح Build (علامة ✅)
154
+ 2. انتظر اكتمال جميع الخطوات
155
+ 3. حدث الصفحة
156
+ ```
157
+
158
+ ### **مشكلة: APK لا يعمل**
159
+ ```
160
+ الحل:
161
+ 1. تأكد من تفعيل "مصادر غير معروفة"
162
+ 2. تحقق من توافق إصدار الأندرويد
163
+ 3. أعد تحميل APK
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 💡 **نصائح مهمة:**
169
+
170
+ ### **للنجاح:**
171
+ - 📁 **ارفع جميع الملفات** المطلوبة
172
+ - 🌐 **تأكد من اتصال الإنترنت** أثناء البناء
173
+ - ⏰ **انتظر اكتمال** جميع الخطوات
174
+
175
+ ### **للأمان:**
176
+ - 🔒 **لا تشارك** معلومات حساسة في Repository العام
177
+ - 🔑 **استخدم Secrets** للمعلومات الحساسة
178
+ - 🛡️ **راجع الأذونات** بانتظام
179
+
180
+ ### **للتطوير:**
181
+ - 📝 **اكتب وصف واضح** للـ commits
182
+ - 🏷️ **استخدم tags** للإصدارات
183
+ - 📚 **حدث README** بانتظام
184
+
185
+ ---
186
+
187
+ ## 🎉 **النتيجة النهائية:**
188
+
189
+ عند اكتمال هذه الخطوات، ستحصل على:
190
+
191
+ - ☁️ **نظام بناء سحابي** مجاني
192
+ - 🔄 **APK تلقائي** عند كل تحديث
193
+ - 📱 **رابط تحميل** مباشر
194
+ - 🌍 **متاح للعالم** عبر GitHub
195
+
196
+ ---
197
+
198
+ ## 📞 **تحتاج مساعدة؟**
199
+
200
+ إذا واجهت أي مشكلة:
201
+ 1. **راجع logs** في GitHub Actions
202
+ 2. **تحقق من الملفات** المرفوعة
203
+ 3. **تواصل للمساعدة**
204
+
205
+ **🚀 مبروك! تطبيقك سيُبنى في السحابة!**
206
+
207
+ ---
208
+
209
+ **💡 ملاحظة:** GitHub Actions مجاني للمشاريع العامة مع 2000 دقيقة/شهر للمشاريع الخاصة.
INSTALL_ANDROID_SDK.bat ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ echo ========================================
3
+ echo تثبيت Android SDK - محفظتي الموحدة
4
+ echo ========================================
5
+ echo.
6
+
7
+ echo هذا الملف سيساعدك في تثبيت Android SDK بدون Android Studio
8
+ echo.
9
+
10
+ echo [الخطوة 1] إنشاء مجلد Android SDK...
11
+ if not exist "C:\Android" mkdir "C:\Android"
12
+ if not exist "C:\Android\cmdline-tools" mkdir "C:\Android\cmdline-tools"
13
+ echo ✅ تم إنشاء المجلدات
14
+
15
+ echo.
16
+ echo [الخطوة 2] تحميل Command Line Tools...
17
+ echo يرجى تحميل Command Line Tools من:
18
+ echo https://developer.android.com/studio#command-tools
19
+ echo.
20
+ echo اختر: "Command line tools only" > Windows
21
+ echo.
22
+ echo بعد التحميل:
23
+ echo 1. استخرج الملف المضغوط
24
+ echo 2. انسخ محتويات مجلد cmdline-tools إلى:
25
+ echo C:\Android\cmdline-tools\latest\
26
+ echo.
27
+ pause
28
+
29
+ echo.
30
+ echo [الخطوة 3] إعداد متغيرات البيئة...
31
+ echo سيتم إضافة متغيرات البيئة التالية:
32
+ echo ANDROID_HOME=C:\Android
33
+ echo ANDROID_SDK_ROOT=C:\Android
34
+ echo.
35
+
36
+ setx ANDROID_HOME "C:\Android" /M >nul 2>&1
37
+ setx ANDROID_SDK_ROOT "C:\Android" /M >nul 2>&1
38
+
39
+ echo ✅ تم إعداد متغيرات البيئة
40
+
41
+ echo.
42
+ echo [الخطوة 4] إضافة إلى PATH...
43
+ set "newPath=C:\Android\cmdline-tools\latest\bin;C:\Android\platform-tools"
44
+
45
+ for /f "tokens=2*" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH 2^>nul') do set "currentPath=%%b"
46
+
47
+ if not defined currentPath set "currentPath="
48
+
49
+ echo %currentPath% | find /i "%newPath%" >nul
50
+ if %errorlevel% neq 0 (
51
+ setx PATH "%currentPath%;%newPath%" /M >nul 2>&1
52
+ echo ✅ تم إضافة Android SDK إلى PATH
53
+ ) else (
54
+ echo ✅ Android SDK موجود بالفعل في PATH
55
+ )
56
+
57
+ echo.
58
+ echo [الخطوة 5] إعادة تشغيل Command Prompt...
59
+ echo يرجى إغلاق هذه النافذة وفتح Command Prompt جديد
60
+ echo ثم تشغيل الأوامر التالية:
61
+ echo.
62
+ echo sdkmanager --version
63
+ echo sdkmanager "platform-tools"
64
+ echo sdkmanager "platforms;android-33"
65
+ echo sdkmanager "build-tools;33.0.0"
66
+ echo.
67
+
68
+ echo ========================================
69
+ echo 📋 ملخص ما تم:
70
+ echo ========================================
71
+ echo ✅ إنشاء مجلد C:\Android
72
+ echo ✅ إعداد ANDROID_HOME
73
+ echo ✅ إعداد ANDROID_SDK_ROOT
74
+ echo ✅ إضافة إلى PATH
75
+ echo.
76
+ echo 📝 المطلوب منك:
77
+ echo 1. تحميل Command Line Tools
78
+ echo 2. استخراج إلى C:\Android\cmdline-tools\latest\
79
+ echo 3. إعادة تشغيل Command Prompt
80
+ echo 4. تشغيل أوامر sdkmanager
81
+ echo.
82
+ echo بعد ذلك يمكنك تشغيل QUICK_APK_BUILD.bat
83
+ echo ========================================
84
+ pause
PROJECT_SUMMARY.md ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📊 ملخص مشروع محفظتي الموحدة - التحويل إلى APK
2
+
3
+ ## 🎯 **الهدف المحقق**
4
+ تم تحويل تطبيق **محفظتي الموحدة** من تطبيق ويب إلى **تطبيق أندرويد APK** جاهز للتثبيت والاستخدام.
5
+
6
+ ---
7
+
8
+ ## ✅ **ما تم إنجازه بنجاح**
9
+
10
+ ### **1. إعداد البيئة التقنية**
11
+ - ✅ تحويل المشروع إلى **Capacitor** (تقنية التطبيقات الهجينة)
12
+ - ✅ إعداد **package.json** مع جميع التبعيات المطلوبة
13
+ - ✅ تثبيت **Java JDK 11** للبناء
14
+ - ✅ إعداد **capacitor.config.ts** للتكوين
15
+
16
+ ### **2. إعداد مشروع الأندرويد**
17
+ - ✅ إضافة منصة الأندرويد: `cap add android`
18
+ - ✅ إعداد **AndroidManifest.xml** مع الأذونات المطلوبة
19
+ - ✅ تكوين **strings.xml** باللغة العربية
20
+ - ✅ نسخ ملفات التطبيق إلى مجلد `www`
21
+
22
+ ### **3. إضافة الأذونات المطلوبة**
23
+ ```xml
24
+ <!-- الأذونات الأساسية -->
25
+ <uses-permission android:name="android.permission.INTERNET" />
26
+ <uses-permission android:name="android.permission.CAMERA" />
27
+ <uses-permission android:name="android.permission.VIBRATE" />
28
+
29
+ <!-- أذونات SMS (للمستقبل) -->
30
+ <uses-permission android:name="android.permission.READ_SMS" />
31
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
32
+
33
+ <!-- أذونات البصمة -->
34
+ <uses-permission android:name="android.permission.USE_FINGERPRINT" />
35
+ <uses-permission android:name="android.permission.USE_BIOMETRIC" />
36
+ ```
37
+
38
+ ### **4. تحسين التطبيق للجوال**
39
+ - ✅ إضافة **Capacitor Core** للتفاعل مع ميزات الجهاز
40
+ - ✅ إعداد **SplashScreen** (شاشة البداية)
41
+ - ✅ تكوين **StatusBar** (شريط الحالة)
42
+ - ✅ إعداد **LocalNotifications** (الإشعارات المحلية)
43
+
44
+ ### **5. إنشاء ملفات التعليمات**
45
+ - ✅ **APK_BUILD_GUIDE.md** - دليل بناء مفصل
46
+ - ✅ **QUICK_APK_BUILD.bat** - ملف بناء سريع
47
+ - ✅ **INSTALL_ANDROID_SDK.bat** - تثبيت Android SDK
48
+ - ✅ **APK_README.md** - دليل المستخدم النهائي
49
+
50
+ ---
51
+
52
+ ## 📱 **معلومات التطبيق النهائي**
53
+
54
+ | المعلومة | القيمة |
55
+ |---------|--------|
56
+ | **اسم التطبيق** | محفظتي الموحدة |
57
+ | **Package ID** | com.almada.unifiedwallet |
58
+ | **الإصدار** | 1.0.0 |
59
+ | **التقنية** | Capacitor + HTML/CSS/JS |
60
+ | **الحد الأدنى للأندرويد** | API 24 (Android 7.0) |
61
+ | **حجم APK المتوقع** | ~15-20 MB |
62
+
63
+ ---
64
+
65
+ ## 🔧 **الحالة الحالية**
66
+
67
+ ### **جاهز للبناء:**
68
+ - ✅ جميع الملفات معدة
69
+ - ✅ التبعيات مثبتة
70
+ - ✅ Java JDK متوفر
71
+ - ✅ مشروع الأندرويد جاهز
72
+
73
+ ### **المطلوب لإكمال البناء:**
74
+ - ❌ **Android SDK** (يحتاج تثبيت)
75
+ - ❌ تشغيل أمر البناء: `gradlew assembleDebug`
76
+
77
+ ---
78
+
79
+ ## 🚀 **طرق إكمال البناء**
80
+
81
+ ### **الطريقة الأسهل:**
82
+ 1. تثبيت [Android Studio](https://developer.android.com/studio)
83
+ 2. فتح مجلد `android` في Android Studio
84
+ 3. **Build > Build APK**
85
+
86
+ ### **الطريقة السريعة:**
87
+ 1. تشغيل `INSTALL_ANDROID_SDK.bat`
88
+ 2. تشغيل `QUICK_APK_BUILD.bat`
89
+
90
+ ### **الطريقة اليدوية:**
91
+ ```bash
92
+ # تثبيت Android SDK
93
+ # ثم:
94
+ cd android
95
+ gradlew assembleDebug
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 📂 **هيكل المشروع النهائي**
101
+
102
+ ```
103
+ almada/
104
+ ├── 📱 android/ # مشروع الأندرويد الكامل
105
+ │ ├── app/ # تطبيق الأندرويد
106
+ │ ├── gradle/ # إعدادات Gradle
107
+ │ └── build.gradle # ملف البناء
108
+ ├── 🌐 www/ # ملفات التطبيق
109
+ │ ├── index.html # الصفحة الرئيسية
110
+ │ ├── styles.css # التصميمات
111
+ │ ├── app.js # المنطق الرئيسي
112
+ │ ├── auth.js # نظام المصادقة
113
+ │ ├── wallets.js # إدارة المحافظ
114
+ │ └── notifications.js # الإشعارات
115
+ ├── 📄 capacitor.config.ts # إعدادات Capacitor
116
+ ├── 📦 package.json # تبعيات المشروع
117
+ ├── 🔨 QUICK_APK_BUILD.bat # بناء سريع
118
+ ├── ⚙️ INSTALL_ANDROID_SDK.bat # تثبيت SDK
119
+ ├── 📖 APK_BUILD_GUIDE.md # دليل البناء المفصل
120
+ ├── 📋 APK_README.md # دليل المستخدم
121
+ └── 📊 PROJECT_SUMMARY.md # هذا الملف
122
+ ```
123
+
124
+ ---
125
+
126
+ ## 🎯 **الميزات المتاحة في التطبيق**
127
+
128
+ ### **الأساسية:**
129
+ - 🔐 تس��يل دخول آمن (رقم هاتف + PIN)
130
+ - 💳 عرض 6 محافظ يمنية
131
+ - 🏠 واجهة رئيسية موحدة
132
+ - 🌙 دعم الوضع الليلي
133
+
134
+ ### **التقنية:**
135
+ - 📱 واجهة أصلية للأندرويد
136
+ - 🔄 عمل بدون إنترنت
137
+ - 💾 حفظ البيانات محلياً
138
+ - 🎨 رسوم متحركة سلسة
139
+
140
+ ### **الأمان:**
141
+ - 🛡️ تشفير البيانات
142
+ - 🔒 حماية PIN
143
+ - ⏰ انتهاء الجلسات
144
+ - 🚫 حماية من المحاولات المتكررة
145
+
146
+ ---
147
+
148
+ ## 🔮 **الميزات المستقبلية (جاهزة للتطوير)**
149
+
150
+ ### **قراءة SMS:**
151
+ - 📨 استخراج أرصدة المحافظ من الرسائل
152
+ - 🔄 تحديث الأرصدة تلقائياً
153
+ - 📊 تحليل أنماط الإنفاق
154
+
155
+ ### **المصادقة البيومترية:**
156
+ - 👆 بصمة الإصبع
157
+ - 👁️ التعرف على الوجه
158
+ - 🗣️ التعرف على الصوت
159
+
160
+ ### **الإشعارات الذكية:**
161
+ - 💰 تنبيهات الرصيد المنخفض
162
+ - 💸 تنبيهات الإنفاق الزائد
163
+ - 📅 تذكير دفع الفواتير
164
+
165
+ ---
166
+
167
+ ## 💰 **نموذج الربح المقترح**
168
+
169
+ ### **الإعلانات:**
170
+ - 📺 إعلانات مستهدفة بناءً على أنماط الإنفاق
171
+ - 🏪 شراكات مع المتاجر والخدمات
172
+ - 💳 عروض خاصة للمحافظ
173
+
174
+ ### **الاشتراكات:**
175
+ - 🆓 **مجاني:** الميزات الأساسية
176
+ - 💎 **مميز:** تحليل متقدم + بدون إعلانات
177
+ - 🏢 **تجاري:** ميزات للشركات
178
+
179
+ ### **العمولات:**
180
+ - 🤝 شراكات مع مقدمي الخدمات
181
+ - 🎁 كاش باك من المشتريات
182
+ - 💰 عمولات التحويلات
183
+
184
+ ---
185
+
186
+ ## 📈 **التوقعات**
187
+
188
+ ### **السنة الأولى:**
189
+ - 👥 **10,000 مستخدم** نشط
190
+ - 💰 **400,000 ر.ي** دخل متوقع
191
+ - 📱 **50,000 تحميل** من Google Play
192
+
193
+ ### **خطة النمو:**
194
+ 1. **الشهر 1-3:** إطلاق وتسويق أولي
195
+ 2. **الشهر 4-6:** إضافة ميزات SMS
196
+ 3. **الشهر 7-9:** تطوير الذكاء الاصطناعي
197
+ 4. **الشهر 10-12:** توسع إقليمي
198
+
199
+ ---
200
+
201
+ ## 🎊 **الخلاصة**
202
+
203
+ ### **تم إنجازه:**
204
+ ✅ **تطبيق ويب** محول إلى **تطبيق أندرويد**
205
+ ✅ **جميع الملفات** جاهزة للبناء
206
+ ✅ **التعليمات** مفصلة وواضحة
207
+ ✅ **الأذونات** معدة للميزات المستقبلية
208
+
209
+ ### **الخطوة التالية:**
210
+ 🔨 **بناء APK** باستخدام إحدى الطرق المذكورة
211
+
212
+ ### **النتيجة المتوقعة:**
213
+ 📱 **تطبيق أندرويد** جاهز للتثبيت والاستخدام
214
+
215
+ ---
216
+
217
+ **🎉 مبروك! مشروعك جاهز للانطلاق إلى العالم!**
218
+
219
+ *تطبيق محفظتي الموحدة - المدى للخدمات البرمجية التسويقية والإعلانية*
QUICK_APK_BUILD.bat ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @echo off
2
+ echo ========================================
3
+ echo محفظتي الموحدة - بناء APK سريع
4
+ echo ========================================
5
+ echo.
6
+
7
+ echo [1/5] التحقق من Java...
8
+ java -version
9
+ if %errorlevel% neq 0 (
10
+ echo ❌ Java غير مثبت! يرجى تثبيت Java JDK 11+
11
+ pause
12
+ exit /b 1
13
+ )
14
+ echo ✅ Java متوفر
15
+
16
+ echo.
17
+ echo [2/5] التحقق من Android SDK...
18
+ if not exist "%ANDROID_HOME%" (
19
+ echo ❌ Android SDK غير مثبت!
20
+ echo يرجى تثبيت Android Studio أو SDK Tools
21
+ echo أو تعيين متغير ANDROID_HOME
22
+ pause
23
+ exit /b 1
24
+ )
25
+ echo ✅ Android SDK متوفر
26
+
27
+ echo.
28
+ echo [3/5] نسخ ملفات التطبيق...
29
+ if not exist "www" mkdir www
30
+ copy index.html www\ >nul 2>&1
31
+ copy styles.css www\ >nul 2>&1
32
+ copy app.js www\ >nul 2>&1
33
+ copy auth.js www\ >nul 2>&1
34
+ copy wallets.js www\ >nul 2>&1
35
+ copy notifications.js www\ >nul 2>&1
36
+ copy demo.html www\ >nul 2>&1
37
+ copy src\manifest.json www\ >nul 2>&1
38
+ echo ✅ تم نسخ الملفات
39
+
40
+ echo.
41
+ echo [4/5] مزامنة Capacitor...
42
+ call cap sync android
43
+ if %errorlevel% neq 0 (
44
+ echo ❌ فشل في مزامنة Capacitor
45
+ pause
46
+ exit /b 1
47
+ )
48
+ echo ✅ تم مزامنة Capacitor
49
+
50
+ echo.
51
+ echo [5/5] بناء APK...
52
+ cd android
53
+ call gradlew assembleDebug
54
+ if %errorlevel% neq 0 (
55
+ echo ❌ فشل في بناء APK
56
+ echo يرجى مراجعة الأخطاء أعلاه
57
+ pause
58
+ exit /b 1
59
+ )
60
+
61
+ echo.
62
+ echo ========================================
63
+ echo 🎉 تم بناء APK بنجاح!
64
+ echo ========================================
65
+ echo.
66
+ echo 📱 ملف APK متوفر في:
67
+ echo android\app\build\outputs\apk\debug\app-debug.apk
68
+ echo.
69
+ echo 📋 الخطوات التالية:
70
+ echo 1. نسخ APK إلى الهاتف
71
+ echo 2. تفعيل "مصادر غير معروفة" في الإعدادات
72
+ echo 3. تثبيت APK
73
+ echo 4. اختبار التطبيق
74
+ echo.
75
+ echo 🔑 بيانات التجربة:
76
+ echo رقم الهاتف: 777123456
77
+ echo رمز PIN: 1234
78
+ echo.
79
+ pause
QUICK_START.md ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # البدء السريع - محفظتي الموحدة
2
+
3
+ ## 🚀 تشغيل التطبيق في 5 دقائق
4
+
5
+ ### المتطلبات الأساسية
6
+ - Node.js (الإصدار 18+)
7
+ - npm أو yarn
8
+
9
+ ### خطوات سريعة
10
+
11
+ #### 1. تثبيت الأدوات
12
+ ```bash
13
+ npm install -g @ionic/cli @angular/cli @capacitor/cli
14
+ ```
15
+
16
+ #### 2. إعداد المشروع
17
+ ```bash
18
+ cd almada
19
+ npm install
20
+ ```
21
+
22
+ #### 3. تشغيل التطبيق
23
+ ```bash
24
+ ionic serve
25
+ ```
26
+
27
+ #### 4. فتح المتصفح
28
+ انتقل إلى: http://localhost:8100
29
+
30
+ ### 📱 بناء تطبيق الجوال
31
+
32
+ #### للأندرويد:
33
+ ```bash
34
+ ionic build --prod
35
+ ionic cap add android
36
+ ionic cap open android
37
+ ```
38
+
39
+ #### لـ iOS:
40
+ ```bash
41
+ ionic build --prod
42
+ ionic cap add ios
43
+ ionic cap open ios
44
+ ```
45
+
46
+ ## 🔑 بيانات التجربة
47
+
48
+ - **رقم الهاتف**: 777123456
49
+ - **رمز PIN**: 1234
50
+
51
+ ## 📋 الميزات المتاحة
52
+
53
+ ✅ تسجيل دخول آمن
54
+ ✅ عرض المحافظ والأرصدة
55
+ ✅ تحويل الأموال
56
+ ✅ إشعارات فورية
57
+ ✅ مصادقة بيومترية
58
+ ✅ واجهة عربية كاملة
59
+
60
+ ## 🛠️ استكشاف الأخطاء
61
+
62
+ ### مشكلة: خطأ في npm install
63
+ ```bash
64
+ npm cache clean --force
65
+ rm -rf node_modules
66
+ npm install
67
+ ```
68
+
69
+ ### مشكلة: خطأ في ionic serve
70
+ ```bash
71
+ ionic repair
72
+ ionic serve --verbose
73
+ ```
74
+
75
+ ### مشكلة: خطأ في Capacitor
76
+ ```bash
77
+ npx cap sync
78
+ npx cap doctor
79
+ ```
80
+
81
+ ## 📚 روابط مفيدة
82
+
83
+ - [تعليمات البناء الكاملة](BUILD_INSTRUCTIONS.md)
84
+ - [وثائق Ionic](https://ionicframework.com/docs)
85
+ - [وثائق Angular](https://angular.io/docs)
86
+ - [وثائق Capacitor](https://capacitorjs.com/docs)
87
+
88
+ ## 💡 نصائح
89
+
90
+ 1. **للتطوير السريع**: استخدم `ionic serve --lab`
91
+ 2. **لاختبار الجوال**: استخدم `ionic cap run android --livereload`
92
+ 3. **للتصحيح**: افتح Developer Tools في المتصفح
93
+ 4. **للأداء**: استخدم `ionic build --prod` للإنتاج
94
+
95
+ ## 🎯 الخطوات التالية
96
+
97
+ 1. جرب تسجيل الدخول
98
+ 2. استكشف المحافظ المختلفة
99
+ 3. جرب التحويلات
100
+ 4. اختبر الإشعارات
101
+ 5. جرب المصادقة البيومترية (في التطبيق الأصلي)
102
+
103
+ ---
104
+
105
+ **🎉 مبروك! تطبيقك جاهز للاستخدام**
106
+
107
+ للمساعدة أو الاستفسارات، راجع الوثائق الكاملة أو تواصل مع فريق التطوير.
README.md CHANGED
@@ -1,3 +1,262 @@
1
- ---
2
- license: deepfloyd-if-license
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية الموحد
2
+
3
+ ## نظرة عامة
4
+
5
+ **محفظتي الموحدة** هو تطبيق جوال متطور مبني بتقنية Ionic/Angular يجمع جميع المحافظ الإلكترونية اليمنية في واجهة موحدة، مما يتيح للمستخدمين إدارة جميع محافظهم من مكان واحد باستخدام رقم هاتف موحد.
6
+
7
+ ## 📱 **التطبيق متاح الآن كـ:**
8
+ - **تطبيق أندرويد** (APK)
9
+ - **تطبيق iOS** (IPA)
10
+ - **تطبيق ويب** (PWA)
11
+ - **تطبيق سطح المكتب** (عبر Electron)
12
+
13
+ ## المحافظ المدعومة
14
+
15
+ التطبيق يدعم المحافظ الإلكترونية اليمنية التالية:
16
+
17
+ 1. **جوالي (Jawali)** - من WeCash YE
18
+ 2. **ONE Cash** - المحفظة الرقمية الأولى في اليمن
19
+ 3. **Cash** - من Tamkeen Financial
20
+ 4. **Jaib Digital Wallet** - من AHD Financial
21
+ 5. **mFloos** - من Alkuraimi Islamic Microfinance Bank
22
+ 6. **Mobile Money Wallet** - من CAC Bank
23
+
24
+ ## الميزات الرئيسية
25
+
26
+ ### 🔐 نظام أمان متقدم
27
+ - تسجيل دخول برقم الهاتف ورمز PIN
28
+ - مصادقة بيومترية (بصمة الإصبع)
29
+ - حماية من المحاولات المتكررة
30
+ - جلسات آمنة مع انتهاء صلاحية تلقائي
31
+
32
+ ### 💸 إدارة المحافظ
33
+ - عرض جميع المحافظ في واجهة موحدة
34
+ - عرض الأرصدة الإجمالية والفردية
35
+ - تحديث الأرصدة في الوقت الفعلي
36
+ - إخفاء/إظهار الأرصدة للخصوصية
37
+
38
+ ### 🔄 التحويلات والمدفوعات
39
+ - تحويل الأموال بين المحافظ المختلفة
40
+ - دفع الفواتير (كهرباء، مياه، إنترنت)
41
+ - شحن أرصدة الهواتف
42
+ - مسح رموز QR للدفع
43
+
44
+ ### 📱 واجهة مستخدم عصرية
45
+ - تصميم متجاوب يعمل على جميع الأجهزة
46
+ - واجهة باللغة العربية مع دعم RTL
47
+ - رسوم متحركة سلسة
48
+ - تجربة مستخدم بديهية
49
+
50
+ ### 🔔 نظام إشعارات متطور
51
+ - إشعارات فورية للمعاملات
52
+ - تنبيهات أمنية
53
+ - إشعارات النظام
54
+ - إدارة الإشعارات المقروءة وغير المقروءة
55
+
56
+ ## التقنيات المستخدمة
57
+
58
+ ### Frontend Framework
59
+ - **Ionic 7** - إطار عمل التطبيقات الهجينة
60
+ - **Angular 17** - إطار عمل الواجهة الأمامية
61
+ - **TypeScript** - لغة البرمجة الأساسية
62
+ - **SCSS** - معالج CSS المتقدم
63
+
64
+ ### Mobile Development
65
+ - **Capacitor 5** - منصة التطبيقات الأصلية
66
+ - **Cordova Plugins** - الوصول لميزات الجهاز
67
+ - **PWA** - تطبيق ويب تقدمي
68
+
69
+ ### Backend & Storage
70
+ - **Ionic Storage** - تخزين البيانات المحلية
71
+ - **RxJS** - إدارة البيانات التفاعلية
72
+ - **HTTP Client** - التواصل مع APIs
73
+
74
+ ### UI/UX
75
+ - **Ionic Components** - مكونات واجهة المستخدم
76
+ - **Ionicons** - مكتبة الأيقونات
77
+ - **Google Fonts** - خط Tajawal العربي
78
+ - **CSS Animations** - الرسوم المتحركة
79
+
80
+ ### Development Tools
81
+ - **Angular CLI** - أدوات التطوير
82
+ - **Capacitor CLI** - أدوات البناء للجوال
83
+ - **ESLint** - فحص جودة الكود
84
+ - **Prettier** - تنسيق الكود
85
+
86
+ ## هيكل المشروع
87
+
88
+ ```
89
+ almada/
90
+ ├── src/ # مجلد المصدر الرئيسي
91
+ │ ├── app/ # تطبيق Angular
92
+ │ │ ├── pages/ # صفحات التطبيق
93
+ │ │ │ ├── login/ # صفحة تسجيل الدخول
94
+ │ │ │ ├── home/ # الصفحة الرئيسية
95
+ │ │ │ ├── wallets/ # صفحة المحافظ
96
+ │ │ │ ├── transfer/ # صفحة التحويلات
97
+ │ │ │ └── ... # باقي الصفحات
98
+ │ │ ├── services/ # الخدمات
99
+ │ │ │ ├── auth.service.ts # خدمة المصادقة
100
+ │ │ │ ├── wallet.service.ts # خدمة المحافظ
101
+ │ │ │ └── ... # باقي الخدمات
102
+ │ │ ├── guards/ # حراس الحماية
103
+ │ │ └── components/ # المكونات المشتركة
104
+ │ ├── assets/ # الملفات الثابتة
105
+ │ ├── theme/ # ملفات الثيم
106
+ │ └── environments/ # إعدادات البيئة
107
+ ├── android/ # مشروع الأندرويد
108
+ ├── ios/ # مشروع iOS
109
+ ├── capacitor.config.ts # إعدادات Capacitor
110
+ ├── ionic.config.json # إعدادات Ionic
111
+ ├── angular.json # إعدادات Angular
112
+ ├── package.json # تبعيات المشروع
113
+ ├── BUILD_INSTRUCTIONS.md # تعليمات البناء
114
+ └── README.md # هذا الملف
115
+ ```
116
+
117
+ ## كيفية التشغيل
118
+
119
+ ### 1. تشغيل للتطوير
120
+
121
+ ```bash
122
+ # استنساخ المشروع
123
+ git clone [repository-url]
124
+ cd almada
125
+
126
+ # تثبيت التبعيات
127
+ npm install
128
+
129
+ # تشغيل خادم التطوير
130
+ ionic serve
131
+
132
+ # فتح المتصفح على
133
+ http://localhost:8100
134
+ ```
135
+
136
+ ### 2. بناء التطبيق للجوال
137
+
138
+ ```bash
139
+ # بناء المشروع
140
+ ionic build --prod
141
+
142
+ # إضافة منصة الأندرويد
143
+ ionic cap add android
144
+
145
+ # إضافة منصة iOS
146
+ ionic cap add ios
147
+
148
+ # بناء APK للأندرويد
149
+ ionic cap build android
150
+
151
+ # بناء IPA لـ iOS
152
+ ionic cap build ios
153
+ ```
154
+
155
+ ### 3. تشغيل على الأجهزة
156
+
157
+ ```bash
158
+ # تشغيل على الأندرويد
159
+ ionic cap run android
160
+
161
+ # تشغيل على iOS
162
+ ionic cap run ios
163
+
164
+ # تشغيل في المتصفح مع إعادة التحميل
165
+ ionic serve --lab
166
+ ```
167
+
168
+ راجع ملف [BUILD_INSTRUCTIONS.md](BUILD_INSTRUCTIONS.md) للتفاصيل الكاملة.
169
+
170
+ ## بيانات التجربة
171
+
172
+ للاختبار، يمكن استخدام البيانات التالية:
173
+
174
+ - **رقم الهاتف**: أي رقم يمني صحيح (9 أرقام)
175
+ - **رمز PIN**: أي رمز من 4-6 أرقام
176
+ - **مثال**: 777123456 / 1234
177
+
178
+ ## الاستخدام
179
+
180
+ ### تسجيل الدخول
181
+ 1. أدخل رقم الهاتف (9 أرقام)
182
+ 2. أدخل رمز PIN (4-6 أرقام)
183
+ 3. أو استخدم المصادقة البيومترية
184
+
185
+ ### إدارة المحافظ
186
+ - عرض جميع المحافظ والأرصدة
187
+ - تحديث الأرصدة
188
+ - إخفاء/إظهار الأرصدة
189
+
190
+ ### التحويلات
191
+ 1. اختر المحفظة المرسلة
192
+ 2. أدخل تفاصيل التحويل
193
+ 3. أكد بـ PIN
194
+
195
+ ### الإشعارات
196
+ - عرض الإشعارات من الأيقونة في الأعلى
197
+ - وضع علامة مقروء
198
+ - حذف الإشعارات
199
+
200
+ ## الأمان
201
+
202
+ التطبيق يتضمن عدة طبقات أمان:
203
+
204
+ - **تشفير البيانات**: جميع البيانات الحساسة مشفرة
205
+ - **جلسات آمنة**: انتهاء صلاحية تلقائي للجلسات
206
+ - **حماية من الهجمات**: حماية من المحاولات المتكررة
207
+ - **مصادقة متعددة**: PIN + بصمة
208
+ - **تخزين آمن**: استخدام Local Storage بشكل آمن
209
+
210
+ ## ملاحظات مهمة
211
+
212
+ ⚠️ **هذا تطبيق تجريبي لأغراض العرض فقط**
213
+
214
+ - جميع البيانات والمعاملات محاكاة
215
+ - لا يؤثر على الحسابات الحقيقية
216
+ - البيانات محفوظة محلياً في المتصفح
217
+ - يتطلب متصفح حديث للمصادقة البيومترية
218
+
219
+ ## التطوير المستقبلي
220
+
221
+ ### الميزات المخطط لها
222
+ - [ ] دعم المزيد من المحافظ
223
+ - [ ] تطبيق جوال أصلي
224
+ - [ ] تكامل مع APIs الحقيقية
225
+ - [ ] نظام إحصائيات متقدم
226
+ - [ ] دعم العملات المتعددة
227
+ - [ ] نظام النسخ الاحتياطي
228
+
229
+ ### التحسينات التقنية
230
+ - [ ] PWA (Progressive Web App)
231
+ - [ ] وضع عدم الاتصال
232
+ - [ ] تحسين الأداء
233
+ - [ ] اختبارات تلقائية
234
+ - [ ] CI/CD Pipeline
235
+
236
+ ## المساهمة
237
+
238
+ نرحب بالمساهمات! يرجى:
239
+
240
+ 1. Fork المشروع
241
+ 2. إنشاء branch للميزة الجديدة
242
+ 3. Commit التغييرات
243
+ 4. Push إلى Branch
244
+ 5. فتح Pull Request
245
+
246
+ ## الترخيص
247
+
248
+ هذا المشروع مرخص تحت رخصة MIT - انظر ملف [LICENSE](LICENSE) للتفاصيل.
249
+
250
+ ## التواصل
251
+
252
+ **المدى للخدمات البرمجية التسويقية والإعلانية**
253
+ - المدير العام: المهندس/ محمد المرتضى
254
+ - © 2025 جميع الحقوق محفوظة
255
+
256
+ ## الدعم
257
+
258
+ للدعم التقني أو الاستفسارات، يرجى فتح issue في المستودع أو التواصل مع فريق التطوير.
259
+
260
+ ---
261
+
262
+ **شكراً لاستخدام محفظتي الموحدة! 🚀**
README_GITHUB.md ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📱 محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية
2
+
3
+ [![🚀 Build APK](https://github.com/USERNAME/almada-unified-wallet/actions/workflows/build-apk.yml/badge.svg)](https://github.com/USERNAME/almada-unified-wallet/actions/workflows/build-apk.yml)
4
+ [![📱 Download APK](https://img.shields.io/badge/Download-APK-green.svg)](https://github.com/USERNAME/almada-unified-wallet/releases/latest)
5
+
6
+ ## 🎯 **نظرة عامة**
7
+
8
+ **محفظتي الموحدة** هو تطبيق أندرويد متطور يجمع جميع المحافظ الإلكترونية اليمنية في واجهة موحدة، مما يتيح للمستخدمين إدارة جميع محافظهم من مكان واحد.
9
+
10
+ ## 📱 **تحميل التطبيق**
11
+
12
+ ### 🚀 **أحدث إصدار:**
13
+ [![📥 تحميل APK](https://img.shields.io/badge/تحميل-APK-blue.svg?style=for-the-badge)](https://github.com/USERNAME/almada-unified-wallet/releases/latest/download/app-debug.apk)
14
+
15
+ ### 🔄 **البناء التلقائي:**
16
+ - يتم بناء APK تلقائياً عند كل تحديث
17
+ - متوفر في قسم [Actions](https://github.com/USERNAME/almada-unified-wallet/actions)
18
+ - تحميل مباشر من [Releases](https://github.com/USERNAME/almada-unified-wallet/releases)
19
+
20
+ ## 🎯 **الميزات**
21
+
22
+ ### ✅ **المتاحة حالياً:**
23
+ - 🔐 تسجيل دخول آمن برقم الهاتف + PIN
24
+ - 💳 عرض 6 محافظ يمنية رئيسية:
25
+ - جوالي (Jawali)
26
+ - ONE Cash
27
+ - Cash
28
+ - Aman
29
+ - Tadawul
30
+ - Al-Kuraimi
31
+ - 🏠 واجهة موحدة لجميع المحافظ
32
+ - 🌙 دعم الوضع الليلي
33
+ - 🔄 واجهة عربية كاملة (RTL)
34
+ - 📱 تصميم متجاوب لجميع أحجام الشاشات
35
+
36
+ ### 🔄 **قيد التطوير:**
37
+ - 📨 قراءة رسائل SMS لاستخراج الأرصدة
38
+ - 👆 مصادقة بيومترية (بصمة/وجه)
39
+ - 🔔 إشعارات ذكية ومخصصة
40
+ - 📊 تحليل أنماط الإنفاق والتوفير
41
+ - 💰 اقتراحات التوفير الذكية
42
+
43
+ ## 🔑 **بيانات التجربة**
44
+
45
+ للدخول إلى التطبيق:
46
+ - **رقم الهاتف:** `777123456`
47
+ - **رمز PIN:** `1234`
48
+
49
+ ## 🛠️ **التقنيات المستخدمة**
50
+
51
+ - **Frontend:** HTML5, CSS3, JavaScript (ES6+)
52
+ - **Mobile Framework:** Capacitor 5
53
+ - **Build System:** Gradle
54
+ - **CI/CD:** GitHub Actions
55
+ - **Platform:** Android (API 24+)
56
+
57
+ ## 📲 **التثبيت**
58
+
59
+ ### **من GitHub Releases:**
60
+ 1. اذهب إلى [Releases](https://github.com/USERNAME/almada-unified-wallet/releases)
61
+ 2. حمل أحدث ملف APK
62
+ 3. في الهاتف: فعل "مصادر غير معروفة"
63
+ 4. ثبت التطبيق
64
+
65
+ ### **من GitHub Actions:**
66
+ 1. اذهب إلى [Actions](https://github.com/USERNAME/almada-unified-wallet/actions)
67
+ 2. اختر آخر build ناجح
68
+ 3. حمل APK من Artifacts
69
+
70
+ ## 🏗️ **البناء المحلي**
71
+
72
+ ```bash
73
+ # استنساخ المشروع
74
+ git clone https://github.com/USERNAME/almada-unified-wallet.git
75
+ cd almada-unified-wallet
76
+
77
+ # تثبيت التبعيات
78
+ npm install
79
+
80
+ # بناء للأندرويد
81
+ npx cap sync android
82
+ cd android
83
+ ./gradlew assembleDebug
84
+ ```
85
+
86
+ ## 📊 **معلومات التطبيق**
87
+
88
+ | المعلومة | القيمة |
89
+ |---------|--------|
90
+ | **اسم التطبيق** | محفظتي الموحدة |
91
+ | **Package ID** | com.almada.unifiedwallet |
92
+ | **الإصدار** | 1.0.0 |
93
+ | **حجم APK** | ~15-20 MB |
94
+ | **الحد الأدنى** | Android 7.0 (API 24) |
95
+ | **اللغة** | العربية (RTL) |
96
+
97
+ ## 🤝 **المساهمة**
98
+
99
+ نرحب بالمساهمات! يرجى:
100
+ 1. Fork المشروع
101
+ 2. إنشاء branch للميزة الجديدة
102
+ 3. Commit التغييرات
103
+ 4. Push إلى Branch
104
+ 5. فتح Pull Request
105
+
106
+ ## 📄 **الترخيص**
107
+
108
+ هذا المشروع مرخص تحت رخصة MIT - راجع ملف [LICENSE](LICENSE) للتفاصيل.
109
+
110
+ ## 📞 **التواصل**
111
+
112
+ - **الشركة:** المدى للخدمات البرمجية التسويقية والإعلانية
113
+ - **الموقع:** https://almada.com
114
+ - **البريد الإلكتروني:** info@almada.com
115
+
116
+ ## 🎉 **شكر خاص**
117
+
118
+ شكر خاص لجميع مطوري المحافظ الإلكترونية اليمنية والمجتمع التقني اليمني.
119
+
120
+ ---
121
+
122
+ **🚀 مبروك! تطبيقك متاح للعالم!**
123
+
124
+ *Made with ❤️ in Yemen*
STEP_BY_STEP_APK.md ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📱 دليل بناء APK خطوة بخطوة - مصور
2
+
3
+ ## 🎯 **الهدف:** الحصول على ملف APK جاهز للتثبيت في 15 دقيقة
4
+
5
+ ---
6
+
7
+ ## 🚀 **الطريقة الأسرع: ملف BAT التلقائي**
8
+
9
+ ### **الخطوة 1: تشغيل الملف التلقائي**
10
+ 1. **اذهب إلى مجلد المشروع:** `E:\almada`
11
+ 2. **اضغط مرتين على:** `BUILD_APK_SIMPLE.bat`
12
+ 3. **انتظر اكتمال العملية** (5-10 دقائق)
13
+
14
+ ### **إذا نجحت العملية:**
15
+ - ✅ ستفتح نافذة تحتوي على ملف APK
16
+ - ✅ الملف سيكون: `app-debug.apk`
17
+ - ✅ انسخه إلى هاتفك وثبته
18
+
19
+ ### **إذا فشلت العملية:**
20
+ - ❌ انتقل للطريقة الثانية أدناه
21
+
22
+ ---
23
+
24
+ ## 🏗️ **الطريقة الثانية: Android Studio (مضمونة 100%)**
25
+
26
+ ### **الخطوة 1: فتح Android Studio**
27
+ ```
28
+ 1. افتح Android Studio
29
+ 2. اختر "Open an Existing Project"
30
+ 3. انتقل إلى: E:\almada\android
31
+ 4. اختر مجلد android واضغط OK
32
+ ```
33
+
34
+ ### **الخطوة 2: انتظار التحميل**
35
+ ```
36
+ ⏳ انتظر رسالة: "Gradle sync finished"
37
+ 📦 قد يستغرق 5-10 دقائق في المرة الأولى
38
+ 🌐 تأكد من اتصال الإنترنت
39
+ ```
40
+
41
+ ### **الخطوة 3: بناء APK**
42
+ ```
43
+ 1. في القائمة العلوية: Build
44
+ 2. اختر: Build Bundle(s) / APK(s)
45
+ 3. اختر: Build APK(s)
46
+ 4. انتظر رسالة: "APK(s) generated successfully"
47
+ ```
48
+
49
+ ### **الخطوة 4: العثور على APK**
50
+ ```
51
+ 📂 المسار: E:\almada\android\app\build\outputs\apk\debug\
52
+ 📱 الملف: app-debug.apk
53
+ 💾 الحجم: ~15-20 MB
54
+ ```
55
+
56
+ ---
57
+
58
+ ## 📲 **تثبيت التطبيق على الهاتف**
59
+
60
+ ### **الطريقة 1: نسخ مباشر**
61
+ 1. **انسخ ملف APK** إلى هاتفك (عبر USB أو البلوتوث)
62
+ 2. **في الهاتف:** Settings > Security > Install from Unknown Sources ✅
63
+ 3. **اضغط على ملف APK** واختر Install
64
+ 4. **انتظر اكتمال التثبيت**
65
+
66
+ ### **الطريقة 2: ADB (للمتقدمين)**
67
+ ```bash
68
+ # وصل الهاتف بـ USB وفعل USB Debugging
69
+ adb install app-debug.apk
70
+ ```
71
+
72
+ ---
73
+
74
+ ## 🔑 **اختبار التطبيق**
75
+
76
+ بعد التثبيت:
77
+ 1. **افتح التطبيق:** "محفظتي الموحدة"
78
+ 2. **أدخل البيانات:**
79
+ - رقم الهاتف: `777123456`
80
+ - رمز PIN: `1234`
81
+ 3. **استكشف الميزات:**
82
+ - عرض المحافظ
83
+ - التنقل بين الصفحات
84
+ - اختبار الواجهة العربية
85
+
86
+ ---
87
+
88
+ ## 🆘 **حل المشاكل الشائعة**
89
+
90
+ ### **مشكلة: "App not installed"**
91
+ ```
92
+ الحل:
93
+ 1. تأكد من تفعيل "Install from Unknown Sources"
94
+ 2. احذف أي إصدار قديم من التطبيق
95
+ 3. أعد تشغيل الهاتف وحاول مرة أخرى
96
+ ```
97
+
98
+ ### **مشكلة: "Parse error"**
99
+ ```
100
+ الحل:
101
+ 1. تأكد من أن ملف APK غير تالف
102
+ 2. أعد تحميل/نسخ الملف
103
+ 3. تأكد من توافق إصدار الأندرويد (7.0+)
104
+ ```
105
+
106
+ ### **مشكلة: "Gradle build failed"**
107
+ ```
108
+ الحل:
109
+ 1. تأكد من اتصال الإنترنت
110
+ 2. في Android Studio: Build > Clean Project
111
+ 3. ثم: Build > Rebuild Project
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 📊 **معلومات التطبيق النهائي**
117
+
118
+ | المعلومة | القيمة |
119
+ |---------|--------|
120
+ | **اسم التطبيق** | محفظتي الموحدة |
121
+ | **Package Name** | com.almada.unifiedwallet |
122
+ | **الإصدار** | 1.0.0 |
123
+ | **حجم APK** | ~15-20 MB |
124
+ | **الحد الأدنى** | Android 7.0 (API 24) |
125
+ | **اللغة** | العربية (RTL) |
126
+ | **النوع** | Debug APK |
127
+
128
+ ---
129
+
130
+ ## 🎯 **الميزات المتاحة**
131
+
132
+ ### **الحالية:**
133
+ - ✅ تسجيل دخول آمن
134
+ - ✅ عرض 6 محافظ يمنية
135
+ - ✅ واجهة عربية كاملة
136
+ - ✅ تصميم متجاوب
137
+ - ✅ حفظ البيانات محلياً
138
+
139
+ ### **المستقبلية:**
140
+ - 🔄 قراءة رسائل SMS
141
+ - 🔄 مصادقة بيومترية
142
+ - 🔄 إشعارات ذكية
143
+ - 🔄 تحليل الإنفاق
144
+
145
+ ---
146
+
147
+ ## 💡 **نصائح مهمة**
148
+
149
+ ### **للبناء الناجح:**
150
+ - 🌐 تأكد من **اتصال الإنترنت** القوي
151
+ - ⏰ **لا تقاطع** عملية التحميل
152
+ - 💾 تأكد من **مساحة كافية** (5+ GB)
153
+
154
+ ### **للاختبار:**
155
+ - 📱 اختبر على **أجهزة مختلفة**
156
+ - 🔄 اختبر **جميع الميزات**
157
+ - 📊 راقب **الأداء**
158
+
159
+ ### **للمشاركة:**
160
+ - 📤 يمكنك **مشاركة APK** مع الآخرين
161
+ - 🔒 هذا **إصدار تجريبي** (Debug)
162
+ - 🏪 للنشر في Google Play تحتاج **إصدار Release**
163
+
164
+ ---
165
+
166
+ ## 🎉 **تهانينا!**
167
+
168
+ عند اكتمال هذه الخطوات، ستحصل على:
169
+ - 📱 **تطبيق أندرويد** كامل وجاهز
170
+ - 💼 **محفظة موحدة** لجميع المحافظ اليمنية
171
+ - �� **واجهة احترافية** باللغة العربية
172
+ - 🔒 **نظام أمان** متقدم
173
+
174
+ **🚀 مبروك! تطبيقك جاهز للعالم!**
175
+
176
+ ---
177
+
178
+ ## 📞 **تحتاج مساعدة؟**
179
+
180
+ إذا واجهت أي مشكلة:
181
+ 1. راجع قسم "حل المشاكل" أعلاه
182
+ 2. تأكد من اتباع الخطوات بالترتيب
183
+ 3. تواصل للحصول على المساعدة
184
+
185
+ **💪 لا تستسلم - النجاح قريب!**
Windows ADDED
@@ -0,0 +1 @@
 
 
1
+ اختر: "Command line tools only"
angular.json ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "newProjectRoot": "projects",
5
+ "projects": {
6
+ "unified-wallet-app": {
7
+ "projectType": "application",
8
+ "schematics": {
9
+ "@ionic/angular-toolkit:component": {
10
+ "styleext": "scss"
11
+ },
12
+ "@ionic/angular-toolkit:page": {
13
+ "styleext": "scss"
14
+ }
15
+ },
16
+ "root": "",
17
+ "sourceRoot": "src",
18
+ "prefix": "app",
19
+ "architect": {
20
+ "build": {
21
+ "builder": "@angular-devkit/build-angular:browser",
22
+ "options": {
23
+ "outputPath": "dist/unified-wallet-app",
24
+ "index": "src/index.html",
25
+ "main": "src/main.ts",
26
+ "polyfills": [
27
+ "zone.js"
28
+ ],
29
+ "tsConfig": "tsconfig.app.json",
30
+ "inlineStyleLanguage": "scss",
31
+ "assets": [
32
+ {
33
+ "glob": "**/*",
34
+ "input": "src/assets",
35
+ "output": "assets"
36
+ },
37
+ {
38
+ "glob": "**/*.svg",
39
+ "input": "node_modules/ionicons/dist/ionicons/svg",
40
+ "output": "./svg"
41
+ }
42
+ ],
43
+ "styles": [
44
+ "src/theme/variables.scss",
45
+ "src/global.scss"
46
+ ],
47
+ "scripts": []
48
+ },
49
+ "configurations": {
50
+ "production": {
51
+ "budgets": [
52
+ {
53
+ "type": "initial",
54
+ "maximumWarning": "2mb",
55
+ "maximumError": "5mb"
56
+ },
57
+ {
58
+ "type": "anyComponentStyle",
59
+ "maximumWarning": "2kb",
60
+ "maximumError": "4kb"
61
+ }
62
+ ],
63
+ "outputHashing": "all"
64
+ },
65
+ "development": {
66
+ "buildOptimizer": false,
67
+ "optimization": false,
68
+ "vendorChunk": true,
69
+ "extractLicenses": false,
70
+ "sourceMap": true,
71
+ "namedChunks": true
72
+ }
73
+ },
74
+ "defaultConfiguration": "production"
75
+ },
76
+ "serve": {
77
+ "builder": "@angular-devkit/build-angular:dev-server",
78
+ "configurations": {
79
+ "production": {
80
+ "buildTarget": "unified-wallet-app:build:production"
81
+ },
82
+ "development": {
83
+ "buildTarget": "unified-wallet-app:build:development"
84
+ }
85
+ },
86
+ "defaultConfiguration": "development"
87
+ },
88
+ "extract-i18n": {
89
+ "builder": "@angular-devkit/build-angular:extract-i18n",
90
+ "options": {
91
+ "buildTarget": "unified-wallet-app:build"
92
+ }
93
+ },
94
+ "test": {
95
+ "builder": "@angular-devkit/build-angular:karma",
96
+ "options": {
97
+ "polyfills": [
98
+ "zone.js",
99
+ "zone.js/testing"
100
+ ],
101
+ "tsConfig": "tsconfig.spec.json",
102
+ "inlineStyleLanguage": "scss",
103
+ "assets": [
104
+ {
105
+ "glob": "**/*",
106
+ "input": "src/assets",
107
+ "output": "assets"
108
+ },
109
+ {
110
+ "glob": "**/*.svg",
111
+ "input": "node_modules/ionicons/dist/ionicons/svg",
112
+ "output": "./svg"
113
+ }
114
+ ],
115
+ "styles": [
116
+ "src/theme/variables.scss",
117
+ "src/global.scss"
118
+ ],
119
+ "scripts": []
120
+ }
121
+ },
122
+ "lint": {
123
+ "builder": "@angular-eslint/builder:lint",
124
+ "options": {
125
+ "lintFilePatterns": [
126
+ "src/**/*.ts",
127
+ "src/**/*.html"
128
+ ]
129
+ }
130
+ }
131
+ }
132
+ }
133
+ },
134
+ "cli": {
135
+ "schematicCollections": [
136
+ "@ionic/angular-toolkit"
137
+ ]
138
+ },
139
+ "schematics": {
140
+ "@ionic/angular-toolkit:component": {
141
+ "styleext": "scss"
142
+ },
143
+ "@ionic/angular-toolkit:page": {
144
+ "styleext": "scss"
145
+ }
146
+ }
147
+ }
app.js ADDED
@@ -0,0 +1,780 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // التطبيق الرئيسي - محفظتي الموحدة
2
+ class UnifiedWalletApp {
3
+ constructor() {
4
+ this.currentUser = null;
5
+ this.currentScreen = 'login';
6
+ this.wallets = [];
7
+ this.transactions = [];
8
+ this.isBalanceHidden = false;
9
+
10
+ // تهيئة المدراء
11
+ this.authManager = new AuthenticationManager();
12
+ this.walletManager = new WalletManager();
13
+ this.notificationManager = new NotificationManager();
14
+
15
+ this.init();
16
+ }
17
+
18
+ // تهيئة التطبيق
19
+ init() {
20
+ this.setupEventListeners();
21
+ this.loadUserData();
22
+ this.showLoadingScreen();
23
+
24
+ // محاكاة تحميل البيانات
25
+ setTimeout(() => {
26
+ this.hideLoadingScreen();
27
+ this.checkAuthStatus();
28
+ }, 2000);
29
+ }
30
+
31
+ // إعداد مستمعي الأحداث
32
+ setupEventListeners() {
33
+ // تسجيل الدخول
34
+ document.getElementById('login-btn').addEventListener('click', () => this.handleLogin());
35
+ document.getElementById('biometric-login').addEventListener('click', () => this.handleBiometricLogin());
36
+ document.getElementById('register-link').addEventListener('click', (e) => {
37
+ e.preventDefault();
38
+ this.showRegisterModal();
39
+ });
40
+
41
+ // الشاشة الرئيسية
42
+ document.getElementById('refresh-balance').addEventListener('click', () => this.refreshBalances());
43
+ document.getElementById('hide-balance').addEventListener('click', () => this.toggleBalanceVisibility());
44
+
45
+ // الإجراءات السريعة
46
+ document.getElementById('transfer-btn').addEventListener('click', () => this.showTransferScreen());
47
+ document.getElementById('pay-bills-btn').addEventListener('click', () => this.showBillsScreen());
48
+ document.getElementById('recharge-btn').addEventListener('click', () => this.showRechargeScreen());
49
+ document.getElementById('qr-scan-btn').addEventListener('click', () => this.startQRScan());
50
+
51
+ // شريط التنقل
52
+ document.querySelectorAll('.nav-item').forEach(item => {
53
+ item.addEventListener('click', () => {
54
+ const screen = item.dataset.screen;
55
+ this.switchScreen(screen);
56
+ });
57
+ });
58
+
59
+ // أزرار الإعدادات والإشعارات
60
+ document.getElementById('settings-btn').addEventListener('click', () => this.showSettings());
61
+ document.getElementById('notifications-btn').addEventListener('click', () => this.showNotifications());
62
+
63
+ // أزرار الإدارة
64
+ document.getElementById('manage-wallets').addEventListener('click', () => this.showWalletManagement());
65
+ document.getElementById('view-all-transactions').addEventListener('click', () => this.showAllTransactions());
66
+
67
+ // أزرار الرجوع
68
+ document.getElementById('transfer-back').addEventListener('click', () => this.switchScreen('main'));
69
+
70
+ // شاشة التحويل
71
+ this.setupTransferScreen();
72
+
73
+ // إدخال رقم الهاتف
74
+ document.getElementById('phone-number').addEventListener('input', this.formatPhoneNumber);
75
+ document.getElementById('pin-code').addEventListener('keypress', (e) => {
76
+ if (e.key === 'Enter') this.handleLogin();
77
+ });
78
+ }
79
+
80
+ // عرض شاشة التحميل
81
+ showLoadingScreen() {
82
+ document.getElementById('loading-screen').style.display = 'flex';
83
+ }
84
+
85
+ // إخفاء شاشة التحميل
86
+ hideLoadingScreen() {
87
+ document.getElementById('loading-screen').style.display = 'none';
88
+ }
89
+
90
+ // فحص حالة المصادقة
91
+ checkAuthStatus() {
92
+ const savedUser = localStorage.getItem('unifiedWallet_user');
93
+ if (savedUser) {
94
+ this.currentUser = JSON.parse(savedUser);
95
+ this.switchScreen('main');
96
+ this.loadUserWallets();
97
+ } else {
98
+ this.switchScreen('login');
99
+ }
100
+ }
101
+
102
+ // تسجيل الدخول
103
+ async handleLogin() {
104
+ const phoneNumber = document.getElementById('phone-number').value;
105
+ const pinCode = document.getElementById('pin-code').value;
106
+
107
+ if (!phoneNumber || !pinCode) {
108
+ this.showAlert('يرجى إدخال رقم الهاتف ورمز PIN', 'error');
109
+ return;
110
+ }
111
+
112
+ this.showLoading('جاري تسجيل الدخول...');
113
+
114
+ try {
115
+ const user = await this.authManager.loginWithPin(phoneNumber, pinCode);
116
+ this.currentUser = user;
117
+
118
+ this.hideLoading();
119
+ this.showAlert('تم تسجيل الدخول بنجاح', 'success');
120
+ this.switchScreen('main');
121
+ await this.loadUserWallets();
122
+
123
+ } catch (error) {
124
+ this.hideLoading();
125
+ this.showAlert(error.message, 'error');
126
+ }
127
+ }
128
+
129
+ // تسجيل الدخ��ل بالبصمة
130
+ async handleBiometricLogin() {
131
+ this.showLoading('جاري التحقق من البصمة...');
132
+
133
+ try {
134
+ const user = await this.authManager.loginWithBiometric();
135
+ this.currentUser = user;
136
+
137
+ this.hideLoading();
138
+ this.showAlert('تم تسجيل الدخول بالبصمة بنجاح', 'success');
139
+ this.switchScreen('main');
140
+ await this.loadUserWallets();
141
+
142
+ } catch (error) {
143
+ this.hideLoading();
144
+ this.showAlert(error.message, 'error');
145
+ }
146
+ }
147
+
148
+ // تحميل محافظ المستخدم
149
+ async loadUserWallets() {
150
+ this.showLoading('جاري تحميل المحافظ...');
151
+
152
+ try {
153
+ // الحصول على محافظ المستخدم من مدير المحافظ
154
+ this.wallets = this.walletManager.getUserWallets();
155
+
156
+ // إذا لم توجد محافظ، إنشاء محافظ تجريبية
157
+ if (this.wallets.length === 0) {
158
+ await this.createDemoWallets();
159
+ }
160
+
161
+ // تحديث أرصدة المحافظ
162
+ await this.walletManager.updateAllBalances();
163
+ this.wallets = this.walletManager.getUserWallets();
164
+
165
+ this.loadRecentTransactions();
166
+ this.updateUI();
167
+ this.hideLoading();
168
+
169
+ } catch (error) {
170
+ this.hideLoading();
171
+ this.showAlert('فشل في تحميل المحافظ', 'error');
172
+ }
173
+ }
174
+
175
+ // إنشاء محافظ تجريبية
176
+ async createDemoWallets() {
177
+ const demoWallets = [
178
+ { id: 'jawali', accountNumber: '777123456', pin: '1234' },
179
+ { id: 'onecash', accountNumber: '777234567', pin: '1234' },
180
+ { id: 'cash', accountNumber: '777345678', pin: '1234' },
181
+ { id: 'jaib', accountNumber: '777456789', pin: '1234' },
182
+ { id: 'mfloos', accountNumber: '777567890', pin: '1234' },
183
+ { id: 'mobilemoney', accountNumber: '777678901', pin: '1234' }
184
+ ];
185
+
186
+ for (const wallet of demoWallets) {
187
+ try {
188
+ await this.walletManager.addWallet(wallet.id, wallet.accountNumber, wallet.pin);
189
+ } catch (error) {
190
+ console.warn(`فشل في إضافة محفظة ${wallet.id}:`, error.message);
191
+ }
192
+ }
193
+ }
194
+
195
+ // تحميل المعاملات الأخيرة
196
+ loadRecentTransactions() {
197
+ this.transactions = [
198
+ {
199
+ id: 1,
200
+ type: 'send',
201
+ title: 'تحويل إلى أحمد محمد',
202
+ wallet: 'جوالي',
203
+ amount: -500,
204
+ time: '10:30 ص',
205
+ date: new Date().toISOString()
206
+ },
207
+ {
208
+ id: 2,
209
+ type: 'receive',
210
+ title: 'استلام من سارة أحمد',
211
+ wallet: 'ONE Cash',
212
+ amount: 1200,
213
+ time: '09:15 ص',
214
+ date: new Date().toISOString()
215
+ },
216
+ {
217
+ id: 3,
218
+ type: 'bill',
219
+ title: 'فاتورة كهرباء',
220
+ wallet: 'Cash',
221
+ amount: -350,
222
+ time: 'أمس',
223
+ date: new Date(Date.now() - 86400000).toISOString()
224
+ },
225
+ {
226
+ id: 4,
227
+ type: 'send',
228
+ title: 'شحن رصيد',
229
+ wallet: 'Jaib',
230
+ amount: -100,
231
+ time: 'أمس',
232
+ date: new Date(Date.now() - 86400000).toISOString()
233
+ }
234
+ ];
235
+ }
236
+
237
+ // تحديث واجهة المستخدم
238
+ updateUI() {
239
+ this.updateUserInfo();
240
+ this.updateTotalBalance();
241
+ this.renderWallets();
242
+ this.renderTransactions();
243
+ }
244
+
245
+ // تحديث معلومات المستخدم
246
+ updateUserInfo() {
247
+ if (this.currentUser) {
248
+ document.getElementById('user-name').textContent = `مرحباً ${this.currentUser.name}`;
249
+ document.getElementById('user-phone').textContent = this.currentUser.phone;
250
+ }
251
+ }
252
+
253
+ // تحديث الرصيد الإجمالي
254
+ updateTotalBalance() {
255
+ const total = this.wallets.reduce((sum, wallet) => sum + wallet.balance, 0);
256
+ const balanceElement = document.getElementById('total-balance');
257
+
258
+ if (this.isBalanceHidden) {
259
+ balanceElement.textContent = '••••• ر.ي';
260
+ } else {
261
+ balanceElement.textContent = `${total.toLocaleString()} ر.ي`;
262
+ }
263
+ }
264
+
265
+ // عرض المحافظ
266
+ renderWallets() {
267
+ const walletsList = document.getElementById('wallets-list');
268
+ walletsList.innerHTML = '';
269
+
270
+ this.wallets.forEach(wallet => {
271
+ const walletCard = this.createWalletCard(wallet);
272
+ walletsList.appendChild(walletCard);
273
+ });
274
+ }
275
+
276
+ // إنشاء بطاقة محفظة
277
+ createWalletCard(wallet) {
278
+ const card = document.createElement('div');
279
+ card.className = 'wallet-card';
280
+ card.onclick = () => this.openWalletDetails(wallet);
281
+
282
+ const balanceDisplay = this.isBalanceHidden ?
283
+ '•••••' : wallet.balance.toLocaleString();
284
+
285
+ card.innerHTML = `
286
+ <div class="wallet-info">
287
+ <div class="wallet-icon">
288
+ <img src="${wallet.icon}" alt="${wallet.name}" onerror="this.style.display='none'">
289
+ </div>
290
+ <div class="wallet-details">
291
+ <h4>${wallet.name}</h4>
292
+ <p>${wallet.provider}</p>
293
+ </div>
294
+ </div>
295
+ <div class="wallet-balance">
296
+ <div class="amount">${balanceDisplay}</div>
297
+ <div class="currency">ر.ي</div>
298
+ </div>
299
+ `;
300
+
301
+ return card;
302
+ }
303
+
304
+ // عرض المعاملات
305
+ renderTransactions() {
306
+ const transactionsList = document.getElementById('transactions-list');
307
+ transactionsList.innerHTML = '';
308
+
309
+ this.transactions.slice(0, 5).forEach(transaction => {
310
+ const transactionItem = this.createTransactionItem(transaction);
311
+ transactionsList.appendChild(transactionItem);
312
+ });
313
+ }
314
+
315
+ // إنشاء عنصر معاملة
316
+ createTransactionItem(transaction) {
317
+ const item = document.createElement('div');
318
+ item.className = 'transaction-item';
319
+
320
+ const iconClass = transaction.type === 'send' ? 'fas fa-arrow-up' :
321
+ transaction.type === 'receive' ? 'fas fa-arrow-down' :
322
+ 'fas fa-file-invoice-dollar';
323
+
324
+ const amountClass = transaction.amount > 0 ? 'positive' : 'negative';
325
+ const amountSign = transaction.amount > 0 ? '+' : '';
326
+
327
+ item.innerHTML = `
328
+ <div class="transaction-info">
329
+ <div class="transaction-icon ${transaction.type}">
330
+ <i class="${iconClass}"></i>
331
+ </div>
332
+ <div class="transaction-details">
333
+ <h5>${transaction.title}</h5>
334
+ <p>${transaction.wallet}</p>
335
+ </div>
336
+ </div>
337
+ <div class="transaction-amount ${amountClass}">
338
+ <div class="amount">${amountSign}${Math.abs(transaction.amount).toLocaleString()} ر.ي</div>
339
+ <div class="time">${transaction.time}</div>
340
+ </div>
341
+ `;
342
+
343
+ return item;
344
+ }
345
+
346
+ // محاكاة استدعاء API
347
+ simulateAPICall(delay = 1000) {
348
+ return new Promise((resolve) => {
349
+ setTimeout(resolve, delay);
350
+ });
351
+ }
352
+
353
+ // عرض رسالة تنبيه
354
+ showAlert(message, type = 'info') {
355
+ this.notificationManager.showToast(message, type);
356
+ }
357
+
358
+ // عرض شاشة التحميل
359
+ showLoading(message = 'جاري التحميل...') {
360
+ this.loadingModal = this.notificationManager.showLoading(message);
361
+ }
362
+
363
+ // إخفاء شاشة التحميل
364
+ hideLoading() {
365
+ this.notificationManager.hideLoading();
366
+ }
367
+
368
+ // تبديل الشاشات
369
+ switchScreen(screenName) {
370
+ document.querySelectorAll('.screen').forEach(screen => {
371
+ screen.classList.remove('active');
372
+ });
373
+
374
+ document.getElementById(`${screenName}-screen`).classList.add('active');
375
+
376
+ // تحديث شريط التنقل
377
+ document.querySelectorAll('.nav-item').forEach(item => {
378
+ item.classList.remove('active');
379
+ });
380
+
381
+ const activeNavItem = document.querySelector(`[data-screen="${screenName}"]`);
382
+ if (activeNavItem) {
383
+ activeNavItem.classList.add('active');
384
+ }
385
+
386
+ this.currentScreen = screenName;
387
+ }
388
+
389
+ // تنسيق رقم الهاتف
390
+ formatPhoneNumber(e) {
391
+ let value = e.target.value.replace(/\D/g, '');
392
+ if (value.length > 9) {
393
+ value = value.slice(0, 9);
394
+ }
395
+ e.target.value = value;
396
+ }
397
+
398
+ // تحديث الأرصدة
399
+ async refreshBalances() {
400
+ this.showLoading('جاري تحديث الأرصدة...');
401
+ await this.simulateAPICall(1500);
402
+ this.updateTotalBalance();
403
+ this.renderWallets();
404
+ this.hideLoading();
405
+ this.showAlert('تم تحديث الأرصدة بنجاح', 'success');
406
+ }
407
+
408
+ // إخفاء/إظهار الرصيد
409
+ toggleBalanceVisibility() {
410
+ this.isBalanceHidden = !this.isBalanceHidden;
411
+ const hideBtn = document.getElementById('hide-balance');
412
+ const icon = hideBtn.querySelector('i');
413
+
414
+ if (this.isBalanceHidden) {
415
+ icon.className = 'fas fa-eye';
416
+ hideBtn.innerHTML = '<i class="fas fa-eye"></i> إظهار';
417
+ } else {
418
+ icon.className = 'fas fa-eye-slash';
419
+ hideBtn.innerHTML = '<i class="fas fa-eye-slash"></i> إخفاء';
420
+ }
421
+
422
+ this.updateTotalBalance();
423
+ this.renderWallets();
424
+ }
425
+
426
+ // تحميل بيانات المستخدم
427
+ loadUserData() {
428
+ // تحميل الإعدادات المحفوظة
429
+ const savedSettings = localStorage.getItem('unifiedWallet_settings');
430
+ if (savedSettings) {
431
+ const settings = JSON.parse(savedSettings);
432
+ this.isBalanceHidden = settings.hideBalance || false;
433
+ }
434
+ }
435
+
436
+ // حفظ بيانات المستخدم
437
+ saveUserData() {
438
+ const settings = {
439
+ hideBalance: this.isBalanceHidden
440
+ };
441
+ localStorage.setItem('unifiedWallet_settings', JSON.stringify(settings));
442
+ }
443
+
444
+ // إعداد شاشة التحويل
445
+ setupTransferScreen() {
446
+ this.currentTransferStep = 1;
447
+ this.selectedSourceWallet = null;
448
+ this.transferData = {};
449
+
450
+ // أزرار التنقل
451
+ document.getElementById('transfer-next-btn').addEventListener('click', () => this.nextTransferStep());
452
+ document.getElementById('transfer-prev-btn').addEventListener('click', () => this.prevTransferStep());
453
+ document.getElementById('transfer-confirm-btn').addEventListener('click', () => this.confirmTransfer());
454
+
455
+ // اقتراحات المبلغ
456
+ document.querySelectorAll('.amount-btn').forEach(btn => {
457
+ btn.addEventListener('click', () => {
458
+ document.getElementById('transfer-amount').value = btn.dataset.amount;
459
+ });
460
+ });
461
+ }
462
+
463
+ // عرض شاشة التحويل
464
+ showTransferScreen() {
465
+ this.switchScreen('transfer');
466
+ this.resetTransferForm();
467
+ this.renderSourceWallets();
468
+ }
469
+
470
+ // إعادة تعيين نموذج التحويل
471
+ resetTransferForm() {
472
+ this.currentTransferStep = 1;
473
+ this.selectedSourceWallet = null;
474
+ this.transferData = {};
475
+
476
+ // إعادة تعيين الخطوات
477
+ this.updateTransferSteps();
478
+
479
+ // مسح النموذج
480
+ document.getElementById('destination-wallet').value = '';
481
+ document.getElementById('recipient-number').value = '';
482
+ document.getElementById('transfer-amount').value = '';
483
+ document.getElementById('transfer-note').value = '';
484
+ document.getElementById('transfer-pin').value = '';
485
+ }
486
+
487
+ // تحديث مؤشر الخطوات
488
+ updateTransferSteps() {
489
+ for (let i = 1; i <= 3; i++) {
490
+ const step = document.getElementById(`transfer-step-${i}`);
491
+ const content = document.getElementById(`transfer-step-content-${i}`);
492
+
493
+ if (i < this.currentTransferStep) {
494
+ step.classList.add('completed');
495
+ step.classList.remove('active');
496
+ } else if (i === this.currentTransferStep) {
497
+ step.classList.add('active');
498
+ step.classList.remove('completed');
499
+ } else {
500
+ step.classList.remove('active', 'completed');
501
+ }
502
+
503
+ content.classList.toggle('active', i === this.currentTransferStep);
504
+ }
505
+
506
+ // تحديث أزرار التنقل
507
+ const prevBtn = document.getElementById('transfer-prev-btn');
508
+ const nextBtn = document.getElementById('transfer-next-btn');
509
+ const confirmBtn = document.getElementById('transfer-confirm-btn');
510
+
511
+ prevBtn.style.display = this.currentTransferStep > 1 ? 'block' : 'none';
512
+ nextBtn.style.display = this.currentTransferStep < 3 ? 'block' : 'none';
513
+ confirmBtn.style.display = this.currentTransferStep === 3 ? 'block' : 'none';
514
+ }
515
+
516
+ // عرض المحافظ المصدر
517
+ renderSourceWallets() {
518
+ const container = document.getElementById('source-wallet-selection');
519
+ container.innerHTML = '';
520
+
521
+ this.wallets.forEach(wallet => {
522
+ const option = this.createWalletOption(wallet);
523
+ container.appendChild(option);
524
+ });
525
+ }
526
+
527
+ // إنشاء خيار محفظة
528
+ createWalletOption(wallet) {
529
+ const option = document.createElement('div');
530
+ option.className = 'wallet-option';
531
+ option.onclick = () => this.selectSourceWallet(wallet);
532
+
533
+ const balanceDisplay = this.isBalanceHidden ?
534
+ '•••••' : wallet.balance.toLocaleString();
535
+
536
+ option.innerHTML = `
537
+ <div class="wallet-option-info">
538
+ <div class="wallet-option-icon">
539
+ <img src="${wallet.icon}" alt="${wallet.name}" onerror="this.style.display='none'">
540
+ </div>
541
+ <div class="wallet-option-details">
542
+ <h4>${wallet.name}</h4>
543
+ <p>${wallet.provider}</p>
544
+ </div>
545
+ </div>
546
+ <div class="wallet-option-balance">
547
+ <div class="amount">${balanceDisplay}</div>
548
+ <div class="currency">ر.ي</div>
549
+ </div>
550
+ `;
551
+
552
+ return option;
553
+ }
554
+
555
+ // اختيار المحفظة المصدر
556
+ selectSourceWallet(wallet) {
557
+ this.selectedSourceWallet = wallet;
558
+
559
+ // تحديث التحديد البصري
560
+ document.querySelectorAll('.wallet-option').forEach(option => {
561
+ option.classList.remove('selected');
562
+ });
563
+ event.currentTarget.classList.add('selected');
564
+
565
+ this.transferData.sourceWallet = wallet;
566
+ }
567
+
568
+ // الخطوة التالية
569
+ nextTransferStep() {
570
+ if (this.validateCurrentStep()) {
571
+ this.currentTransferStep++;
572
+ this.updateTransferSteps();
573
+
574
+ if (this.currentTransferStep === 3) {
575
+ this.updateTransferSummary();
576
+ }
577
+ }
578
+ }
579
+
580
+ // الخطوة السابقة
581
+ prevTransferStep() {
582
+ this.currentTransferStep--;
583
+ this.updateTransferSteps();
584
+ }
585
+
586
+ // التحقق من صحة الخطوة الحالية
587
+ validateCurrentStep() {
588
+ switch (this.currentTransferStep) {
589
+ case 1:
590
+ if (!this.selectedSourceWallet) {
591
+ this.showAlert('يرجى اختيار المحفظة المرسلة', 'error');
592
+ return false;
593
+ }
594
+ return true;
595
+
596
+ case 2:
597
+ const destinationWallet = document.getElementById('destination-wallet').value;
598
+ const recipientNumber = document.getElementById('recipient-number').value;
599
+ const amount = parseFloat(document.getElementById('transfer-amount').value);
600
+
601
+ if (!destinationWallet) {
602
+ this.showAlert('يرجى اختيار المحفظة المستقبلة', 'error');
603
+ return false;
604
+ }
605
+
606
+ if (!recipientNumber || recipientNumber.length !== 9) {
607
+ this.showAlert('يرجى إدخال رقم المستقبل صحيح (9 أرقام)', 'error');
608
+ return false;
609
+ }
610
+
611
+ if (!amount || amount <= 0) {
612
+ this.showAlert('يرجى إدخال مبلغ صحيح', 'error');
613
+ return false;
614
+ }
615
+
616
+ if (amount > this.selectedSourceWallet.balance) {
617
+ this.showAlert('المبلغ أكبر من الرصيد المتاح', 'error');
618
+ return false;
619
+ }
620
+
621
+ // حفظ بيانات التحويل
622
+ this.transferData.destinationWallet = destinationWallet;
623
+ this.transferData.recipientNumber = recipientNumber;
624
+ this.transferData.amount = amount;
625
+ this.transferData.note = document.getElementById('transfer-note').value;
626
+
627
+ return true;
628
+
629
+ default:
630
+ return true;
631
+ }
632
+ }
633
+
634
+ // تحديث ملخص التحويل
635
+ updateTransferSummary() {
636
+ const sourceWalletInfo = this.walletManager.getWalletInfo(this.transferData.sourceWallet.id);
637
+ const destinationWalletInfo = this.walletManager.getWalletInfo(this.transferData.destinationWallet);
638
+
639
+ const fee = sourceWalletInfo.fees.transfer;
640
+ const total = this.transferData.amount + fee;
641
+
642
+ document.getElementById('summary-from-wallet').textContent = this.transferData.sourceWallet.name;
643
+ document.getElementById('summary-to-wallet').textContent = destinationWalletInfo.name;
644
+ document.getElementById('summary-recipient').textContent = `+967${this.transferData.recipientNumber}`;
645
+ document.getElementById('summary-amount').textContent = `${this.transferData.amount.toLocaleString()} ر.ي`;
646
+ document.getElementById('summary-fee').textContent = `${fee.toLocaleString()} ر.ي`;
647
+ document.getElementById('summary-total').textContent = `${total.toLocaleString()} ر.ي`;
648
+ }
649
+
650
+ // تأكيد التحويل
651
+ async confirmTransfer() {
652
+ const pin = document.getElementById('transfer-pin').value;
653
+
654
+ if (!pin) {
655
+ this.showAlert('يرجى إدخال رمز PIN', 'error');
656
+ return;
657
+ }
658
+
659
+ this.showLoading('جاري تنفيذ التحويل...');
660
+
661
+ try {
662
+ const result = await this.walletManager.executeTransfer(
663
+ this.transferData.sourceWallet.id,
664
+ this.transferData.destinationWallet,
665
+ this.transferData.amount,
666
+ this.transferData.recipientNumber,
667
+ pin
668
+ );
669
+
670
+ this.hideLoading();
671
+ this.showTransferSuccess(result);
672
+
673
+ // تحديث البيانات
674
+ await this.loadUserWallets();
675
+
676
+ } catch (error) {
677
+ this.hideLoading();
678
+ this.showAlert(error.message, 'error');
679
+ }
680
+ }
681
+
682
+ // عرض نجاح التحويل
683
+ showTransferSuccess(result) {
684
+ const message = `
685
+ تم التحويل بنجاح!
686
+
687
+ رقم المعاملة: ${result.transactionId}
688
+ المبلغ المحول: ${result.amount.toLocaleString()} ر.ي
689
+ الرسوم: ${result.fee.toLocaleString()} ر.ي
690
+ الرصيد المتبقي: ${result.newBalance.toLocaleString()} ر.ي
691
+ `;
692
+
693
+ this.showAlert(message, 'success');
694
+ this.switchScreen('main');
695
+ }
696
+
697
+ // الوظائف التي سيتم تطويرها لاحقاً
698
+ showBillsScreen() { console.log('عرض شاشة الفواتير'); }
699
+ showRechargeScreen() { console.log('عرض شاشة الشحن'); }
700
+ startQRScan() { console.log('بدء مسح QR'); }
701
+ showSettings() { console.log('عرض الإعدادات'); }
702
+ showNotifications() {
703
+ this.notificationManager.showNotificationsList();
704
+ }
705
+ showWalletManagement() { console.log('إدارة المحافظ'); }
706
+ showAllTransactions() { console.log('عرض جميع المعاملات'); }
707
+ openWalletDetails(wallet) { console.log('تفاصيل المحفظة:', wallet.name); }
708
+ showRegisterModal() {
709
+ this.notificationManager.showModal(
710
+ 'إنشاء حساب جديد',
711
+ `
712
+ <div class="form-group">
713
+ <label>رقم الهاتف</label>
714
+ <div class="input-group">
715
+ <span class="input-prefix">+967</span>
716
+ <input type="tel" id="register-phone" placeholder="7xxxxxxxx" maxlength="9">
717
+ </div>
718
+ </div>
719
+ <div class="form-group">
720
+ <label>رمز PIN</label>
721
+ <input type="password" id="register-pin" placeholder="أدخل رمز PIN" maxlength="6">
722
+ </div>
723
+ <div class="form-group">
724
+ <label>تأكيد رمز PIN</label>
725
+ <input type="password" id="register-pin-confirm" placeholder="أعد إدخال رمز PIN" maxlength="6">
726
+ </div>
727
+ `,
728
+ [
729
+ {
730
+ text: 'إنشاء الحساب',
731
+ class: 'btn-primary',
732
+ action: () => this.handleRegister()
733
+ },
734
+ {
735
+ text: 'إلغاء',
736
+ class: 'btn-secondary'
737
+ }
738
+ ]
739
+ );
740
+ }
741
+
742
+ // التعامل مع التسجيل
743
+ handleRegister() {
744
+ const phone = document.getElementById('register-phone').value;
745
+ const pin = document.getElementById('register-pin').value;
746
+ const pinConfirm = document.getElementById('register-pin-confirm').value;
747
+
748
+ if (!phone || !pin || !pinConfirm) {
749
+ this.showAlert('يرجى ملء جميع الحقول', 'error');
750
+ return;
751
+ }
752
+
753
+ if (pin !== pinConfirm) {
754
+ this.showAlert('رمز PIN غير متطابق', 'error');
755
+ return;
756
+ }
757
+
758
+ if (phone.length !== 9) {
759
+ this.showAlert('رقم الهاتف يجب أن يكون 9 أرقام', 'error');
760
+ return;
761
+ }
762
+
763
+ if (pin.length < 4) {
764
+ this.showAlert('رمز PIN يجب أن يكون 4 أرقام على الأقل', 'error');
765
+ return;
766
+ }
767
+
768
+ // محاكاة إنشاء الحساب
769
+ this.showAlert('تم إنشاء الحساب بنجاح! يمكنك الآن تسجيل الدخول', 'success');
770
+
771
+ // ملء بيانات تسجيل الدخول
772
+ document.getElementById('phone-number').value = phone;
773
+ document.getElementById('pin-code').value = pin;
774
+ }
775
+ }
776
+
777
+ // تهيئة التطبيق عند تحميل الصفحة
778
+ document.addEventListener('DOMContentLoaded', () => {
779
+ window.app = new UnifiedWalletApp();
780
+ });
auth.js ADDED
@@ -0,0 +1,426 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // نظام المصادقة والأمان
2
+ class AuthenticationManager {
3
+ constructor() {
4
+ this.currentUser = null;
5
+ this.sessionTimeout = 15 * 60 * 1000; // 15 دقيقة
6
+ this.maxLoginAttempts = 3;
7
+ this.lockoutDuration = 30 * 60 * 1000; // 30 دقيقة
8
+ this.biometricCredential = null;
9
+
10
+ this.init();
11
+ }
12
+
13
+ // تهيئة نظام المصادقة
14
+ init() {
15
+ this.setupSessionManagement();
16
+ this.loadStoredCredentials();
17
+ this.checkBiometricSupport();
18
+ }
19
+
20
+ // إعداد إدارة الجلسة
21
+ setupSessionManagement() {
22
+ // تحديث وقت النشاط عند التفاعل
23
+ document.addEventListener('click', () => this.updateLastActivity());
24
+ document.addEventListener('keypress', () => this.updateLastActivity());
25
+ document.addEventListener('touchstart', () => this.updateLastActivity());
26
+
27
+ // فحص انتهاء الجلسة كل دقيقة
28
+ setInterval(() => this.checkSessionExpiry(), 60000);
29
+ }
30
+
31
+ // تسجيل دخول بالرقم ورمز PIN
32
+ async loginWithPin(phoneNumber, pin) {
33
+ try {
34
+ // التحقق من محاولات تسجيل الدخول
35
+ if (this.isAccountLocked(phoneNumber)) {
36
+ const lockoutTime = this.getLockoutRemainingTime(phoneNumber);
37
+ throw new Error(`الحساب مقفل. المحاولة مرة أخرى خلال ${Math.ceil(lockoutTime / 60000)} دقيقة`);
38
+ }
39
+
40
+ // التحقق من صحة البيانات
41
+ if (!this.validatePhoneNumber(phoneNumber)) {
42
+ throw new Error('رقم الهاتف غير صحيح');
43
+ }
44
+
45
+ if (!this.validatePin(pin)) {
46
+ throw new Error('رمز PIN يجب أن يكون 4-6 أرقام');
47
+ }
48
+
49
+ // محاكاة التحقق من البيانات
50
+ const isValid = await this.verifyCredentials(phoneNumber, pin);
51
+
52
+ if (!isValid) {
53
+ this.recordFailedAttempt(phoneNumber);
54
+ const remainingAttempts = this.getRemainingAttempts(phoneNumber);
55
+
56
+ if (remainingAttempts <= 0) {
57
+ this.lockAccount(phoneNumber);
58
+ throw new Error('تم قفل الحساب بسبب المحاولات الخاطئة المتكررة');
59
+ }
60
+
61
+ throw new Error(`بيانات تسجيل الدخول غير صحيحة. المحاولات المتبقية: ${remainingAttempts}`);
62
+ }
63
+
64
+ // تسجيل دخول ناجح
65
+ this.clearFailedAttempts(phoneNumber);
66
+ const user = await this.createUserSession(phoneNumber, pin);
67
+
68
+ return user;
69
+
70
+ } catch (error) {
71
+ console.error('خطأ في تسجيل الدخول:', error);
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ // تسجيل دخول بالبصمة
77
+ async loginWithBiometric() {
78
+ try {
79
+ if (!this.isBiometricSupported()) {
80
+ throw new Error('المصادقة البيومترية غير مدعومة في هذا المتصفح');
81
+ }
82
+
83
+ if (!this.biometricCredential) {
84
+ throw new Error('لم يتم تسجيل بصمة مسبقاً. يرجى تسجيل الدخول برمز PIN أولاً');
85
+ }
86
+
87
+ // التحقق من البصمة
88
+ const credential = await navigator.credentials.get({
89
+ publicKey: {
90
+ challenge: this.generateChallenge(),
91
+ allowCredentials: [{
92
+ type: 'public-key',
93
+ id: this.biometricCredential.id
94
+ }],
95
+ timeout: 60000,
96
+ userVerification: 'required'
97
+ }
98
+ });
99
+
100
+ if (!credential) {
101
+ throw new Error('فشل في التحقق من البصمة');
102
+ }
103
+
104
+ // إنشاء جلسة المستخدم
105
+ const savedUser = this.getStoredUser();
106
+ if (!savedUser) {
107
+ throw new Error('لم يتم العثور على بيانات المستخدم');
108
+ }
109
+
110
+ const user = await this.createUserSession(savedUser.phone, null, 'biometric');
111
+ return user;
112
+
113
+ } catch (error) {
114
+ console.error('خطأ في تسجيل الدخول بالبصمة:', error);
115
+ throw error;
116
+ }
117
+ }
118
+
119
+ // تسجيل البصمة
120
+ async registerBiometric(phoneNumber) {
121
+ try {
122
+ if (!this.isBiometricSupported()) {
123
+ throw new Error('المصادقة البيومترية غير مدعومة');
124
+ }
125
+
126
+ const credential = await navigator.credentials.create({
127
+ publicKey: {
128
+ challenge: this.generateChallenge(),
129
+ rp: {
130
+ name: 'محفظتي الموحدة',
131
+ id: window.location.hostname
132
+ },
133
+ user: {
134
+ id: new TextEncoder().encode(phoneNumber),
135
+ name: phoneNumber,
136
+ displayName: `مستخدم ${phoneNumber}`
137
+ },
138
+ pubKeyCredParams: [{
139
+ type: 'public-key',
140
+ alg: -7 // ES256
141
+ }],
142
+ timeout: 60000,
143
+ attestation: 'none',
144
+ authenticatorSelection: {
145
+ authenticatorAttachment: 'platform',
146
+ userVerification: 'required'
147
+ }
148
+ }
149
+ });
150
+
151
+ if (!credential) {
152
+ throw new Error('فشل في تسجيل البصمة');
153
+ }
154
+
155
+ // حفظ بيانات البصمة
156
+ this.biometricCredential = {
157
+ id: credential.rawId,
158
+ publicKey: credential.response.publicKey,
159
+ phoneNumber: phoneNumber,
160
+ registeredAt: new Date().toISOString()
161
+ };
162
+
163
+ this.storeBiometricCredential();
164
+ return true;
165
+
166
+ } catch (error) {
167
+ console.error('خطأ في تسجيل البصمة:', error);
168
+ throw error;
169
+ }
170
+ }
171
+
172
+ // إنشاء جلسة مستخدم
173
+ async createUserSession(phoneNumber, pin, authMethod = 'pin') {
174
+ const user = {
175
+ id: this.generateUserId(),
176
+ phone: phoneNumber,
177
+ name: this.extractNameFromPhone(phoneNumber),
178
+ authMethod: authMethod,
179
+ loginTime: new Date().toISOString(),
180
+ lastActivity: new Date().toISOString(),
181
+ sessionId: this.generateSessionId()
182
+ };
183
+
184
+ this.currentUser = user;
185
+ this.storeUserSession(user);
186
+ this.updateLastActivity();
187
+
188
+ return user;
189
+ }
190
+
191
+ // تسجيل الخروج
192
+ logout() {
193
+ this.currentUser = null;
194
+ this.clearUserSession();
195
+ this.clearStoredCredentials();
196
+
197
+ // إعادة توجيه لشاشة تسجيل الدخول
198
+ if (window.app) {
199
+ window.app.switchScreen('login');
200
+ }
201
+ }
202
+
203
+ // التحقق من صحة الجلسة
204
+ isSessionValid() {
205
+ if (!this.currentUser) {
206
+ return false;
207
+ }
208
+
209
+ const lastActivity = new Date(this.currentUser.lastActivity);
210
+ const now = new Date();
211
+ const timeDiff = now.getTime() - lastActivity.getTime();
212
+
213
+ return timeDiff < this.sessionTimeout;
214
+ }
215
+
216
+ // فحص انتهاء الجلسة
217
+ checkSessionExpiry() {
218
+ if (this.currentUser && !this.isSessionValid()) {
219
+ this.showSessionExpiredDialog();
220
+ }
221
+ }
222
+
223
+ // عرض حوار انتهاء الجلسة
224
+ showSessionExpiredDialog() {
225
+ if (confirm('انتهت صلاحية الجلسة. هل تريد تسجيل الدخول مرة أخرى؟')) {
226
+ this.logout();
227
+ } else {
228
+ this.logout();
229
+ }
230
+ }
231
+
232
+ // تحديث وقت النشاط الأخير
233
+ updateLastActivity() {
234
+ if (this.currentUser) {
235
+ this.currentUser.lastActivity = new Date().toISOString();
236
+ this.storeUserSession(this.currentUser);
237
+ }
238
+ }
239
+
240
+ // التحقق من قفل الحساب
241
+ isAccountLocked(phoneNumber) {
242
+ const lockData = this.getLockData(phoneNumber);
243
+ if (!lockData) return false;
244
+
245
+ const now = new Date().getTime();
246
+ return now < lockData.lockedUntil;
247
+ }
248
+
249
+ // الحصول على الوقت المتبقي للقفل
250
+ getLockoutRemainingTime(phoneNumber) {
251
+ const lockData = this.getLockData(phoneNumber);
252
+ if (!lockData) return 0;
253
+
254
+ const now = new Date().getTime();
255
+ return Math.max(0, lockData.lockedUntil - now);
256
+ }
257
+
258
+ // تسجيل محاولة فاشلة
259
+ recordFailedAttempt(phoneNumber) {
260
+ const attempts = this.getFailedAttempts(phoneNumber);
261
+ attempts.push(new Date().toISOString());
262
+
263
+ localStorage.setItem(`failed_attempts_${phoneNumber}`, JSON.stringify(attempts));
264
+ }
265
+
266
+ // الحصول على المحاولات الفاشلة
267
+ getFailedAttempts(phoneNumber) {
268
+ const stored = localStorage.getItem(`failed_attempts_${phoneNumber}`);
269
+ return stored ? JSON.parse(stored) : [];
270
+ }
271
+
272
+ // الحصول على المحاولات المتبقية
273
+ getRemainingAttempts(phoneNumber) {
274
+ const attempts = this.getFailedAttempts(phoneNumber);
275
+ return Math.max(0, this.maxLoginAttempts - attempts.length);
276
+ }
277
+
278
+ // قفل الحساب
279
+ lockAccount(phoneNumber) {
280
+ const lockData = {
281
+ lockedAt: new Date().toISOString(),
282
+ lockedUntil: new Date().getTime() + this.lockoutDuration
283
+ };
284
+
285
+ localStorage.setItem(`account_lock_${phoneNumber}`, JSON.stringify(lockData));
286
+ }
287
+
288
+ // الحصول على بيانات القفل
289
+ getLockData(phoneNumber) {
290
+ const stored = localStorage.getItem(`account_lock_${phoneNumber}`);
291
+ return stored ? JSON.parse(stored) : null;
292
+ }
293
+
294
+ // مسح المحاولات الفاشلة
295
+ clearFailedAttempts(phoneNumber) {
296
+ localStorage.removeItem(`failed_attempts_${phoneNumber}`);
297
+ localStorage.removeItem(`account_lock_${phoneNumber}`);
298
+ }
299
+
300
+ // التحقق من صحة رقم الهاتف
301
+ validatePhoneNumber(phoneNumber) {
302
+ return /^7[0-9]{8}$/.test(phoneNumber);
303
+ }
304
+
305
+ // التحقق من صحة رمز PIN
306
+ validatePin(pin) {
307
+ return /^[0-9]{4,6}$/.test(pin);
308
+ }
309
+
310
+ // محاكاة التحقق من البيانات
311
+ async verifyCredentials(phoneNumber, pin) {
312
+ // محاكاة استدعاء API
313
+ await new Promise(resolve => setTimeout(resolve, 1000));
314
+
315
+ // في التطبيق الحقيقي، سيتم التحقق من البيانات مع الخادم
316
+ // للتجربة، نقبل أي رقم هاتف صحيح ورمز PIN من 4-6 أرقام
317
+ return this.validatePhoneNumber(phoneNumber) && this.validatePin(pin);
318
+ }
319
+
320
+ // فحص دعم المصادقة البيومترية
321
+ isBiometricSupported() {
322
+ return window.PublicKeyCredential &&
323
+ PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable;
324
+ }
325
+
326
+ // فحص دعم المصادقة البيومترية
327
+ async checkBiometricSupport() {
328
+ if (this.isBiometricSupported()) {
329
+ try {
330
+ const available = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
331
+ return available;
332
+ } catch (error) {
333
+ console.warn('خطأ في فحص دعم المصادقة البيومترية:', error);
334
+ return false;
335
+ }
336
+ }
337
+ return false;
338
+ }
339
+
340
+ // توليد تحدي للمصادقة البيومترية
341
+ generateChallenge() {
342
+ const array = new Uint8Array(32);
343
+ crypto.getRandomValues(array);
344
+ return array;
345
+ }
346
+
347
+ // توليد معرف مستخدم
348
+ generateUserId() {
349
+ return 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
350
+ }
351
+
352
+ // توليد معرف جلسة
353
+ generateSessionId() {
354
+ return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
355
+ }
356
+
357
+ // استخراج اسم من رقم الهاتف
358
+ extractNameFromPhone(phoneNumber) {
359
+ return `مستخدم ${phoneNumber.substr(-4)}`;
360
+ }
361
+
362
+ // حفظ جلسة المستخدم
363
+ storeUserSession(user) {
364
+ localStorage.setItem('unifiedWallet_session', JSON.stringify(user));
365
+ }
366
+
367
+ // تحميل جلسة المستخدم
368
+ loadStoredSession() {
369
+ const stored = localStorage.getItem('unifiedWallet_session');
370
+ if (stored) {
371
+ const user = JSON.parse(stored);
372
+ if (this.isSessionValid()) {
373
+ this.currentUser = user;
374
+ return user;
375
+ } else {
376
+ this.clearUserSession();
377
+ }
378
+ }
379
+ return null;
380
+ }
381
+
382
+ // مسح جلسة المستخدم
383
+ clearUserSession() {
384
+ localStorage.removeItem('unifiedWallet_session');
385
+ }
386
+
387
+ // حفظ بيانات البصمة
388
+ storeBiometricCredential() {
389
+ if (this.biometricCredential) {
390
+ localStorage.setItem('unifiedWallet_biometric', JSON.stringify(this.biometricCredential));
391
+ }
392
+ }
393
+
394
+ // تحميل بيانات البصمة
395
+ loadStoredCredentials() {
396
+ const stored = localStorage.getItem('unifiedWallet_biometric');
397
+ if (stored) {
398
+ this.biometricCredential = JSON.parse(stored);
399
+ }
400
+ }
401
+
402
+ // مسح بيانات البصمة
403
+ clearStoredCredentials() {
404
+ localStorage.removeItem('unifiedWallet_biometric');
405
+ this.biometricCredential = null;
406
+ }
407
+
408
+ // الحصول على المستخدم المحفوظ
409
+ getStoredUser() {
410
+ const stored = localStorage.getItem('unifiedWallet_user');
411
+ return stored ? JSON.parse(stored) : null;
412
+ }
413
+
414
+ // الحصول على المستخدم الحالي
415
+ getCurrentUser() {
416
+ return this.currentUser;
417
+ }
418
+
419
+ // التحقق من تسجيل الدخول
420
+ isLoggedIn() {
421
+ return this.currentUser !== null && this.isSessionValid();
422
+ }
423
+ }
424
+
425
+ // تصدير الكلاس للاستخدام في التطبيق الرئيسي
426
+ window.AuthenticationManager = AuthenticationManager;
capacitor-simple.config.ts ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { CapacitorConfig } from '@capacitor/cli';
2
+
3
+ const config: CapacitorConfig = {
4
+ appId: 'com.almada.unifiedwallet',
5
+ appName: 'محفظتي الموحدة',
6
+ webDir: '.',
7
+ bundledWebRuntime: false,
8
+ server: {
9
+ androidScheme: 'https'
10
+ },
11
+ plugins: {
12
+ SplashScreen: {
13
+ launchShowDuration: 3000,
14
+ launchAutoHide: true,
15
+ backgroundColor: "#4361ee",
16
+ androidSplashResourceName: "splash",
17
+ androidScaleType: "CENTER_CROP",
18
+ showSpinner: false,
19
+ splashFullScreen: true,
20
+ splashImmersive: true
21
+ },
22
+ StatusBar: {
23
+ style: "LIGHT",
24
+ backgroundColor: "#4361ee"
25
+ },
26
+ Keyboard: {
27
+ resize: "body",
28
+ style: "dark",
29
+ resizeOnFullScreen: true
30
+ },
31
+ LocalNotifications: {
32
+ smallIcon: "ic_stat_icon_config_sample",
33
+ iconColor: "#4361ee",
34
+ sound: "beep.wav"
35
+ },
36
+ Device: {
37
+ permissions: {
38
+ device: "تحتاج هذه الميزة لتحديد هوية الجهاز للأمان"
39
+ }
40
+ }
41
+ },
42
+ android: {
43
+ allowMixedContent: true,
44
+ captureInput: true,
45
+ webContentsDebuggingEnabled: true
46
+ }
47
+ };
48
+
49
+ export default config;
capacitor.config.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const config = {
2
+ appId: 'com.almada.unifiedwallet',
3
+ appName: 'محفظتي الموحدة',
4
+ webDir: 'www',
5
+ bundledWebRuntime: false,
6
+ server: {
7
+ androidScheme: 'https'
8
+ },
9
+ plugins: {
10
+ SplashScreen: {
11
+ launchShowDuration: 3000,
12
+ launchAutoHide: true,
13
+ backgroundColor: "#4361ee",
14
+ androidSplashResourceName: "splash",
15
+ androidScaleType: "CENTER_CROP",
16
+ showSpinner: false,
17
+ splashFullScreen: true,
18
+ splashImmersive: true
19
+ },
20
+ StatusBar: {
21
+ style: "LIGHT",
22
+ backgroundColor: "#4361ee"
23
+ },
24
+ Keyboard: {
25
+ resize: "body",
26
+ style: "dark",
27
+ resizeOnFullScreen: true
28
+ },
29
+ LocalNotifications: {
30
+ smallIcon: "ic_stat_icon_config_sample",
31
+ iconColor: "#4361ee",
32
+ sound: "beep.wav"
33
+ },
34
+ Device: {
35
+ permissions: {
36
+ device: "تحتاج هذه الميزة لتحديد هوية الجهاز للأمان"
37
+ }
38
+ }
39
+ },
40
+ android: {
41
+ allowMixedContent: true,
42
+ captureInput: true,
43
+ webContentsDebuggingEnabled: true
44
+ }
45
+ };
46
+
47
+ module.exports = config;
capacitor.config.ts ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { CapacitorConfig } from '@capacitor/cli';
2
+
3
+ const config: CapacitorConfig = {
4
+ appId: 'com.almada.unifiedwallet',
5
+ appName: 'محفظتي الموحدة',
6
+ webDir: 'www',
7
+ server: {
8
+ androidScheme: 'https'
9
+ },
10
+ plugins: {
11
+ SplashScreen: {
12
+ launchShowDuration: 3000,
13
+ launchAutoHide: true,
14
+ backgroundColor: "#4361ee",
15
+ androidSplashResourceName: "splash",
16
+ androidScaleType: "CENTER_CROP",
17
+ showSpinner: false,
18
+ androidSpinnerStyle: "large",
19
+ iosSpinnerStyle: "small",
20
+ spinnerColor: "#ffffff",
21
+ splashFullScreen: true,
22
+ splashImmersive: true,
23
+ layoutName: "launch_screen",
24
+ useDialog: true,
25
+ },
26
+ StatusBar: {
27
+ style: "LIGHT",
28
+ backgroundColor: "#4361ee"
29
+ },
30
+ Keyboard: {
31
+ resize: "body",
32
+ style: "dark",
33
+ resizeOnFullScreen: true
34
+ },
35
+ LocalNotifications: {
36
+ smallIcon: "ic_stat_icon_config_sample",
37
+ iconColor: "#4361ee",
38
+ sound: "beep.wav"
39
+ },
40
+ PushNotifications: {
41
+ presentationOptions: ["badge", "sound", "alert"]
42
+ },
43
+ Camera: {
44
+ permissions: {
45
+ camera: "تحتاج هذه الميزة للوصول إلى الكاميرا لمسح رموز QR",
46
+ photos: "تحتاج هذه الميزة للوصول إلى الصور لحفظ الإيصالات"
47
+ }
48
+ },
49
+ Device: {
50
+ permissions: {
51
+ device: "تحتاج هذه الميزة لتحديد هوية الجهاز للأمان"
52
+ }
53
+ }
54
+ },
55
+ android: {
56
+ allowMixedContent: true,
57
+ captureInput: true,
58
+ webContentsDebuggingEnabled: false
59
+ },
60
+ ios: {
61
+ contentInset: "automatic",
62
+ scrollEnabled: true,
63
+ allowsLinkPreview: false
64
+ }
65
+ };
66
+
67
+ export default config;
demo.html ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>تجربة محفظتي الموحدة</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@300;400;500;700&display=swap" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ font-family: 'Tajawal', sans-serif;
11
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
12
+ margin: 0;
13
+ padding: 20px;
14
+ min-height: 100vh;
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ }
19
+
20
+ .demo-container {
21
+ background: white;
22
+ border-radius: 20px;
23
+ padding: 40px;
24
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
25
+ text-align: center;
26
+ max-width: 600px;
27
+ width: 100%;
28
+ }
29
+
30
+ .demo-header {
31
+ margin-bottom: 30px;
32
+ }
33
+
34
+ .demo-logo {
35
+ font-size: 4rem;
36
+ color: #4361ee;
37
+ margin-bottom: 20px;
38
+ }
39
+
40
+ .demo-title {
41
+ font-size: 2.5rem;
42
+ font-weight: 700;
43
+ color: #1f2937;
44
+ margin-bottom: 10px;
45
+ }
46
+
47
+ .demo-subtitle {
48
+ font-size: 1.2rem;
49
+ color: #6b7280;
50
+ margin-bottom: 30px;
51
+ }
52
+
53
+ .demo-features {
54
+ display: grid;
55
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
56
+ gap: 20px;
57
+ margin-bottom: 40px;
58
+ }
59
+
60
+ .feature-card {
61
+ background: #f8fafc;
62
+ border-radius: 15px;
63
+ padding: 25px;
64
+ border: 1px solid #e5e7eb;
65
+ }
66
+
67
+ .feature-icon {
68
+ font-size: 2.5rem;
69
+ color: #4361ee;
70
+ margin-bottom: 15px;
71
+ }
72
+
73
+ .feature-title {
74
+ font-size: 1.3rem;
75
+ font-weight: 600;
76
+ color: #1f2937;
77
+ margin-bottom: 10px;
78
+ }
79
+
80
+ .feature-description {
81
+ color: #6b7280;
82
+ line-height: 1.6;
83
+ }
84
+
85
+ .demo-wallets {
86
+ margin-bottom: 40px;
87
+ }
88
+
89
+ .wallets-grid {
90
+ display: grid;
91
+ grid-template-columns: repeat(3, 1fr);
92
+ gap: 15px;
93
+ margin-top: 20px;
94
+ }
95
+
96
+ .wallet-item {
97
+ background: white;
98
+ border: 2px solid #e5e7eb;
99
+ border-radius: 12px;
100
+ padding: 15px;
101
+ transition: all 0.3s ease;
102
+ }
103
+
104
+ .wallet-item:hover {
105
+ border-color: #4361ee;
106
+ transform: translateY(-5px);
107
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
108
+ }
109
+
110
+ .wallet-logo {
111
+ width: 50px;
112
+ height: 50px;
113
+ border-radius: 8px;
114
+ margin: 0 auto 10px;
115
+ overflow: hidden;
116
+ }
117
+
118
+ .wallet-logo img {
119
+ width: 100%;
120
+ height: 100%;
121
+ object-fit: cover;
122
+ }
123
+
124
+ .wallet-name {
125
+ font-weight: 600;
126
+ color: #1f2937;
127
+ font-size: 0.9rem;
128
+ }
129
+
130
+ .demo-actions {
131
+ display: flex;
132
+ gap: 20px;
133
+ justify-content: center;
134
+ flex-wrap: wrap;
135
+ }
136
+
137
+ .demo-btn {
138
+ background: #4361ee;
139
+ color: white;
140
+ border: none;
141
+ border-radius: 12px;
142
+ padding: 15px 30px;
143
+ font-size: 1.1rem;
144
+ font-weight: 600;
145
+ cursor: pointer;
146
+ transition: all 0.3s ease;
147
+ text-decoration: none;
148
+ display: inline-flex;
149
+ align-items: center;
150
+ gap: 10px;
151
+ }
152
+
153
+ .demo-btn:hover {
154
+ background: #3f37c9;
155
+ transform: translateY(-2px);
156
+ box-shadow: 0 10px 20px rgba(67, 97, 238, 0.3);
157
+ }
158
+
159
+ .demo-btn.secondary {
160
+ background: #6b7280;
161
+ }
162
+
163
+ .demo-btn.secondary:hover {
164
+ background: #4b5563;
165
+ }
166
+
167
+ .demo-info {
168
+ background: #f0f9ff;
169
+ border: 1px solid #0ea5e9;
170
+ border-radius: 12px;
171
+ padding: 20px;
172
+ margin-top: 30px;
173
+ }
174
+
175
+ .demo-info-title {
176
+ color: #0369a1;
177
+ font-weight: 600;
178
+ margin-bottom: 10px;
179
+ }
180
+
181
+ .demo-info-text {
182
+ color: #0c4a6e;
183
+ line-height: 1.6;
184
+ }
185
+
186
+ .credentials {
187
+ background: #fef3c7;
188
+ border: 1px solid #f59e0b;
189
+ border-radius: 12px;
190
+ padding: 20px;
191
+ margin-top: 20px;
192
+ }
193
+
194
+ .credentials-title {
195
+ color: #92400e;
196
+ font-weight: 600;
197
+ margin-bottom: 10px;
198
+ }
199
+
200
+ .credentials-list {
201
+ color: #78350f;
202
+ text-align: right;
203
+ }
204
+
205
+ @media (max-width: 768px) {
206
+ .demo-container {
207
+ padding: 20px;
208
+ margin: 10px;
209
+ }
210
+
211
+ .demo-title {
212
+ font-size: 2rem;
213
+ }
214
+
215
+ .wallets-grid {
216
+ grid-template-columns: repeat(2, 1fr);
217
+ }
218
+
219
+ .demo-actions {
220
+ flex-direction: column;
221
+ align-items: center;
222
+ }
223
+
224
+ .demo-btn {
225
+ width: 100%;
226
+ max-width: 300px;
227
+ }
228
+ }
229
+ </style>
230
+ </head>
231
+ <body>
232
+ <div class="demo-container">
233
+ <div class="demo-header">
234
+ <div class="demo-logo">💳</div>
235
+ <h1 class="demo-title">محفظتي الموحدة</h1>
236
+ <p class="demo-subtitle">جميع محافظك الإلكترونية اليمنية في مكان واحد</p>
237
+ </div>
238
+
239
+ <div class="demo-features">
240
+ <div class="feature-card">
241
+ <div class="feature-icon">🔐</div>
242
+ <h3 class="feature-title">أمان متقدم</h3>
243
+ <p class="feature-description">نظام أمان متطور مع خيارات متعددة للتحقق (PIN، بصمة، OTP)</p>
244
+ </div>
245
+
246
+ <div class="feature-card">
247
+ <div class="feature-icon">💸</div>
248
+ <h3 class="feature-title">تحويلات سريعة</h3>
249
+ <p class="feature-description">تحويل الأموال بين المحافظ المختلفة بسهولة وأمان</p>
250
+ </div>
251
+
252
+ <div class="feature-card">
253
+ <div class="feature-icon">📱</div>
254
+ <h3 class="feature-title">واجهة موحدة</h3>
255
+ <p class="feature-description">إدارة جميع محافظك من تطبيق واحد بواجهة عصرية</p>
256
+ </div>
257
+ </div>
258
+
259
+ <div class="demo-wallets">
260
+ <h3>المحافظ المدعومة</h3>
261
+ <div class="wallets-grid">
262
+ <div class="wallet-item">
263
+ <div class="wallet-logo">
264
+ <img src="https://play-lh.googleusercontent.com/NuKV_Snecpx633RHzIWvFauG32WBAk-jt3lcZOajw2w7VD8Hdt8h5Lb0pYLopB_Qk4Y=w240-h480" alt="جوالي">
265
+ </div>
266
+ <div class="wallet-name">جوالي</div>
267
+ </div>
268
+
269
+ <div class="wallet-item">
270
+ <div class="wallet-logo">
271
+ <img src="https://play-lh.googleusercontent.com/OF2xMRUmNH47BIaOTbv7GgvmLRTQbT1xHkFF_Ocswx6Jq5gfX4VlfAl_275UmjH2pg=w240-h480" alt="ONE Cash">
272
+ </div>
273
+ <div class="wallet-name">ONE Cash</div>
274
+ </div>
275
+
276
+ <div class="wallet-item">
277
+ <div class="wallet-logo">
278
+ <img src="https://play-lh.googleusercontent.com/zkV8HeO6iF2xa77ObHdKfAXfrfjU5fgWB0XsWt7_DmG4VGSKob2jU_CrqWyKQtghQyE=w240-h480" alt="Cash">
279
+ </div>
280
+ <div class="wallet-name">Cash</div>
281
+ </div>
282
+
283
+ <div class="wallet-item">
284
+ <div class="wallet-logo">
285
+ <img src="https://play-lh.googleusercontent.com/EAaXnjh1FVPYpI5qWZwWvZIV5oD1hm9auDX0owOgREBjMAzYKX9od1USWRzlXIhRvKMx=w240-h480" alt="Jaib">
286
+ </div>
287
+ <div class="wallet-name">Jaib</div>
288
+ </div>
289
+
290
+ <div class="wallet-item">
291
+ <div class="wallet-logo">
292
+ <img src="https://play-lh.googleusercontent.com/mNvakjEk-3VX7icU5w4xmAhT4MQgGAGcQYpRvPkBLVTzD-sYnmzAH_wuglMujTsaqQ=w240-h480" alt="mFloos">
293
+ </div>
294
+ <div class="wallet-name">mFloos</div>
295
+ </div>
296
+
297
+ <div class="wallet-item">
298
+ <div class="wallet-logo">
299
+ <img src="https://play-lh.googleusercontent.com/51r7PLMlK0gVvITgOoJ7BnGX-9Gq3_ayiSiHHxSDbJZPCgABXI_LnU6jNCHAefWHvSPV=w240-h480" alt="Mobile Money">
300
+ </div>
301
+ <div class="wallet-name">Mobile Money</div>
302
+ </div>
303
+ </div>
304
+ </div>
305
+
306
+ <div class="demo-actions">
307
+ <a href="index.html" class="demo-btn">
308
+ 🚀 تجربة التطبيق
309
+ </a>
310
+ <a href="الاخير.html" class="demo-btn secondary">
311
+ 📄 النظام الأصلي
312
+ </a>
313
+ </div>
314
+
315
+ <div class="credentials">
316
+ <div class="credentials-title">بيانات التجربة:</div>
317
+ <div class="credentials-list">
318
+ <div>رقم الهاتف: أي رقم يمني صحيح (9 أرقام)</div>
319
+ <div>رمز PIN: أي رمز من 4-6 أرقام</div>
320
+ <div>مثال: 777123456 / 1234</div>
321
+ </div>
322
+ </div>
323
+
324
+ <div class="demo-info">
325
+ <div class="demo-info-title">ملاحظة مهمة:</div>
326
+ <div class="demo-info-text">
327
+ هذا تطبيق تجريبي لأغراض العرض فقط. جميع البيانات والمعاملات محاكاة ولا تؤثر على الحسابات الحقيقية.
328
+ التطبيق يدعم المصادقة البيومترية في المتصفحات المتوافقة.
329
+ </div>
330
+ </div>
331
+ </div>
332
+ </body>
333
+ </html>
index.html ADDED
@@ -0,0 +1,369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>محفظتي الموحدة - جميع المحافظ الإلكترونية اليمنية</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@300;400;500;700&display=swap" rel="stylesheet">
8
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
9
+ <link rel="stylesheet" href="styles.css">
10
+ </head>
11
+ <body>
12
+ <!-- شاشة التحميل -->
13
+ <div id="loading-screen" class="loading-screen">
14
+ <div class="loading-content">
15
+ <div class="loading-logo">
16
+ <i class="fas fa-wallet"></i>
17
+ </div>
18
+ <h2>محفظتي الموحدة</h2>
19
+ <div class="loading-spinner"></div>
20
+ <p>جاري تحميل محافظك...</p>
21
+ </div>
22
+ </div>
23
+
24
+ <!-- شاشة تسجيل الدخول -->
25
+ <div id="login-screen" class="screen active">
26
+ <div class="login-container">
27
+ <div class="login-header">
28
+ <div class="app-logo">
29
+ <i class="fas fa-wallet"></i>
30
+ </div>
31
+ <h1>محفظتي الموحدة</h1>
32
+ <p>جميع محافظك الإلكترونية في مكان واحد</p>
33
+ </div>
34
+
35
+ <div class="login-form">
36
+ <div class="form-group">
37
+ <label for="phone-number">رقم الهاتف</label>
38
+ <div class="input-group">
39
+ <span class="input-prefix">+967</span>
40
+ <input type="tel" id="phone-number" placeholder="7xxxxxxxx" maxlength="9">
41
+ </div>
42
+ </div>
43
+
44
+ <div class="form-group">
45
+ <label for="pin-code">رمز PIN</label>
46
+ <input type="password" id="pin-code" placeholder="أدخل رمز PIN" maxlength="6">
47
+ </div>
48
+
49
+ <button id="login-btn" class="btn-primary">
50
+ <i class="fas fa-sign-in-alt"></i>
51
+ تسجيل الدخول
52
+ </button>
53
+
54
+ <div class="alternative-login">
55
+ <p>أو</p>
56
+ <button id="biometric-login" class="btn-secondary">
57
+ <i class="fas fa-fingerprint"></i>
58
+ تسجيل الدخول بالبصمة
59
+ </button>
60
+ </div>
61
+
62
+ <div class="register-link">
63
+ <p>ليس لديك حساب؟ <a href="#" id="register-link">إنشاء حساب جديد</a></p>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="supported-wallets">
68
+ <h3>المحافظ المدعومة</h3>
69
+ <div class="wallet-logos">
70
+ <div class="wallet-logo" title="جوالي">
71
+ <img src="https://play-lh.googleusercontent.com/NuKV_Snecpx633RHzIWvFauG32WBAk-jt3lcZOajw2w7VD8Hdt8h5Lb0pYLopB_Qk4Y=w240-h480" alt="جوالي">
72
+ </div>
73
+ <div class="wallet-logo" title="ONE Cash">
74
+ <img src="https://play-lh.googleusercontent.com/OF2xMRUmNH47BIaOTbv7GgvmLRTQbT1xHkFF_Ocswx6Jq5gfX4VlfAl_275UmjH2pg=w240-h480" alt="ONE Cash">
75
+ </div>
76
+ <div class="wallet-logo" title="Cash">
77
+ <img src="https://play-lh.googleusercontent.com/zkV8HeO6iF2xa77ObHdKfAXfrfjU5fgWB0XsWt7_DmG4VGSKob2jU_CrqWyKQtghQyE=w240-h480" alt="Cash">
78
+ </div>
79
+ <div class="wallet-logo" title="Jaib">
80
+ <img src="https://play-lh.googleusercontent.com/EAaXnjh1FVPYpI5qWZwWvZIV5oD1hm9auDX0owOgREBjMAzYKX9od1USWRzlXIhRvKMx=w240-h480" alt="Jaib">
81
+ </div>
82
+ <div class="wallet-logo" title="mFloos">
83
+ <img src="https://play-lh.googleusercontent.com/mNvakjEk-3VX7icU5w4xmAhT4MQgGAGcQYpRvPkBLVTzD-sYnmzAH_wuglMujTsaqQ=w240-h480" alt="mFloos">
84
+ </div>
85
+ <div class="wallet-logo" title="Mobile Money">
86
+ <img src="https://play-lh.googleusercontent.com/51r7PLMlK0gVvITgOoJ7BnGX-9Gq3_ayiSiHHxSDbJZPCgABXI_LnU6jNCHAefWHvSPV=w240-h480" alt="Mobile Money">
87
+ </div>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- الشاشة الرئيسية -->
94
+ <div id="main-screen" class="screen">
95
+ <header class="main-header">
96
+ <div class="header-top">
97
+ <div class="user-info">
98
+ <div class="user-avatar">
99
+ <i class="fas fa-user"></i>
100
+ </div>
101
+ <div class="user-details">
102
+ <h3 id="user-name">مرحباً بك</h3>
103
+ <p id="user-phone">+967 7xxxxxxxx</p>
104
+ </div>
105
+ </div>
106
+ <div class="header-actions">
107
+ <button class="icon-btn" id="notifications-btn">
108
+ <i class="fas fa-bell"></i>
109
+ <span class="badge">3</span>
110
+ </button>
111
+ <button class="icon-btn" id="settings-btn">
112
+ <i class="fas fa-cog"></i>
113
+ </button>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="total-balance">
118
+ <h2>إجمالي الرصيد</h2>
119
+ <div class="balance-amount" id="total-balance">0 ر.ي</div>
120
+ <div class="balance-actions">
121
+ <button class="btn-small" id="refresh-balance">
122
+ <i class="fas fa-sync-alt"></i>
123
+ تحديث
124
+ </button>
125
+ <button class="btn-small" id="hide-balance">
126
+ <i class="fas fa-eye-slash"></i>
127
+ إخفاء
128
+ </button>
129
+ </div>
130
+ </div>
131
+ </header>
132
+
133
+ <main class="main-content">
134
+ <!-- قائمة الإجراءات السريعة -->
135
+ <section class="quick-actions">
136
+ <h3>الإجراءات السريعة</h3>
137
+ <div class="actions-grid">
138
+ <button class="action-btn" id="transfer-btn">
139
+ <i class="fas fa-exchange-alt"></i>
140
+ <span>تحويل</span>
141
+ </button>
142
+ <button class="action-btn" id="pay-bills-btn">
143
+ <i class="fas fa-file-invoice-dollar"></i>
144
+ <span>دفع فواتير</span>
145
+ </button>
146
+ <button class="action-btn" id="recharge-btn">
147
+ <i class="fas fa-mobile-alt"></i>
148
+ <span>شحن رصيد</span>
149
+ </button>
150
+ <button class="action-btn" id="qr-scan-btn">
151
+ <i class="fas fa-qrcode"></i>
152
+ <span>مسح QR</span>
153
+ </button>
154
+ </div>
155
+ </section>
156
+
157
+ <!-- قائمة المحافظ -->
158
+ <section class="wallets-section">
159
+ <div class="section-header">
160
+ <h3>محافظي</h3>
161
+ <button class="btn-link" id="manage-wallets">إدارة المحافظ</button>
162
+ </div>
163
+ <div class="wallets-list" id="wallets-list">
164
+ <!-- سيتم ملء المحافظ ديناميكياً -->
165
+ </div>
166
+ </section>
167
+
168
+ <!-- آخر المعاملات -->
169
+ <section class="transactions-section">
170
+ <div class="section-header">
171
+ <h3>آخر المعاملات</h3>
172
+ <button class="btn-link" id="view-all-transactions">عرض الكل</button>
173
+ </div>
174
+ <div class="transactions-list" id="transactions-list">
175
+ <!-- سيتم ملء المعاملات ديناميكياً -->
176
+ </div>
177
+ </section>
178
+ </main>
179
+
180
+ <!-- شريط التنقل السفلي -->
181
+ <nav class="bottom-nav">
182
+ <button class="nav-item active" data-screen="main">
183
+ <i class="fas fa-home"></i>
184
+ <span>الرئيسية</span>
185
+ </button>
186
+ <button class="nav-item" data-screen="transfer">
187
+ <i class="fas fa-exchange-alt"></i>
188
+ <span>تحويل</span>
189
+ </button>
190
+ <button class="nav-item" data-screen="history">
191
+ <i class="fas fa-history"></i>
192
+ <span>السجل</span>
193
+ </button>
194
+ <button class="nav-item" data-screen="profile">
195
+ <i class="fas fa-user"></i>
196
+ <span>الملف الشخصي</span>
197
+ </button>
198
+ </nav>
199
+ </div>
200
+
201
+ <!-- شاشة التحويل -->
202
+ <div id="transfer-screen" class="screen">
203
+ <header class="screen-header">
204
+ <button class="back-btn" id="transfer-back">
205
+ <i class="fas fa-arrow-right"></i>
206
+ </button>
207
+ <h2>تحويل الأموال</h2>
208
+ </header>
209
+
210
+ <div class="transfer-content">
211
+ <div class="transfer-steps">
212
+ <div class="step-indicator">
213
+ <div class="step active" id="transfer-step-1">1</div>
214
+ <div class="step-line"></div>
215
+ <div class="step" id="transfer-step-2">2</div>
216
+ <div class="step-line"></div>
217
+ <div class="step" id="transfer-step-3">3</div>
218
+ </div>
219
+ <div class="step-labels">
220
+ <span>اختيار المحفظة</span>
221
+ <span>تفاصيل التحويل</span>
222
+ <span>التأكيد</span>
223
+ </div>
224
+ </div>
225
+
226
+ <!-- الخطوة الأولى: اختيار المحفظة -->
227
+ <div class="transfer-step-content active" id="transfer-step-content-1">
228
+ <h3>اختر المحفظة المرسلة</h3>
229
+ <div class="wallet-selection" id="source-wallet-selection">
230
+ <!-- سيتم ملء المحافظ ديناميكياً -->
231
+ </div>
232
+ </div>
233
+
234
+ <!-- الخطوة الثانية: تفاصيل التحويل -->
235
+ <div class="transfer-step-content" id="transfer-step-content-2">
236
+ <h3>تفاصيل التحويل</h3>
237
+
238
+ <div class="form-group">
239
+ <label>المحفظة المستقبلة</label>
240
+ <select id="destination-wallet" class="form-control">
241
+ <option value="">-- اختر المحفظة --</option>
242
+ <option value="jawali">جوالي</option>
243
+ <option value="onecash">ONE Cash</option>
244
+ <option value="cash">Cash</option>
245
+ <option value="jaib">Jaib</option>
246
+ <option value="mfloos">mFloos</option>
247
+ <option value="mobilemoney">Mobile Money</option>
248
+ </select>
249
+ </div>
250
+
251
+ <div class="form-group">
252
+ <label>رقم المستقبل</label>
253
+ <div class="input-group">
254
+ <span class="input-prefix">+967</span>
255
+ <input type="tel" id="recipient-number" placeholder="7xxxxxxxx" maxlength="9" class="form-control">
256
+ </div>
257
+ </div>
258
+
259
+ <div class="form-group">
260
+ <label>المبلغ (ر.ي)</label>
261
+ <input type="number" id="transfer-amount" placeholder="أدخل المبلغ" class="form-control">
262
+ <div class="amount-suggestions">
263
+ <button type="button" class="amount-btn" data-amount="100">100</button>
264
+ <button type="button" class="amount-btn" data-amount="500">500</button>
265
+ <button type="button" class="amount-btn" data-amount="1000">1000</button>
266
+ <button type="button" class="amount-btn" data-amount="5000">5000</button>
267
+ </div>
268
+ </div>
269
+
270
+ <div class="form-group">
271
+ <label>ملاحظة (اختياري)</label>
272
+ <textarea id="transfer-note" placeholder="أضف ملاحظة..." rows="3" class="form-control"></textarea>
273
+ </div>
274
+ </div>
275
+
276
+ <!-- الخطوة الثالثة: التأكيد -->
277
+ <div class="transfer-step-content" id="transfer-step-content-3">
278
+ <h3>تأكيد التحويل</h3>
279
+
280
+ <div class="transfer-summary">
281
+ <div class="summary-item">
282
+ <span>من:</span>
283
+ <strong id="summary-from-wallet">-</strong>
284
+ </div>
285
+ <div class="summary-item">
286
+ <span>إلى:</span>
287
+ <strong id="summary-to-wallet">-</strong>
288
+ </div>
289
+ <div class="summary-item">
290
+ <span>رقم المستقبل:</span>
291
+ <strong id="summary-recipient">-</strong>
292
+ </div>
293
+ <div class="summary-item">
294
+ <span>المبلغ:</span>
295
+ <strong id="summary-amount">-</strong>
296
+ </div>
297
+ <div class="summary-item">
298
+ <span>رسوم التحويل:</span>
299
+ <strong id="summary-fee">-</strong>
300
+ </div>
301
+ <div class="summary-item total">
302
+ <span>إجمالي المبلغ المخصوم:</span>
303
+ <strong id="summary-total">-</strong>
304
+ </div>
305
+ </div>
306
+
307
+ <div class="form-group">
308
+ <label>رمز PIN للتأكيد</label>
309
+ <input type="password" id="transfer-pin" placeholder="أدخل رمز PIN" maxlength="6" class="form-control">
310
+ </div>
311
+ </div>
312
+
313
+ <!-- أزرار التنقل -->
314
+ <div class="transfer-navigation">
315
+ <button type="button" id="transfer-prev-btn" class="btn-secondary" style="display: none;">
316
+ <i class="fas fa-arrow-right"></i>
317
+ السابق
318
+ </button>
319
+ <button type="button" id="transfer-next-btn" class="btn-primary">
320
+ التالي
321
+ <i class="fas fa-arrow-left"></i>
322
+ </button>
323
+ <button type="button" id="transfer-confirm-btn" class="btn-primary" style="display: none;">
324
+ <i class="fas fa-check"></i>
325
+ تأكيد التحويل
326
+ </button>
327
+ </div>
328
+ </div>
329
+ </div>
330
+
331
+ <!-- النوافذ المنبثقة والمودالز -->
332
+ <div id="modal-overlay" class="modal-overlay"></div>
333
+
334
+ <!-- Capacitor Core -->
335
+ <script type="module" src="https://unpkg.com/@capacitor/core@4/dist/capacitor.js"></script>
336
+
337
+ <!-- تحميل الملفات الخارجية -->
338
+ <script src="notifications.js"></script>
339
+ <script src="auth.js"></script>
340
+ <script src="wallets.js"></script>
341
+ <script src="app.js"></script>
342
+
343
+ <!-- Capacitor Initialization -->
344
+ <script>
345
+ // تهيئة Capacitor
346
+ if (window.Capacitor) {
347
+ console.log('Capacitor is available');
348
+
349
+ // إعداد الإشعارات
350
+ if (window.Capacitor.Plugins.LocalNotifications) {
351
+ window.Capacitor.Plugins.LocalNotifications.requestPermissions();
352
+ }
353
+
354
+ // إعداد شريط الحالة
355
+ if (window.Capacitor.Plugins.StatusBar) {
356
+ window.Capacitor.Plugins.StatusBar.setStyle({ style: 'LIGHT' });
357
+ window.Capacitor.Plugins.StatusBar.setBackgroundColor({ color: '#4361ee' });
358
+ }
359
+
360
+ // إخفاء شاشة البداية
361
+ if (window.Capacitor.Plugins.SplashScreen) {
362
+ setTimeout(() => {
363
+ window.Capacitor.Plugins.SplashScreen.hide();
364
+ }, 2000);
365
+ }
366
+ }
367
+ </script>
368
+ </body>
369
+ </html>
ionic.config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "unified-wallet-app",
3
+ "integrations": {
4
+ "capacitor": {}
5
+ },
6
+ "type": "angular",
7
+ "id": "unified-wallet"
8
+ }
notifications.js ADDED
@@ -0,0 +1,371 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // نظام الإشعارات والتنبيهات
2
+ class NotificationManager {
3
+ constructor() {
4
+ this.notifications = [];
5
+ this.toastContainer = null;
6
+ this.modalContainer = null;
7
+ this.init();
8
+ }
9
+
10
+ // تهيئة نظام الإشعارات
11
+ init() {
12
+ this.createToastContainer();
13
+ this.createModalContainer();
14
+ this.loadStoredNotifications();
15
+ }
16
+
17
+ // إنشاء حاوية التوست
18
+ createToastContainer() {
19
+ this.toastContainer = document.createElement('div');
20
+ this.toastContainer.className = 'toast-container';
21
+ this.toastContainer.innerHTML = '';
22
+ document.body.appendChild(this.toastContainer);
23
+ }
24
+
25
+ // إنشاء حاوية المودال
26
+ createModalContainer() {
27
+ this.modalContainer = document.createElement('div');
28
+ this.modalContainer.className = 'modal-container';
29
+ this.modalContainer.innerHTML = `
30
+ <div class="modal-overlay" onclick="this.parentElement.style.display='none'"></div>
31
+ <div class="modal-content">
32
+ <div class="modal-header">
33
+ <h3 class="modal-title"></h3>
34
+ <button class="modal-close" onclick="this.closest('.modal-container').style.display='none'">
35
+ <i class="fas fa-times"></i>
36
+ </button>
37
+ </div>
38
+ <div class="modal-body"></div>
39
+ <div class="modal-footer"></div>
40
+ </div>
41
+ `;
42
+ document.body.appendChild(this.modalContainer);
43
+ }
44
+
45
+ // عرض تنبيه توست
46
+ showToast(message, type = 'info', duration = 5000) {
47
+ const toast = document.createElement('div');
48
+ toast.className = `toast toast-${type}`;
49
+
50
+ const icon = this.getToastIcon(type);
51
+
52
+ toast.innerHTML = `
53
+ <div class="toast-icon">
54
+ <i class="${icon}"></i>
55
+ </div>
56
+ <div class="toast-content">
57
+ <div class="toast-message">${message}</div>
58
+ </div>
59
+ <button class="toast-close" onclick="this.parentElement.remove()">
60
+ <i class="fas fa-times"></i>
61
+ </button>
62
+ `;
63
+
64
+ // إضافة التوست
65
+ this.toastContainer.appendChild(toast);
66
+
67
+ // تحريك التوست للداخل
68
+ setTimeout(() => {
69
+ toast.classList.add('toast-show');
70
+ }, 100);
71
+
72
+ // إزالة التوست تلقائياً
73
+ if (duration > 0) {
74
+ setTimeout(() => {
75
+ this.removeToast(toast);
76
+ }, duration);
77
+ }
78
+
79
+ return toast;
80
+ }
81
+
82
+ // إزالة التوست
83
+ removeToast(toast) {
84
+ toast.classList.add('toast-hide');
85
+ setTimeout(() => {
86
+ if (toast.parentElement) {
87
+ toast.parentElement.removeChild(toast);
88
+ }
89
+ }, 300);
90
+ }
91
+
92
+ // الحصول على أيقونة التوست
93
+ getToastIcon(type) {
94
+ const icons = {
95
+ success: 'fas fa-check-circle',
96
+ error: 'fas fa-exclamation-circle',
97
+ warning: 'fas fa-exclamation-triangle',
98
+ info: 'fas fa-info-circle',
99
+ loading: 'fas fa-spinner fa-spin'
100
+ };
101
+ return icons[type] || icons.info;
102
+ }
103
+
104
+ // عرض مودال
105
+ showModal(title, content, buttons = []) {
106
+ const modal = this.modalContainer;
107
+
108
+ modal.querySelector('.modal-title').textContent = title;
109
+ modal.querySelector('.modal-body').innerHTML = content;
110
+
111
+ // إضافة الأزرار
112
+ const footer = modal.querySelector('.modal-footer');
113
+ footer.innerHTML = '';
114
+
115
+ buttons.forEach(button => {
116
+ const btn = document.createElement('button');
117
+ btn.className = `btn ${button.class || 'btn-primary'}`;
118
+ btn.textContent = button.text;
119
+ btn.onclick = () => {
120
+ if (button.action) button.action();
121
+ modal.style.display = 'none';
122
+ };
123
+ footer.appendChild(btn);
124
+ });
125
+
126
+ // إضافة زر إغلاق افتراضي إذا لم توجد أزرار
127
+ if (buttons.length === 0) {
128
+ const closeBtn = document.createElement('button');
129
+ closeBtn.className = 'btn btn-secondary';
130
+ closeBtn.textContent = 'إغلاق';
131
+ closeBtn.onclick = () => modal.style.display = 'none';
132
+ footer.appendChild(closeBtn);
133
+ }
134
+
135
+ modal.style.display = 'flex';
136
+ return modal;
137
+ }
138
+
139
+ // عرض مودال تأكيد
140
+ showConfirm(title, message, onConfirm, onCancel) {
141
+ return this.showModal(title, `<p>${message}</p>`, [
142
+ {
143
+ text: 'تأكيد',
144
+ class: 'btn-primary',
145
+ action: onConfirm
146
+ },
147
+ {
148
+ text: 'إلغاء',
149
+ class: 'btn-secondary',
150
+ action: onCancel
151
+ }
152
+ ]);
153
+ }
154
+
155
+ // عرض مودال تحميل
156
+ showLoading(message = 'جاري التحميل...') {
157
+ const loadingContent = `
158
+ <div class="loading-content">
159
+ <div class="loading-spinner"></div>
160
+ <p>${message}</p>
161
+ </div>
162
+ `;
163
+
164
+ const modal = this.showModal('', loadingContent, []);
165
+ modal.classList.add('loading-modal');
166
+
167
+ // منع إغلاق مودال التحميل بالنقر خارجه
168
+ modal.querySelector('.modal-overlay').onclick = null;
169
+ modal.querySelector('.modal-close').style.display = 'none';
170
+
171
+ return modal;
172
+ }
173
+
174
+ // إخفاء مودال التحميل
175
+ hideLoading() {
176
+ const loadingModal = document.querySelector('.loading-modal');
177
+ if (loadingModal) {
178
+ loadingModal.style.display = 'none';
179
+ loadingModal.classList.remove('loading-modal');
180
+ }
181
+ }
182
+
183
+ // إضافة إشعار
184
+ addNotification(notification) {
185
+ const newNotification = {
186
+ id: Date.now(),
187
+ timestamp: new Date().toISOString(),
188
+ read: false,
189
+ ...notification
190
+ };
191
+
192
+ this.notifications.unshift(newNotification);
193
+ this.saveNotifications();
194
+ this.updateNotificationBadge();
195
+
196
+ return newNotification;
197
+ }
198
+
199
+ // وضع علامة مقروء على الإشعار
200
+ markAsRead(notificationId) {
201
+ const notification = this.notifications.find(n => n.id === notificationId);
202
+ if (notification) {
203
+ notification.read = true;
204
+ this.saveNotifications();
205
+ this.updateNotificationBadge();
206
+ }
207
+ }
208
+
209
+ // وضع علامة مقروء على جميع الإشعارات
210
+ markAllAsRead() {
211
+ this.notifications.forEach(n => n.read = true);
212
+ this.saveNotifications();
213
+ this.updateNotificationBadge();
214
+ }
215
+
216
+ // حذف إشعار
217
+ deleteNotification(notificationId) {
218
+ this.notifications = this.notifications.filter(n => n.id !== notificationId);
219
+ this.saveNotifications();
220
+ this.updateNotificationBadge();
221
+ }
222
+
223
+ // الحصول على الإشعارات غير المقروءة
224
+ getUnreadNotifications() {
225
+ return this.notifications.filter(n => !n.read);
226
+ }
227
+
228
+ // الحصول على عدد الإشعارات غير المقروءة
229
+ getUnreadCount() {
230
+ return this.getUnreadNotifications().length;
231
+ }
232
+
233
+ // تحديث شارة الإشعارات
234
+ updateNotificationBadge() {
235
+ const badge = document.querySelector('#notifications-btn .badge');
236
+ const unreadCount = this.getUnreadCount();
237
+
238
+ if (badge) {
239
+ if (unreadCount > 0) {
240
+ badge.textContent = unreadCount > 99 ? '99+' : unreadCount;
241
+ badge.style.display = 'block';
242
+ } else {
243
+ badge.style.display = 'none';
244
+ }
245
+ }
246
+ }
247
+
248
+ // عرض قائمة الإشعارات
249
+ showNotificationsList() {
250
+ const notificationsHtml = this.notifications.length > 0 ?
251
+ this.notifications.map(n => this.renderNotification(n)).join('') :
252
+ '<div class="no-notifications">لا توجد إشعارات</div>';
253
+
254
+ const content = `
255
+ <div class="notifications-header">
256
+ <button class="btn btn-link" onclick="window.notificationManager.markAllAsRead()">
257
+ وضع علامة مقروء على الكل
258
+ </button>
259
+ </div>
260
+ <div class="notifications-list">
261
+ ${notificationsHtml}
262
+ </div>
263
+ `;
264
+
265
+ this.showModal('الإشعارات', content, []);
266
+ }
267
+
268
+ // عرض إشعار واحد
269
+ renderNotification(notification) {
270
+ const timeAgo = this.getTimeAgo(notification.timestamp);
271
+ const readClass = notification.read ? 'read' : 'unread';
272
+
273
+ return `
274
+ <div class="notification-item ${readClass}" data-id="${notification.id}">
275
+ <div class="notification-icon ${notification.type}">
276
+ <i class="${this.getNotificationIcon(notification.type)}"></i>
277
+ </div>
278
+ <div class="notification-content">
279
+ <h4>${notification.title}</h4>
280
+ <p>${notification.message}</p>
281
+ <span class="notification-time">${timeAgo}</span>
282
+ </div>
283
+ <div class="notification-actions">
284
+ ${!notification.read ? `
285
+ <button onclick="window.notificationManager.markAsRead(${notification.id})" title="وضع علامة مقروء">
286
+ <i class="fas fa-check"></i>
287
+ </button>
288
+ ` : ''}
289
+ <button onclick="window.notificationManager.deleteNotification(${notification.id})" title="حذف">
290
+ <i class="fas fa-trash"></i>
291
+ </button>
292
+ </div>
293
+ </div>
294
+ `;
295
+ }
296
+
297
+ // الحصول على أيقونة الإشعار
298
+ getNotificationIcon(type) {
299
+ const icons = {
300
+ transaction: 'fas fa-exchange-alt',
301
+ security: 'fas fa-shield-alt',
302
+ system: 'fas fa-cog',
303
+ promotion: 'fas fa-gift',
304
+ warning: 'fas fa-exclamation-triangle'
305
+ };
306
+ return icons[type] || 'fas fa-bell';
307
+ }
308
+
309
+ // حساب الوقت المنقضي
310
+ getTimeAgo(timestamp) {
311
+ const now = new Date();
312
+ const time = new Date(timestamp);
313
+ const diffInSeconds = Math.floor((now - time) / 1000);
314
+
315
+ if (diffInSeconds < 60) return 'الآن';
316
+ if (diffInSeconds < 3600) return `${Math.floor(diffInSeconds / 60)} دقيقة`;
317
+ if (diffInSeconds < 86400) return `${Math.floor(diffInSeconds / 3600)} ساعة`;
318
+ if (diffInSeconds < 2592000) return `${Math.floor(diffInSeconds / 86400)} يوم`;
319
+ return time.toLocaleDateString('ar-SA');
320
+ }
321
+
322
+ // حفظ الإشعارات
323
+ saveNotifications() {
324
+ localStorage.setItem('unifiedWallet_notifications', JSON.stringify(this.notifications));
325
+ }
326
+
327
+ // تحميل الإشعارات المحفوظة
328
+ loadStoredNotifications() {
329
+ const stored = localStorage.getItem('unifiedWallet_notifications');
330
+ if (stored) {
331
+ this.notifications = JSON.parse(stored);
332
+ this.updateNotificationBadge();
333
+ }
334
+ }
335
+
336
+ // إضافة إشعار معاملة
337
+ addTransactionNotification(type, amount, wallet) {
338
+ const messages = {
339
+ send: `تم إرسال ${amount.toLocaleString()} ر.ي من ${wallet}`,
340
+ receive: `تم استلام ${amount.toLocaleString()} ر.ي في ${wallet}`,
341
+ bill: `تم دفع فاتورة بمبلغ ${amount.toLocaleString()} ر.ي من ${wallet}`
342
+ };
343
+
344
+ this.addNotification({
345
+ type: 'transaction',
346
+ title: 'معاملة جديدة',
347
+ message: messages[type] || `معاملة بمبلغ ${amount.toLocaleString()} ر.ي`
348
+ });
349
+ }
350
+
351
+ // إضافة إشعار أمني
352
+ addSecurityNotification(message) {
353
+ this.addNotification({
354
+ type: 'security',
355
+ title: 'تنبيه أمني',
356
+ message: message
357
+ });
358
+ }
359
+
360
+ // إضافة إشعار نظام
361
+ addSystemNotification(message) {
362
+ this.addNotification({
363
+ type: 'system',
364
+ title: 'إشعار النظام',
365
+ message: message
366
+ });
367
+ }
368
+ }
369
+
370
+ // تصدير الكلاس للاستخدام في التطبيق الرئيسي
371
+ window.NotificationManager = NotificationManager;
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package-new.json ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "unified-wallet-app",
3
+ "version": "1.0.0",
4
+ "description": "محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية الموحد",
5
+ "author": "المدى للخدمات البرمجية التسويقية والإعلانية",
6
+ "homepage": "https://almada.com/",
7
+ "main": "index.html",
8
+ "scripts": {
9
+ "start": "http-server . -p 8100",
10
+ "build": "echo 'Building for production...'",
11
+ "cap:add:android": "cap add android",
12
+ "cap:build:android": "cap copy android && cap open android",
13
+ "cap:sync": "cap sync",
14
+ "serve": "http-server . -p 8100 -o"
15
+ },
16
+ "dependencies": {
17
+ "@capacitor/android": "^4.8.0",
18
+ "@capacitor/app": "^4.1.1",
19
+ "@capacitor/core": "^4.8.0",
20
+ "@capacitor/device": "^4.1.0",
21
+ "@capacitor/haptics": "^4.1.0",
22
+ "@capacitor/keyboard": "^4.1.1",
23
+ "@capacitor/local-notifications": "^4.1.5",
24
+ "@capacitor/splash-screen": "^4.2.0",
25
+ "@capacitor/status-bar": "^4.2.0",
26
+ "@capacitor/storage": "^1.2.5"
27
+ },
28
+ "devDependencies": {
29
+ "@capacitor/cli": "^4.8.0",
30
+ "http-server": "^14.1.1"
31
+ },
32
+ "keywords": [
33
+ "wallet",
34
+ "yemen",
35
+ "fintech",
36
+ "mobile",
37
+ "محفظة",
38
+ "يمن"
39
+ ],
40
+ "license": "MIT"
41
+ }
package-simple.json ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "unified-wallet-app",
3
+ "version": "1.0.0",
4
+ "description": "محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية الموحد",
5
+ "author": "المدى للخدمات البرمجية التسويقية والإعلانية",
6
+ "homepage": "https://almada.com/",
7
+ "main": "index.html",
8
+ "scripts": {
9
+ "start": "http-server . -p 8100",
10
+ "build": "echo 'Building for production...'",
11
+ "cap:init": "cap init",
12
+ "cap:add:android": "cap add android",
13
+ "cap:build:android": "cap copy android && cap open android",
14
+ "cap:sync": "cap sync",
15
+ "serve": "http-server . -p 8100 -o"
16
+ },
17
+ "dependencies": {
18
+ "@capacitor/android": "^4.8.0",
19
+ "@capacitor/app": "^4.1.1",
20
+ "@capacitor/core": "^4.8.0",
21
+ "@capacitor/device": "^4.1.0",
22
+ "@capacitor/haptics": "^4.1.0",
23
+ "@capacitor/keyboard": "^4.1.1",
24
+ "@capacitor/local-notifications": "^4.1.5",
25
+ "@capacitor/splash-screen": "^4.2.0",
26
+ "@capacitor/status-bar": "^4.2.0",
27
+ "@capacitor/storage": "^1.2.5"
28
+ },
29
+ "devDependencies": {
30
+ "@capacitor/cli": "^4.8.0",
31
+ "http-server": "^14.1.1"
32
+ },
33
+ "keywords": [
34
+ "wallet",
35
+ "yemen",
36
+ "fintech",
37
+ "mobile",
38
+ "محفظة",
39
+ "يمن"
40
+ ],
41
+ "license": "MIT"
42
+ }
package.json ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "unified-wallet-app",
3
+ "version": "1.0.0",
4
+ "description": "محفظتي الموحدة - تطبيق المحافظ الإلكترونية اليمنية الموحد",
5
+ "author": "المدى للخدمات البرمجية التسويقية والإعلانية",
6
+ "homepage": "https://almada.com/",
7
+ "scripts": {
8
+ "start": "ionic serve",
9
+ "build": "ionic build",
10
+ "build:prod": "ionic build --prod",
11
+ "cap:add:android": "ionic cap add android",
12
+ "cap:build:android": "ionic cap build android",
13
+ "cap:open:android": "ionic cap open android",
14
+ "cap:sync": "ionic cap sync"
15
+ },
16
+ "private": true,
17
+ "dependencies": {
18
+ "@angular/animations": "^17.0.0",
19
+ "@angular/common": "^17.0.0",
20
+ "@angular/compiler": "^17.0.0",
21
+ "@angular/core": "^17.0.0",
22
+ "@angular/forms": "^17.0.0",
23
+ "@angular/platform-browser": "^17.0.0",
24
+ "@angular/platform-browser-dynamic": "^17.0.0",
25
+ "@angular/router": "^17.0.0",
26
+ "@angular/service-worker": "^17.0.0",
27
+ "@capacitor/android": "^5.0.0",
28
+ "@capacitor/app": "^5.0.0",
29
+ "@capacitor/camera": "^5.0.0",
30
+ "@capacitor/core": "^5.0.0",
31
+ "@capacitor/device": "^5.0.0",
32
+ "@capacitor/haptics": "^5.0.0",
33
+ "@capacitor/ios": "^5.0.0",
34
+ "@capacitor/keyboard": "^5.0.0",
35
+ "@capacitor/local-notifications": "^5.0.0",
36
+ "@capacitor/push-notifications": "^5.0.0",
37
+ "@capacitor/splash-screen": "^5.0.0",
38
+ "@capacitor/status-bar": "^5.0.0",
39
+ "@capacitor/preferences": "^4.0.0",
40
+ "@ionic/angular": "^7.0.0",
41
+ "@ionic/storage-angular": "^4.0.0",
42
+
43
+ "ionicons": "^7.0.0",
44
+ "rxjs": "~7.8.0",
45
+ "tslib": "^2.3.0",
46
+ "zone.js": "~0.14.0"
47
+ },
48
+ "devDependencies": {
49
+ "@angular-devkit/build-angular": "^17.0.0",
50
+ "@angular-eslint/builder": "^17.0.0",
51
+ "@angular-eslint/eslint-plugin": "^17.0.0",
52
+ "@angular-eslint/eslint-plugin-template": "^17.0.0",
53
+ "@angular-eslint/schematics": "^17.0.0",
54
+ "@angular-eslint/template-parser": "^17.0.0",
55
+ "@angular/cli": "^17.0.0",
56
+ "@angular/compiler-cli": "^17.0.0",
57
+ "@angular/language-service": "^17.0.0",
58
+ "@capacitor/cli": "^5.0.0",
59
+ "@ionic/angular-toolkit": "^9.0.0",
60
+ "@types/jasmine": "~5.1.0",
61
+ "@types/node": "^18.18.0",
62
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
63
+ "@typescript-eslint/parser": "^6.0.0",
64
+ "eslint": "^8.57.0",
65
+ "eslint-plugin-import": "^2.29.0",
66
+ "eslint-plugin-jsdoc": "^46.8.0",
67
+ "eslint-plugin-prefer-arrow": "^1.2.2",
68
+ "jasmine-core": "~5.1.0",
69
+ "karma": "~6.4.0",
70
+ "karma-chrome-launcher": "~3.2.0",
71
+ "karma-coverage": "~2.2.0",
72
+ "karma-jasmine": "~5.1.0",
73
+ "karma-jasmine-html-reporter": "~2.1.0",
74
+ "typescript": "~5.2.0"
75
+ },
76
+ "keywords": [
77
+ "ionic",
78
+ "angular",
79
+ "mobile",
80
+ "wallet",
81
+ "yemen",
82
+ "fintech",
83
+ "محفظة",
84
+ "يمن"
85
+ ]
86
+ }
styles.css ADDED
@@ -0,0 +1,1334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* المتغيرات العامة */
2
+ :root {
3
+ --primary-color: #2563eb;
4
+ --secondary-color: #1e40af;
5
+ --success-color: #059669;
6
+ --warning-color: #d97706;
7
+ --error-color: #dc2626;
8
+ --text-primary: #1f2937;
9
+ --text-secondary: #6b7280;
10
+ --background: #f8fafc;
11
+ --surface: #ffffff;
12
+ --border: #e5e7eb;
13
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
14
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
15
+ --border-radius: 12px;
16
+ --transition: all 0.3s ease;
17
+ }
18
+
19
+ /* إعادة تعيين الأساسيات */
20
+ * {
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
+ }
25
+
26
+ body {
27
+ font-family: 'Tajawal', sans-serif;
28
+ background: var(--background);
29
+ color: var(--text-primary);
30
+ line-height: 1.6;
31
+ overflow-x: hidden;
32
+ }
33
+
34
+ /* الشاشات */
35
+ .screen {
36
+ display: none;
37
+ min-height: 100vh;
38
+ position: relative;
39
+ }
40
+
41
+ .screen.active {
42
+ display: block;
43
+ }
44
+
45
+ /* شاشة التحميل */
46
+ .loading-screen {
47
+ position: fixed;
48
+ top: 0;
49
+ left: 0;
50
+ width: 100%;
51
+ height: 100%;
52
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ z-index: 9999;
57
+ color: white;
58
+ }
59
+
60
+ .loading-content {
61
+ text-align: center;
62
+ animation: fadeInUp 0.8s ease;
63
+ }
64
+
65
+ .loading-logo {
66
+ font-size: 4rem;
67
+ margin-bottom: 1rem;
68
+ animation: pulse 2s infinite;
69
+ }
70
+
71
+ .loading-spinner {
72
+ width: 40px;
73
+ height: 40px;
74
+ border: 3px solid rgba(255, 255, 255, 0.3);
75
+ border-top: 3px solid white;
76
+ border-radius: 50%;
77
+ animation: spin 1s linear infinite;
78
+ margin: 1rem auto;
79
+ }
80
+
81
+ /* شاشة تسجيل الدخول */
82
+ .login-container {
83
+ max-width: 400px;
84
+ margin: 0 auto;
85
+ padding: 2rem;
86
+ min-height: 100vh;
87
+ display: flex;
88
+ flex-direction: column;
89
+ justify-content: center;
90
+ }
91
+
92
+ .login-header {
93
+ text-align: center;
94
+ margin-bottom: 2rem;
95
+ }
96
+
97
+ .app-logo {
98
+ font-size: 3rem;
99
+ color: var(--primary-color);
100
+ margin-bottom: 1rem;
101
+ }
102
+
103
+ .login-header h1 {
104
+ font-size: 1.8rem;
105
+ font-weight: 700;
106
+ margin-bottom: 0.5rem;
107
+ }
108
+
109
+ .login-header p {
110
+ color: var(--text-secondary);
111
+ font-size: 0.9rem;
112
+ }
113
+
114
+ /* النماذج */
115
+ .form-group {
116
+ margin-bottom: 1.5rem;
117
+ }
118
+
119
+ .form-group label {
120
+ display: block;
121
+ margin-bottom: 0.5rem;
122
+ font-weight: 500;
123
+ color: var(--text-primary);
124
+ }
125
+
126
+ .input-group {
127
+ position: relative;
128
+ display: flex;
129
+ }
130
+
131
+ .input-prefix {
132
+ background: var(--border);
133
+ padding: 0.75rem 1rem;
134
+ border: 1px solid var(--border);
135
+ border-left: none;
136
+ border-radius: var(--border-radius) 0 0 var(--border-radius);
137
+ color: var(--text-secondary);
138
+ font-weight: 500;
139
+ }
140
+
141
+ input {
142
+ width: 100%;
143
+ padding: 0.75rem 1rem;
144
+ border: 1px solid var(--border);
145
+ border-radius: var(--border-radius);
146
+ font-family: inherit;
147
+ font-size: 1rem;
148
+ transition: var(--transition);
149
+ }
150
+
151
+ .input-group input {
152
+ border-radius: 0 var(--border-radius) var(--border-radius) 0;
153
+ border-right: none;
154
+ }
155
+
156
+ input:focus {
157
+ outline: none;
158
+ border-color: var(--primary-color);
159
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
160
+ }
161
+
162
+ /* الأزرار */
163
+ .btn-primary, .btn-secondary, .btn-small, .btn-link {
164
+ padding: 0.75rem 1.5rem;
165
+ border: none;
166
+ border-radius: var(--border-radius);
167
+ font-family: inherit;
168
+ font-size: 1rem;
169
+ font-weight: 500;
170
+ cursor: pointer;
171
+ transition: var(--transition);
172
+ display: inline-flex;
173
+ align-items: center;
174
+ justify-content: center;
175
+ gap: 0.5rem;
176
+ text-decoration: none;
177
+ }
178
+
179
+ .btn-primary {
180
+ background: var(--primary-color);
181
+ color: white;
182
+ width: 100%;
183
+ margin-bottom: 1rem;
184
+ }
185
+
186
+ .btn-primary:hover {
187
+ background: var(--secondary-color);
188
+ transform: translateY(-2px);
189
+ box-shadow: var(--shadow);
190
+ }
191
+
192
+ .btn-secondary {
193
+ background: var(--surface);
194
+ color: var(--text-primary);
195
+ border: 1px solid var(--border);
196
+ width: 100%;
197
+ }
198
+
199
+ .btn-secondary:hover {
200
+ background: var(--background);
201
+ }
202
+
203
+ .btn-small {
204
+ padding: 0.5rem 1rem;
205
+ font-size: 0.875rem;
206
+ background: var(--surface);
207
+ color: var(--text-primary);
208
+ border: 1px solid var(--border);
209
+ }
210
+
211
+ .btn-link {
212
+ background: none;
213
+ color: var(--primary-color);
214
+ padding: 0;
215
+ font-size: 0.875rem;
216
+ }
217
+
218
+ /* تسجيل الدخول البديل */
219
+ .alternative-login {
220
+ text-align: center;
221
+ margin: 1rem 0;
222
+ }
223
+
224
+ .alternative-login p {
225
+ color: var(--text-secondary);
226
+ margin-bottom: 1rem;
227
+ position: relative;
228
+ }
229
+
230
+ .alternative-login p::before,
231
+ .alternative-login p::after {
232
+ content: '';
233
+ position: absolute;
234
+ top: 50%;
235
+ width: 40%;
236
+ height: 1px;
237
+ background: var(--border);
238
+ }
239
+
240
+ .alternative-login p::before {
241
+ right: 60%;
242
+ }
243
+
244
+ .alternative-login p::after {
245
+ left: 60%;
246
+ }
247
+
248
+ .register-link {
249
+ text-align: center;
250
+ margin-top: 2rem;
251
+ }
252
+
253
+ .register-link a {
254
+ color: var(--primary-color);
255
+ text-decoration: none;
256
+ }
257
+
258
+ /* المحافظ المدعومة */
259
+ .supported-wallets {
260
+ margin-top: 2rem;
261
+ text-align: center;
262
+ }
263
+
264
+ .supported-wallets h3 {
265
+ font-size: 1rem;
266
+ margin-bottom: 1rem;
267
+ color: var(--text-secondary);
268
+ }
269
+
270
+ .wallet-logos {
271
+ display: grid;
272
+ grid-template-columns: repeat(3, 1fr);
273
+ gap: 1rem;
274
+ }
275
+
276
+ .wallet-logo {
277
+ width: 60px;
278
+ height: 60px;
279
+ border-radius: var(--border-radius);
280
+ overflow: hidden;
281
+ border: 1px solid var(--border);
282
+ display: flex;
283
+ align-items: center;
284
+ justify-content: center;
285
+ background: var(--surface);
286
+ transition: var(--transition);
287
+ }
288
+
289
+ .wallet-logo:hover {
290
+ transform: scale(1.05);
291
+ box-shadow: var(--shadow);
292
+ }
293
+
294
+ .wallet-logo img {
295
+ width: 100%;
296
+ height: 100%;
297
+ object-fit: cover;
298
+ }
299
+
300
+ /* الشاشة الرئيسية */
301
+ .main-header {
302
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
303
+ color: white;
304
+ padding: 2rem 1rem;
305
+ border-radius: 0 0 2rem 2rem;
306
+ }
307
+
308
+ .header-top {
309
+ display: flex;
310
+ justify-content: space-between;
311
+ align-items: center;
312
+ margin-bottom: 2rem;
313
+ }
314
+
315
+ .user-info {
316
+ display: flex;
317
+ align-items: center;
318
+ gap: 1rem;
319
+ }
320
+
321
+ .user-avatar {
322
+ width: 50px;
323
+ height: 50px;
324
+ background: rgba(255, 255, 255, 0.2);
325
+ border-radius: 50%;
326
+ display: flex;
327
+ align-items: center;
328
+ justify-content: center;
329
+ font-size: 1.5rem;
330
+ }
331
+
332
+ .user-details h3 {
333
+ font-size: 1.1rem;
334
+ margin-bottom: 0.25rem;
335
+ }
336
+
337
+ .user-details p {
338
+ font-size: 0.875rem;
339
+ opacity: 0.8;
340
+ }
341
+
342
+ .header-actions {
343
+ display: flex;
344
+ gap: 0.5rem;
345
+ }
346
+
347
+ .icon-btn {
348
+ width: 40px;
349
+ height: 40px;
350
+ background: rgba(255, 255, 255, 0.2);
351
+ border: none;
352
+ border-radius: 50%;
353
+ color: white;
354
+ cursor: pointer;
355
+ display: flex;
356
+ align-items: center;
357
+ justify-content: center;
358
+ position: relative;
359
+ transition: var(--transition);
360
+ }
361
+
362
+ .icon-btn:hover {
363
+ background: rgba(255, 255, 255, 0.3);
364
+ }
365
+
366
+ .badge {
367
+ position: absolute;
368
+ top: -5px;
369
+ left: -5px;
370
+ background: var(--error-color);
371
+ color: white;
372
+ font-size: 0.75rem;
373
+ padding: 0.125rem 0.375rem;
374
+ border-radius: 10px;
375
+ min-width: 18px;
376
+ text-align: center;
377
+ }
378
+
379
+ /* الرصيد الإجمالي */
380
+ .total-balance {
381
+ text-align: center;
382
+ }
383
+
384
+ .total-balance h2 {
385
+ font-size: 1rem;
386
+ opacity: 0.9;
387
+ margin-bottom: 0.5rem;
388
+ }
389
+
390
+ .balance-amount {
391
+ font-size: 2.5rem;
392
+ font-weight: 700;
393
+ margin-bottom: 1rem;
394
+ }
395
+
396
+ .balance-actions {
397
+ display: flex;
398
+ justify-content: center;
399
+ gap: 1rem;
400
+ }
401
+
402
+ .balance-actions .btn-small {
403
+ background: rgba(255, 255, 255, 0.2);
404
+ color: white;
405
+ border: 1px solid rgba(255, 255, 255, 0.3);
406
+ }
407
+
408
+ /* المحتوى الرئيسي */
409
+ .main-content {
410
+ padding: 2rem 1rem 6rem;
411
+ }
412
+
413
+ .main-content section {
414
+ margin-bottom: 2rem;
415
+ }
416
+
417
+ .section-header {
418
+ display: flex;
419
+ justify-content: space-between;
420
+ align-items: center;
421
+ margin-bottom: 1rem;
422
+ }
423
+
424
+ .section-header h3 {
425
+ font-size: 1.25rem;
426
+ font-weight: 600;
427
+ }
428
+
429
+ /* الإجراءات السريعة */
430
+ .actions-grid {
431
+ display: grid;
432
+ grid-template-columns: repeat(2, 1fr);
433
+ gap: 1rem;
434
+ }
435
+
436
+ .action-btn {
437
+ background: var(--surface);
438
+ border: 1px solid var(--border);
439
+ border-radius: var(--border-radius);
440
+ padding: 1.5rem;
441
+ display: flex;
442
+ flex-direction: column;
443
+ align-items: center;
444
+ gap: 0.5rem;
445
+ cursor: pointer;
446
+ transition: var(--transition);
447
+ text-decoration: none;
448
+ color: var(--text-primary);
449
+ }
450
+
451
+ .action-btn:hover {
452
+ transform: translateY(-2px);
453
+ box-shadow: var(--shadow);
454
+ border-color: var(--primary-color);
455
+ }
456
+
457
+ .action-btn i {
458
+ font-size: 1.5rem;
459
+ color: var(--primary-color);
460
+ }
461
+
462
+ .action-btn span {
463
+ font-weight: 500;
464
+ }
465
+
466
+ /* الرسوم المتحركة */
467
+ @keyframes fadeInUp {
468
+ from {
469
+ opacity: 0;
470
+ transform: translateY(30px);
471
+ }
472
+ to {
473
+ opacity: 1;
474
+ transform: translateY(0);
475
+ }
476
+ }
477
+
478
+ @keyframes pulse {
479
+ 0%, 100% {
480
+ transform: scale(1);
481
+ }
482
+ 50% {
483
+ transform: scale(1.1);
484
+ }
485
+ }
486
+
487
+ @keyframes spin {
488
+ from {
489
+ transform: rotate(0deg);
490
+ }
491
+ to {
492
+ transform: rotate(360deg);
493
+ }
494
+ }
495
+
496
+ /* قائمة المحافظ */
497
+ .wallets-list {
498
+ display: flex;
499
+ flex-direction: column;
500
+ gap: 1rem;
501
+ }
502
+
503
+ .wallet-card {
504
+ background: var(--surface);
505
+ border: 1px solid var(--border);
506
+ border-radius: var(--border-radius);
507
+ padding: 1.5rem;
508
+ display: flex;
509
+ align-items: center;
510
+ justify-content: space-between;
511
+ transition: var(--transition);
512
+ cursor: pointer;
513
+ }
514
+
515
+ .wallet-card:hover {
516
+ transform: translateY(-2px);
517
+ box-shadow: var(--shadow);
518
+ border-color: var(--primary-color);
519
+ }
520
+
521
+ .wallet-info {
522
+ display: flex;
523
+ align-items: center;
524
+ gap: 1rem;
525
+ }
526
+
527
+ .wallet-icon {
528
+ width: 50px;
529
+ height: 50px;
530
+ border-radius: var(--border-radius);
531
+ overflow: hidden;
532
+ border: 1px solid var(--border);
533
+ display: flex;
534
+ align-items: center;
535
+ justify-content: center;
536
+ }
537
+
538
+ .wallet-icon img {
539
+ width: 100%;
540
+ height: 100%;
541
+ object-fit: cover;
542
+ }
543
+
544
+ .wallet-details h4 {
545
+ font-size: 1.1rem;
546
+ font-weight: 600;
547
+ margin-bottom: 0.25rem;
548
+ }
549
+
550
+ .wallet-details p {
551
+ color: var(--text-secondary);
552
+ font-size: 0.875rem;
553
+ }
554
+
555
+ .wallet-balance {
556
+ text-align: left;
557
+ }
558
+
559
+ .wallet-balance .amount {
560
+ font-size: 1.25rem;
561
+ font-weight: 700;
562
+ color: var(--success-color);
563
+ }
564
+
565
+ .wallet-balance .currency {
566
+ font-size: 0.875rem;
567
+ color: var(--text-secondary);
568
+ }
569
+
570
+ /* قائمة المعاملات */
571
+ .transactions-list {
572
+ display: flex;
573
+ flex-direction: column;
574
+ gap: 0.75rem;
575
+ }
576
+
577
+ .transaction-item {
578
+ background: var(--surface);
579
+ border: 1px solid var(--border);
580
+ border-radius: var(--border-radius);
581
+ padding: 1rem;
582
+ display: flex;
583
+ align-items: center;
584
+ justify-content: space-between;
585
+ }
586
+
587
+ .transaction-info {
588
+ display: flex;
589
+ align-items: center;
590
+ gap: 1rem;
591
+ }
592
+
593
+ .transaction-icon {
594
+ width: 40px;
595
+ height: 40px;
596
+ border-radius: 50%;
597
+ display: flex;
598
+ align-items: center;
599
+ justify-content: center;
600
+ font-size: 1rem;
601
+ }
602
+
603
+ .transaction-icon.send {
604
+ background: rgba(220, 38, 38, 0.1);
605
+ color: var(--error-color);
606
+ }
607
+
608
+ .transaction-icon.receive {
609
+ background: rgba(5, 150, 105, 0.1);
610
+ color: var(--success-color);
611
+ }
612
+
613
+ .transaction-icon.bill {
614
+ background: rgba(217, 119, 6, 0.1);
615
+ color: var(--warning-color);
616
+ }
617
+
618
+ .transaction-details h5 {
619
+ font-size: 1rem;
620
+ font-weight: 500;
621
+ margin-bottom: 0.25rem;
622
+ }
623
+
624
+ .transaction-details p {
625
+ color: var(--text-secondary);
626
+ font-size: 0.875rem;
627
+ }
628
+
629
+ .transaction-amount {
630
+ text-align: left;
631
+ }
632
+
633
+ .transaction-amount .amount {
634
+ font-size: 1rem;
635
+ font-weight: 600;
636
+ }
637
+
638
+ .transaction-amount.positive .amount {
639
+ color: var(--success-color);
640
+ }
641
+
642
+ .transaction-amount.negative .amount {
643
+ color: var(--error-color);
644
+ }
645
+
646
+ .transaction-amount .time {
647
+ font-size: 0.75rem;
648
+ color: var(--text-secondary);
649
+ }
650
+
651
+ /* شريط التنقل السفلي */
652
+ .bottom-nav {
653
+ position: fixed;
654
+ bottom: 0;
655
+ left: 0;
656
+ right: 0;
657
+ background: var(--surface);
658
+ border-top: 1px solid var(--border);
659
+ display: flex;
660
+ justify-content: space-around;
661
+ padding: 0.75rem 0;
662
+ z-index: 100;
663
+ }
664
+
665
+ .nav-item {
666
+ background: none;
667
+ border: none;
668
+ display: flex;
669
+ flex-direction: column;
670
+ align-items: center;
671
+ gap: 0.25rem;
672
+ cursor: pointer;
673
+ color: var(--text-secondary);
674
+ transition: var(--transition);
675
+ padding: 0.5rem;
676
+ border-radius: var(--border-radius);
677
+ }
678
+
679
+ .nav-item.active {
680
+ color: var(--primary-color);
681
+ }
682
+
683
+ .nav-item i {
684
+ font-size: 1.25rem;
685
+ }
686
+
687
+ .nav-item span {
688
+ font-size: 0.75rem;
689
+ font-weight: 500;
690
+ }
691
+
692
+ /* رؤوس الشاشات */
693
+ .screen-header {
694
+ background: var(--surface);
695
+ border-bottom: 1px solid var(--border);
696
+ padding: 1rem;
697
+ display: flex;
698
+ align-items: center;
699
+ gap: 1rem;
700
+ position: sticky;
701
+ top: 0;
702
+ z-index: 50;
703
+ }
704
+
705
+ .back-btn {
706
+ background: none;
707
+ border: none;
708
+ font-size: 1.25rem;
709
+ color: var(--text-primary);
710
+ cursor: pointer;
711
+ padding: 0.5rem;
712
+ border-radius: 50%;
713
+ transition: var(--transition);
714
+ }
715
+
716
+ .back-btn:hover {
717
+ background: var(--background);
718
+ }
719
+
720
+ .screen-header h2 {
721
+ font-size: 1.25rem;
722
+ font-weight: 600;
723
+ }
724
+
725
+ /* النوافذ المنبثقة */
726
+ .modal-overlay {
727
+ position: fixed;
728
+ top: 0;
729
+ left: 0;
730
+ width: 100%;
731
+ height: 100%;
732
+ background: rgba(0, 0, 0, 0.5);
733
+ display: none;
734
+ z-index: 1000;
735
+ backdrop-filter: blur(3px);
736
+ }
737
+
738
+ .modal-overlay.active {
739
+ display: flex;
740
+ align-items: center;
741
+ justify-content: center;
742
+ }
743
+
744
+ /* شاشة التحويل */
745
+ .transfer-content {
746
+ padding: 2rem 1rem 6rem;
747
+ max-width: 500px;
748
+ margin: 0 auto;
749
+ }
750
+
751
+ .transfer-steps {
752
+ margin-bottom: 2rem;
753
+ }
754
+
755
+ .step-indicator {
756
+ display: flex;
757
+ align-items: center;
758
+ justify-content: center;
759
+ margin-bottom: 1rem;
760
+ }
761
+
762
+ .step-indicator .step {
763
+ width: 40px;
764
+ height: 40px;
765
+ border-radius: 50%;
766
+ background: var(--border);
767
+ color: var(--text-secondary);
768
+ display: flex;
769
+ align-items: center;
770
+ justify-content: center;
771
+ font-weight: 600;
772
+ transition: var(--transition);
773
+ }
774
+
775
+ .step-indicator .step.active {
776
+ background: var(--primary-color);
777
+ color: white;
778
+ }
779
+
780
+ .step-indicator .step.completed {
781
+ background: var(--success-color);
782
+ color: white;
783
+ }
784
+
785
+ .step-line {
786
+ flex: 1;
787
+ height: 2px;
788
+ background: var(--border);
789
+ margin: 0 1rem;
790
+ }
791
+
792
+ .step-labels {
793
+ display: flex;
794
+ justify-content: space-between;
795
+ font-size: 0.875rem;
796
+ color: var(--text-secondary);
797
+ }
798
+
799
+ .transfer-step-content {
800
+ display: none;
801
+ animation: fadeInUp 0.5s ease;
802
+ }
803
+
804
+ .transfer-step-content.active {
805
+ display: block;
806
+ }
807
+
808
+ .transfer-step-content h3 {
809
+ font-size: 1.25rem;
810
+ font-weight: 600;
811
+ margin-bottom: 1.5rem;
812
+ text-align: center;
813
+ }
814
+
815
+ /* اختيار المحفظة */
816
+ .wallet-selection {
817
+ display: flex;
818
+ flex-direction: column;
819
+ gap: 1rem;
820
+ }
821
+
822
+ .wallet-option {
823
+ background: var(--surface);
824
+ border: 2px solid var(--border);
825
+ border-radius: var(--border-radius);
826
+ padding: 1rem;
827
+ display: flex;
828
+ align-items: center;
829
+ justify-content: space-between;
830
+ cursor: pointer;
831
+ transition: var(--transition);
832
+ }
833
+
834
+ .wallet-option:hover {
835
+ border-color: var(--primary-color);
836
+ transform: translateY(-2px);
837
+ box-shadow: var(--shadow);
838
+ }
839
+
840
+ .wallet-option.selected {
841
+ border-color: var(--primary-color);
842
+ background: rgba(37, 99, 235, 0.05);
843
+ }
844
+
845
+ .wallet-option-info {
846
+ display: flex;
847
+ align-items: center;
848
+ gap: 1rem;
849
+ }
850
+
851
+ .wallet-option-icon {
852
+ width: 50px;
853
+ height: 50px;
854
+ border-radius: var(--border-radius);
855
+ overflow: hidden;
856
+ border: 1px solid var(--border);
857
+ }
858
+
859
+ .wallet-option-icon img {
860
+ width: 100%;
861
+ height: 100%;
862
+ object-fit: cover;
863
+ }
864
+
865
+ .wallet-option-details h4 {
866
+ font-size: 1.1rem;
867
+ font-weight: 600;
868
+ margin-bottom: 0.25rem;
869
+ }
870
+
871
+ .wallet-option-details p {
872
+ color: var(--text-secondary);
873
+ font-size: 0.875rem;
874
+ }
875
+
876
+ .wallet-option-balance {
877
+ text-align: left;
878
+ }
879
+
880
+ .wallet-option-balance .amount {
881
+ font-size: 1.25rem;
882
+ font-weight: 700;
883
+ color: var(--success-color);
884
+ }
885
+
886
+ /* عناصر النموذج */
887
+ .form-control {
888
+ width: 100%;
889
+ padding: 0.75rem 1rem;
890
+ border: 1px solid var(--border);
891
+ border-radius: var(--border-radius);
892
+ font-family: inherit;
893
+ font-size: 1rem;
894
+ transition: var(--transition);
895
+ }
896
+
897
+ .form-control:focus {
898
+ outline: none;
899
+ border-color: var(--primary-color);
900
+ box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
901
+ }
902
+
903
+ /* اقتراحات المبلغ */
904
+ .amount-suggestions {
905
+ display: flex;
906
+ gap: 0.5rem;
907
+ margin-top: 0.5rem;
908
+ flex-wrap: wrap;
909
+ }
910
+
911
+ .amount-btn {
912
+ background: var(--surface);
913
+ border: 1px solid var(--border);
914
+ border-radius: 20px;
915
+ padding: 0.5rem 1rem;
916
+ font-size: 0.875rem;
917
+ cursor: pointer;
918
+ transition: var(--transition);
919
+ }
920
+
921
+ .amount-btn:hover {
922
+ background: var(--primary-color);
923
+ color: white;
924
+ border-color: var(--primary-color);
925
+ }
926
+
927
+ /* ملخص التحويل */
928
+ .transfer-summary {
929
+ background: var(--background);
930
+ border-radius: var(--border-radius);
931
+ padding: 1.5rem;
932
+ margin-bottom: 1.5rem;
933
+ }
934
+
935
+ .summary-item {
936
+ display: flex;
937
+ justify-content: space-between;
938
+ align-items: center;
939
+ padding: 0.75rem 0;
940
+ border-bottom: 1px solid var(--border);
941
+ }
942
+
943
+ .summary-item:last-child {
944
+ border-bottom: none;
945
+ }
946
+
947
+ .summary-item.total {
948
+ font-weight: 600;
949
+ font-size: 1.1rem;
950
+ color: var(--primary-color);
951
+ border-top: 2px solid var(--border);
952
+ margin-top: 0.5rem;
953
+ padding-top: 1rem;
954
+ }
955
+
956
+ /* أزرار التنقل */
957
+ .transfer-navigation {
958
+ display: flex;
959
+ gap: 1rem;
960
+ margin-top: 2rem;
961
+ }
962
+
963
+ .transfer-navigation button {
964
+ flex: 1;
965
+ }
966
+
967
+ .hidden {
968
+ display: none !important;
969
+ }
970
+
971
+ /* نظام الإشعارات والتنبيهات */
972
+ .toast-container {
973
+ position: fixed;
974
+ top: 20px;
975
+ left: 20px;
976
+ z-index: 9999;
977
+ display: flex;
978
+ flex-direction: column;
979
+ gap: 10px;
980
+ max-width: 400px;
981
+ width: 100%;
982
+ }
983
+
984
+ .toast {
985
+ background: var(--surface);
986
+ border-radius: var(--border-radius);
987
+ box-shadow: var(--shadow-lg);
988
+ display: flex;
989
+ align-items: center;
990
+ gap: 1rem;
991
+ padding: 1rem;
992
+ transform: translateX(-100%);
993
+ transition: var(--transition);
994
+ border-right: 4px solid var(--primary-color);
995
+ }
996
+
997
+ .toast.toast-show {
998
+ transform: translateX(0);
999
+ }
1000
+
1001
+ .toast.toast-hide {
1002
+ transform: translateX(-100%);
1003
+ opacity: 0;
1004
+ }
1005
+
1006
+ .toast.toast-success {
1007
+ border-right-color: var(--success-color);
1008
+ }
1009
+
1010
+ .toast.toast-error {
1011
+ border-right-color: var(--error-color);
1012
+ }
1013
+
1014
+ .toast.toast-warning {
1015
+ border-right-color: var(--warning-color);
1016
+ }
1017
+
1018
+ .toast-icon {
1019
+ font-size: 1.5rem;
1020
+ color: var(--primary-color);
1021
+ }
1022
+
1023
+ .toast.toast-success .toast-icon {
1024
+ color: var(--success-color);
1025
+ }
1026
+
1027
+ .toast.toast-error .toast-icon {
1028
+ color: var(--error-color);
1029
+ }
1030
+
1031
+ .toast.toast-warning .toast-icon {
1032
+ color: var(--warning-color);
1033
+ }
1034
+
1035
+ .toast-content {
1036
+ flex: 1;
1037
+ }
1038
+
1039
+ .toast-message {
1040
+ font-weight: 500;
1041
+ line-height: 1.4;
1042
+ }
1043
+
1044
+ .toast-close {
1045
+ background: none;
1046
+ border: none;
1047
+ color: var(--text-secondary);
1048
+ cursor: pointer;
1049
+ padding: 0.25rem;
1050
+ border-radius: 50%;
1051
+ transition: var(--transition);
1052
+ }
1053
+
1054
+ .toast-close:hover {
1055
+ background: var(--background);
1056
+ color: var(--text-primary);
1057
+ }
1058
+
1059
+ /* المودال */
1060
+ .modal-container {
1061
+ position: fixed;
1062
+ top: 0;
1063
+ left: 0;
1064
+ width: 100%;
1065
+ height: 100%;
1066
+ z-index: 9998;
1067
+ display: none;
1068
+ align-items: center;
1069
+ justify-content: center;
1070
+ padding: 1rem;
1071
+ }
1072
+
1073
+ .modal-overlay {
1074
+ position: absolute;
1075
+ top: 0;
1076
+ left: 0;
1077
+ width: 100%;
1078
+ height: 100%;
1079
+ background: rgba(0, 0, 0, 0.5);
1080
+ backdrop-filter: blur(3px);
1081
+ -webkit-backdrop-filter: blur(3px);
1082
+ }
1083
+
1084
+ .modal-content {
1085
+ background: var(--surface);
1086
+ border-radius: var(--border-radius);
1087
+ box-shadow: var(--shadow-lg);
1088
+ max-width: 500px;
1089
+ width: 100%;
1090
+ max-height: 80vh;
1091
+ overflow-y: auto;
1092
+ position: relative;
1093
+ z-index: 1;
1094
+ animation: modalSlideIn 0.3s ease;
1095
+ }
1096
+
1097
+ @keyframes modalSlideIn {
1098
+ from {
1099
+ opacity: 0;
1100
+ transform: scale(0.9) translateY(-20px);
1101
+ }
1102
+ to {
1103
+ opacity: 1;
1104
+ transform: scale(1) translateY(0);
1105
+ }
1106
+ }
1107
+
1108
+ .modal-header {
1109
+ display: flex;
1110
+ justify-content: space-between;
1111
+ align-items: center;
1112
+ padding: 1.5rem;
1113
+ border-bottom: 1px solid var(--border);
1114
+ }
1115
+
1116
+ .modal-title {
1117
+ font-size: 1.25rem;
1118
+ font-weight: 600;
1119
+ margin: 0;
1120
+ }
1121
+
1122
+ .modal-close {
1123
+ background: none;
1124
+ border: none;
1125
+ font-size: 1.25rem;
1126
+ color: var(--text-secondary);
1127
+ cursor: pointer;
1128
+ padding: 0.5rem;
1129
+ border-radius: 50%;
1130
+ transition: var(--transition);
1131
+ }
1132
+
1133
+ .modal-close:hover {
1134
+ background: var(--background);
1135
+ color: var(--text-primary);
1136
+ }
1137
+
1138
+ .modal-body {
1139
+ padding: 1.5rem;
1140
+ }
1141
+
1142
+ .modal-footer {
1143
+ padding: 1rem 1.5rem;
1144
+ border-top: 1px solid var(--border);
1145
+ display: flex;
1146
+ gap: 1rem;
1147
+ justify-content: flex-end;
1148
+ }
1149
+
1150
+ .modal-footer .btn {
1151
+ min-width: 100px;
1152
+ }
1153
+
1154
+ /* مودال التحميل */
1155
+ .loading-modal .modal-content {
1156
+ max-width: 300px;
1157
+ text-align: center;
1158
+ }
1159
+
1160
+ .loading-content {
1161
+ padding: 2rem;
1162
+ }
1163
+
1164
+ .loading-content .loading-spinner {
1165
+ width: 50px;
1166
+ height: 50px;
1167
+ border: 4px solid var(--border);
1168
+ border-top: 4px solid var(--primary-color);
1169
+ border-radius: 50%;
1170
+ animation: spin 1s linear infinite;
1171
+ margin: 0 auto 1rem;
1172
+ }
1173
+
1174
+ .loading-content p {
1175
+ color: var(--text-secondary);
1176
+ margin: 0;
1177
+ }
1178
+
1179
+ /* قائمة الإشعارات */
1180
+ .notifications-header {
1181
+ display: flex;
1182
+ justify-content: space-between;
1183
+ align-items: center;
1184
+ margin-bottom: 1rem;
1185
+ }
1186
+
1187
+ .notifications-list {
1188
+ max-height: 400px;
1189
+ overflow-y: auto;
1190
+ }
1191
+
1192
+ .notification-item {
1193
+ display: flex;
1194
+ align-items: flex-start;
1195
+ gap: 1rem;
1196
+ padding: 1rem;
1197
+ border-bottom: 1px solid var(--border);
1198
+ transition: var(--transition);
1199
+ }
1200
+
1201
+ .notification-item:hover {
1202
+ background: var(--background);
1203
+ }
1204
+
1205
+ .notification-item.unread {
1206
+ background: rgba(37, 99, 235, 0.05);
1207
+ border-right: 3px solid var(--primary-color);
1208
+ }
1209
+
1210
+ .notification-icon {
1211
+ width: 40px;
1212
+ height: 40px;
1213
+ border-radius: 50%;
1214
+ display: flex;
1215
+ align-items: center;
1216
+ justify-content: center;
1217
+ font-size: 1rem;
1218
+ flex-shrink: 0;
1219
+ }
1220
+
1221
+ .notification-icon.transaction {
1222
+ background: rgba(37, 99, 235, 0.1);
1223
+ color: var(--primary-color);
1224
+ }
1225
+
1226
+ .notification-icon.security {
1227
+ background: rgba(220, 38, 38, 0.1);
1228
+ color: var(--error-color);
1229
+ }
1230
+
1231
+ .notification-icon.system {
1232
+ background: rgba(107, 114, 128, 0.1);
1233
+ color: var(--text-secondary);
1234
+ }
1235
+
1236
+ .notification-content {
1237
+ flex: 1;
1238
+ }
1239
+
1240
+ .notification-content h4 {
1241
+ font-size: 1rem;
1242
+ font-weight: 600;
1243
+ margin: 0 0 0.25rem 0;
1244
+ }
1245
+
1246
+ .notification-content p {
1247
+ color: var(--text-secondary);
1248
+ margin: 0 0 0.5rem 0;
1249
+ line-height: 1.4;
1250
+ }
1251
+
1252
+ .notification-time {
1253
+ font-size: 0.875rem;
1254
+ color: var(--text-secondary);
1255
+ }
1256
+
1257
+ .notification-actions {
1258
+ display: flex;
1259
+ gap: 0.5rem;
1260
+ flex-shrink: 0;
1261
+ }
1262
+
1263
+ .notification-actions button {
1264
+ background: none;
1265
+ border: none;
1266
+ color: var(--text-secondary);
1267
+ cursor: pointer;
1268
+ padding: 0.5rem;
1269
+ border-radius: 50%;
1270
+ transition: var(--transition);
1271
+ }
1272
+
1273
+ .notification-actions button:hover {
1274
+ background: var(--background);
1275
+ color: var(--text-primary);
1276
+ }
1277
+
1278
+ .no-notifications {
1279
+ text-align: center;
1280
+ color: var(--text-secondary);
1281
+ padding: 2rem;
1282
+ font-style: italic;
1283
+ }
1284
+
1285
+ /* الاستجابة للشاشات الصغيرة */
1286
+ @media (max-width: 768px) {
1287
+ .login-container {
1288
+ padding: 1rem;
1289
+ }
1290
+
1291
+ .wallet-logos {
1292
+ grid-template-columns: repeat(2, 1fr);
1293
+ }
1294
+
1295
+ .actions-grid {
1296
+ grid-template-columns: repeat(2, 1fr);
1297
+ }
1298
+
1299
+ .main-header {
1300
+ padding: 1.5rem 1rem;
1301
+ }
1302
+
1303
+ .balance-amount {
1304
+ font-size: 2rem;
1305
+ }
1306
+
1307
+ .wallet-card {
1308
+ padding: 1rem;
1309
+ }
1310
+
1311
+ .transaction-item {
1312
+ padding: 0.75rem;
1313
+ }
1314
+
1315
+ .transfer-content {
1316
+ padding: 1rem 1rem 6rem;
1317
+ }
1318
+
1319
+ .step-labels {
1320
+ font-size: 0.75rem;
1321
+ }
1322
+
1323
+ .wallet-option {
1324
+ padding: 0.75rem;
1325
+ }
1326
+
1327
+ .amount-suggestions {
1328
+ justify-content: center;
1329
+ }
1330
+
1331
+ .transfer-navigation {
1332
+ flex-direction: column;
1333
+ }
1334
+ }
tsconfig.app.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./out-tsc/app",
5
+ "types": []
6
+ },
7
+ "files": [
8
+ "src/main.ts"
9
+ ],
10
+ "include": [
11
+ "src/**/*.d.ts"
12
+ ]
13
+ }
tsconfig.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compileOnSave": false,
3
+ "compilerOptions": {
4
+ "baseUrl": "./",
5
+ "outDir": "./dist/out-tsc",
6
+ "forceConsistentCasingInFileNames": true,
7
+ "strict": true,
8
+ "noImplicitOverride": true,
9
+ "noPropertyAccessFromIndexSignature": true,
10
+ "noImplicitReturns": true,
11
+ "noFallthroughCasesInSwitch": true,
12
+ "sourceMap": true,
13
+ "declaration": false,
14
+ "downlevelIteration": true,
15
+ "experimentalDecorators": true,
16
+ "moduleResolution": "node",
17
+ "importHelpers": true,
18
+ "target": "ES2022",
19
+ "module": "ES2022",
20
+ "useDefineForClassFields": false,
21
+ "lib": [
22
+ "ES2022",
23
+ "dom"
24
+ ]
25
+ },
26
+ "angularCompilerOptions": {
27
+ "enableI18nLegacyMessageIdFormat": false,
28
+ "strictInjectionParameters": true,
29
+ "strictInputAccessModifiers": true,
30
+ "strictTemplates": true
31
+ }
32
+ }
wallets.js ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // إدارة المحافظ الإلكترونية
2
+ class WalletManager {
3
+ constructor() {
4
+ this.supportedWallets = {
5
+ jawali: {
6
+ id: 'jawali',
7
+ name: 'جوالي',
8
+ nameEn: 'Jawali',
9
+ provider: 'WeCash YE',
10
+ packageId: 'com.ama.wecashmobileapp',
11
+ icon: 'https://play-lh.googleusercontent.com/NuKV_Snecpx633RHzIWvFauG32WBAk-jt3lcZOajw2w7VD8Hdt8h5Lb0pYLopB_Qk4Y=w240-h480',
12
+ color: '#4361ee',
13
+ features: ['transfer', 'bills', 'recharge', 'qr'],
14
+ supportedCurrencies: ['YER', 'SAR', 'USD'],
15
+ maxTransfer: 3000000,
16
+ fees: {
17
+ transfer: 20,
18
+ billPayment: 15,
19
+ recharge: 10
20
+ }
21
+ },
22
+ onecash: {
23
+ id: 'onecash',
24
+ name: 'ONE Cash',
25
+ nameEn: 'ONE Cash',
26
+ provider: 'ONECASHYE',
27
+ packageId: 'com.one.onecustomer',
28
+ icon: 'https://play-lh.googleusercontent.com/OF2xMRUmNH47BIaOTbv7GgvmLRTQbT1xHkFF_Ocswx6Jq5gfX4VlfAl_275UmjH2pg=w240-h480',
29
+ color: '#059669',
30
+ features: ['transfer', 'bills', 'recharge', 'qr', 'international'],
31
+ supportedCurrencies: ['YER', 'SAR', 'USD'],
32
+ maxTransfer: 3000000,
33
+ fees: {
34
+ transfer: 0, // مجاني للمستخدمين
35
+ billPayment: 10,
36
+ recharge: 5
37
+ }
38
+ },
39
+ cash: {
40
+ id: 'cash',
41
+ name: 'Cash',
42
+ nameEn: 'Cash',
43
+ provider: 'Tamkeen Financial',
44
+ packageId: 'com.tamkeen.sms',
45
+ icon: 'https://play-lh.googleusercontent.com/zkV8HeO6iF2xa77ObHdKfAXfrfjU5fgWB0XsWt7_DmG4VGSKob2jU_CrqWyKQtghQyE=w240-h480',
46
+ color: '#dc2626',
47
+ features: ['transfer', 'bills', 'recharge', 'qr', 'offline'],
48
+ supportedCurrencies: ['YER'],
49
+ maxTransfer: 2000000,
50
+ fees: {
51
+ transfer: 25,
52
+ billPayment: 20,
53
+ recharge: 15
54
+ }
55
+ },
56
+ jaib: {
57
+ id: 'jaib',
58
+ name: 'Jaib',
59
+ nameEn: 'Jaib Digital Wallet',
60
+ provider: 'AHD Financial',
61
+ packageId: 'com.ahd.jaib',
62
+ icon: 'https://play-lh.googleusercontent.com/EAaXnjh1FVPYpI5qWZwWvZIV5oD1hm9auDX0owOgREBjMAzYKX9od1USWRzlXIhRvKMx=w240-h480',
63
+ color: '#7c3aed',
64
+ features: ['transfer', 'bills', 'recharge', 'qr', 'entertainment'],
65
+ supportedCurrencies: ['YER'],
66
+ maxTransfer: 1500000,
67
+ fees: {
68
+ transfer: 15,
69
+ billPayment: 12,
70
+ recharge: 8
71
+ }
72
+ },
73
+ mfloos: {
74
+ id: 'mfloos',
75
+ name: 'mFloos',
76
+ nameEn: 'mFloos - Customers',
77
+ provider: 'Alkuraimi Islamic Microfinance Bank',
78
+ packageId: 'wallet.mfloos.com.mflooswallet.customer',
79
+ icon: 'https://play-lh.googleusercontent.com/mNvakjEk-3VX7icU5w4xmAhT4MQgGAGcQYpRvPkBLVTzD-sYnmzAH_wuglMujTsaqQ=w240-h480',
80
+ color: '#0891b2',
81
+ features: ['transfer', 'bills', 'recharge', 'banking'],
82
+ supportedCurrencies: ['YER'],
83
+ maxTransfer: 1000000,
84
+ fees: {
85
+ transfer: 10,
86
+ billPayment: 8,
87
+ recharge: 5
88
+ }
89
+ },
90
+ mobilemoney: {
91
+ id: 'mobilemoney',
92
+ name: 'Mobile Money',
93
+ nameEn: 'Mobile Money Wallet',
94
+ provider: 'CAC Bank',
95
+ packageId: 'cac.mobilemoney.app',
96
+ icon: 'https://play-lh.googleusercontent.com/51r7PLMlK0gVvITgOoJ7BnGX-9Gq3_ayiSiHHxSDbJZPCgABXI_LnU6jNCHAefWHvSPV=w240-h480',
97
+ color: '#ea580c',
98
+ features: ['transfer', 'bills', 'recharge', 'atm'],
99
+ supportedCurrencies: ['YER'],
100
+ maxTransfer: 2500000,
101
+ fees: {
102
+ transfer: 18,
103
+ billPayment: 15,
104
+ recharge: 12
105
+ }
106
+ }
107
+ };
108
+
109
+ this.userWallets = [];
110
+ this.init();
111
+ }
112
+
113
+ // تهيئة مدير المحافظ
114
+ init() {
115
+ this.loadUserWallets();
116
+ }
117
+
118
+ // تحميل محافظ المستخدم
119
+ loadUserWallets() {
120
+ const savedWallets = localStorage.getItem('unifiedWallet_userWallets');
121
+ if (savedWallets) {
122
+ this.userWallets = JSON.parse(savedWallets);
123
+ }
124
+ }
125
+
126
+ // حفظ محافظ المستخدم
127
+ saveUserWallets() {
128
+ localStorage.setItem('unifiedWallet_userWallets', JSON.stringify(this.userWallets));
129
+ }
130
+
131
+ // إضافة محفظة جديدة
132
+ async addWallet(walletId, accountNumber, pin) {
133
+ const walletInfo = this.supportedWallets[walletId];
134
+ if (!walletInfo) {
135
+ throw new Error('محفظة غير مدعومة');
136
+ }
137
+
138
+ // التحقق من صحة البيانات
139
+ if (!this.validateAccountNumber(accountNumber)) {
140
+ throw new Error('رقم الحساب غير صحيح');
141
+ }
142
+
143
+ if (!this.validatePin(pin)) {
144
+ throw new Error('رمز PIN غير صحيح');
145
+ }
146
+
147
+ // التحقق من عدم وجود المحفظة مسبقاً
148
+ const existingWallet = this.userWallets.find(w => w.id === walletId);
149
+ if (existingWallet) {
150
+ throw new Error('هذه المحفظة مضافة مسبقاً');
151
+ }
152
+
153
+ // محاكاة التحقق من المحفظة
154
+ await this.verifyWalletCredentials(walletId, accountNumber, pin);
155
+
156
+ // إضافة المحفظة
157
+ const newWallet = {
158
+ id: walletId,
159
+ accountNumber: accountNumber,
160
+ pin: this.encryptPin(pin),
161
+ balance: await this.fetchWalletBalance(walletId, accountNumber),
162
+ status: 'active',
163
+ addedAt: new Date().toISOString(),
164
+ lastSync: new Date().toISOString()
165
+ };
166
+
167
+ this.userWallets.push(newWallet);
168
+ this.saveUserWallets();
169
+
170
+ return newWallet;
171
+ }
172
+
173
+ // إزالة محفظة
174
+ removeWallet(walletId) {
175
+ const index = this.userWallets.findIndex(w => w.id === walletId);
176
+ if (index === -1) {
177
+ throw new Error('المحفظة غير موجودة');
178
+ }
179
+
180
+ this.userWallets.splice(index, 1);
181
+ this.saveUserWallets();
182
+ }
183
+
184
+ // تحديث رصيد محفظة
185
+ async updateWalletBalance(walletId) {
186
+ const wallet = this.userWallets.find(w => w.id === walletId);
187
+ if (!wallet) {
188
+ throw new Error('المحفظة غير موجودة');
189
+ }
190
+
191
+ const newBalance = await this.fetchWalletBalance(walletId, wallet.accountNumber);
192
+ wallet.balance = newBalance;
193
+ wallet.lastSync = new Date().toISOString();
194
+
195
+ this.saveUserWallets();
196
+ return newBalance;
197
+ }
198
+
199
+ // تحديث جميع الأرصدة
200
+ async updateAllBalances() {
201
+ const updatePromises = this.userWallets.map(wallet =>
202
+ this.updateWalletBalance(wallet.id)
203
+ );
204
+
205
+ await Promise.all(updatePromises);
206
+ }
207
+
208
+ // تنفيذ تحويل
209
+ async executeTransfer(fromWalletId, toWalletId, amount, recipientNumber, pin) {
210
+ const fromWallet = this.userWallets.find(w => w.id === fromWalletId);
211
+ if (!fromWallet) {
212
+ throw new Error('محفظة المرسل غير موجودة');
213
+ }
214
+
215
+ const fromWalletInfo = this.supportedWallets[fromWalletId];
216
+ const toWalletInfo = this.supportedWallets[toWalletId];
217
+
218
+ // التحقق من الرصيد
219
+ const fee = fromWalletInfo.fees.transfer;
220
+ const totalAmount = amount + fee;
221
+
222
+ if (fromWallet.balance < totalAmount) {
223
+ throw new Error('الرصيد غير كافي');
224
+ }
225
+
226
+ // التحقق من الحد الأقصى للتحويل
227
+ if (amount > fromWalletInfo.maxTransfer) {
228
+ throw new Error(`الحد الأقصى للتحويل هو ${fromWalletInfo.maxTransfer.toLocaleString()} ر.ي`);
229
+ }
230
+
231
+ // التحقق من رمز PIN
232
+ if (!this.verifyPin(pin, fromWallet.pin)) {
233
+ throw new Error('رمز PIN غير صحيح');
234
+ }
235
+
236
+ // تنفيذ التحويل
237
+ await this.processTransfer({
238
+ fromWallet: fromWalletId,
239
+ toWallet: toWalletId,
240
+ amount: amount,
241
+ fee: fee,
242
+ recipientNumber: recipientNumber,
243
+ timestamp: new Date().toISOString()
244
+ });
245
+
246
+ // تحديث الرصيد
247
+ fromWallet.balance -= totalAmount;
248
+ this.saveUserWallets();
249
+
250
+ return {
251
+ success: true,
252
+ transactionId: this.generateTransactionId(),
253
+ amount: amount,
254
+ fee: fee,
255
+ total: totalAmount,
256
+ newBalance: fromWallet.balance
257
+ };
258
+ }
259
+
260
+ // دفع فاتورة
261
+ async payBill(walletId, billType, billNumber, amount, pin) {
262
+ const wallet = this.userWallets.find(w => w.id === walletId);
263
+ if (!wallet) {
264
+ throw new Error('المحفظة غير موجودة');
265
+ }
266
+
267
+ const walletInfo = this.supportedWallets[walletId];
268
+ const fee = walletInfo.fees.billPayment;
269
+ const totalAmount = amount + fee;
270
+
271
+ if (wallet.balance < totalAmount) {
272
+ throw new Error('الرصيد غير كافي');
273
+ }
274
+
275
+ if (!this.verifyPin(pin, wallet.pin)) {
276
+ throw new Error('رمز PIN غير صحيح');
277
+ }
278
+
279
+ // تنفيذ دفع الفاتورة
280
+ await this.processBillPayment({
281
+ wallet: walletId,
282
+ billType: billType,
283
+ billNumber: billNumber,
284
+ amount: amount,
285
+ fee: fee,
286
+ timestamp: new Date().toISOString()
287
+ });
288
+
289
+ wallet.balance -= totalAmount;
290
+ this.saveUserWallets();
291
+
292
+ return {
293
+ success: true,
294
+ transactionId: this.generateTransactionId(),
295
+ amount: amount,
296
+ fee: fee,
297
+ total: totalAmount,
298
+ newBalance: wallet.balance
299
+ };
300
+ }
301
+
302
+ // شحن رصيد
303
+ async rechargeBalance(walletId, phoneNumber, amount, pin) {
304
+ const wallet = this.userWallets.find(w => w.id === walletId);
305
+ if (!wallet) {
306
+ throw new Error('المحفظة غير موجودة');
307
+ }
308
+
309
+ const walletInfo = this.supportedWallets[walletId];
310
+ const fee = walletInfo.fees.recharge;
311
+ const totalAmount = amount + fee;
312
+
313
+ if (wallet.balance < totalAmount) {
314
+ throw new Error('الرصيد غير كافي');
315
+ }
316
+
317
+ if (!this.verifyPin(pin, wallet.pin)) {
318
+ throw new Error('رمز PIN غير صحيح');
319
+ }
320
+
321
+ // تنفيذ شحن الرصيد
322
+ await this.processRecharge({
323
+ wallet: walletId,
324
+ phoneNumber: phoneNumber,
325
+ amount: amount,
326
+ fee: fee,
327
+ timestamp: new Date().toISOString()
328
+ });
329
+
330
+ wallet.balance -= totalAmount;
331
+ this.saveUserWallets();
332
+
333
+ return {
334
+ success: true,
335
+ transactionId: this.generateTransactionId(),
336
+ amount: amount,
337
+ fee: fee,
338
+ total: totalAmount,
339
+ newBalance: wallet.balance
340
+ };
341
+ }
342
+
343
+ // الحصول على معلومات محفظة
344
+ getWalletInfo(walletId) {
345
+ return this.supportedWallets[walletId];
346
+ }
347
+
348
+ // الحصول على محافظ المستخدم
349
+ getUserWallets() {
350
+ return this.userWallets.map(userWallet => {
351
+ const walletInfo = this.supportedWallets[userWallet.id];
352
+ return {
353
+ ...walletInfo,
354
+ ...userWallet,
355
+ accountNumber: userWallet.accountNumber
356
+ };
357
+ });
358
+ }
359
+
360
+ // التحقق من صحة رقم الحساب
361
+ validateAccountNumber(accountNumber) {
362
+ return /^[0-9]{9}$/.test(accountNumber);
363
+ }
364
+
365
+ // التحقق من صحة رمز PIN
366
+ validatePin(pin) {
367
+ return /^[0-9]{4,6}$/.test(pin);
368
+ }
369
+
370
+ // تشفير رمز PIN
371
+ encryptPin(pin) {
372
+ // تشفير بسيط للتجربة - في الإنتاج يجب استخدام تشفير قوي
373
+ return btoa(pin);
374
+ }
375
+
376
+ // فك تشفير رمز PIN
377
+ decryptPin(encryptedPin) {
378
+ return atob(encryptedPin);
379
+ }
380
+
381
+ // التحقق من رمز PIN
382
+ verifyPin(pin, encryptedPin) {
383
+ return pin === this.decryptPin(encryptedPin);
384
+ }
385
+
386
+ // توليد معرف معاملة
387
+ generateTransactionId() {
388
+ return 'TXN' + Date.now() + Math.random().toString(36).substr(2, 5).toUpperCase();
389
+ }
390
+
391
+ // محاكاة التحقق من بيانات المحفظة
392
+ async verifyWalletCredentials(walletId, accountNumber, pin) {
393
+ // محاكاة استدعاء API للتحقق
394
+ await new Promise(resolve => setTimeout(resolve, 1500));
395
+
396
+ // في التطبيق الحقيقي، سيتم التحقق من البيانات مع خوادم المحفظة
397
+ return true;
398
+ }
399
+
400
+ // محاكاة جلب رصيد المحفظة
401
+ async fetchWalletBalance(walletId, accountNumber) {
402
+ // محاكاة استدعاء API لجلب الرصيد
403
+ await new Promise(resolve => setTimeout(resolve, 1000));
404
+
405
+ // إرجاع رصيد عشوائي للتجربة
406
+ return Math.floor(Math.random() * 50000) + 1000;
407
+ }
408
+
409
+ // محاكاة تنفيذ التحويل
410
+ async processTransfer(transferData) {
411
+ await new Promise(resolve => setTimeout(resolve, 2000));
412
+ // في التطبيق الحقيقي، سيتم إرسال البيانات لخوادم المحفظة
413
+ console.log('تم تنفيذ التحويل:', transferData);
414
+ }
415
+
416
+ // محاكاة دفع الفاتورة
417
+ async processBillPayment(billData) {
418
+ await new Promise(resolve => setTimeout(resolve, 1500));
419
+ console.log('تم دفع الفاتورة:', billData);
420
+ }
421
+
422
+ // محاكاة شحن الرصيد
423
+ async processRecharge(rechargeData) {
424
+ await new Promise(resolve => setTimeout(resolve, 1000));
425
+ console.log('تم شحن الرصيد:', rechargeData);
426
+ }
427
+ }
428
+
429
+ // تصدير الكلاس للاستخدام في التطبيق الرئيسي
430
+ window.WalletManager = WalletManager;
الاخير.html ADDED
@@ -0,0 +1,618 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>نظام الدفع متعدد المحافظ</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap" rel="stylesheet">
8
+ <style>
9
+ :root {
10
+ --primary: #4361ee;
11
+ --secondary: #3f37c9;
12
+ --success: #2e7d32;
13
+ --warning: #e63946;
14
+ --light: #f8f9fa;
15
+ --dark: #212529;
16
+ --gray: #6c757d;
17
+ --border: #dee2e6;
18
+ --shadow: 0 4px 6px rgba(0,0,0,0.1);
19
+ }
20
+
21
+ body {
22
+ font-family: 'Tajawal', sans-serif;
23
+ background: #f5f7fa;
24
+ padding: 20px;
25
+ color: var(--dark);
26
+ line-height: 1.6;
27
+ }
28
+
29
+ .container {
30
+ max-width: 500px;
31
+ margin: 0 auto;
32
+ background: white;
33
+ padding: 25px;
34
+ border-radius: 12px;
35
+ box-shadow: var(--shadow);
36
+ transition: all 0.3s ease;
37
+ }
38
+
39
+ h1 {
40
+ color: var(--primary);
41
+ text-align: center;
42
+ margin-bottom: 25px;
43
+ font-weight: 700;
44
+ font-size: 1.8rem;
45
+ }
46
+
47
+ .form-group {
48
+ margin-bottom: 20px;
49
+ animation: fadeIn 0.5s ease;
50
+ }
51
+
52
+ @keyframes fadeIn {
53
+ from { opacity: 0; transform: translateY(10px); }
54
+ to { opacity: 1; transform: translateY(0); }
55
+ }
56
+
57
+ label {
58
+ display: block;
59
+ margin-bottom: 8px;
60
+ font-weight: 500;
61
+ color: var(--dark);
62
+ font-size: 1rem;
63
+ }
64
+
65
+ select, input, button {
66
+ width: 100%;
67
+ padding: 12px 15px;
68
+ border: 1px solid var(--border);
69
+ border-radius: 8px;
70
+ font-family: 'Tajawal', sans-serif;
71
+ font-size: 1rem;
72
+ transition: all 0.3s;
73
+ box-sizing: border-box;
74
+ }
75
+
76
+ select:focus, input:focus {
77
+ outline: none;
78
+ border-color: var(--primary);
79
+ box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
80
+ }
81
+
82
+ button {
83
+ background: var(--primary);
84
+ color: white;
85
+ border: none;
86
+ cursor: pointer;
87
+ font-weight: 500;
88
+ margin-top: 10px;
89
+ }
90
+
91
+ button:hover {
92
+ background: var(--secondary);
93
+ transform: translateY(-2px);
94
+ box-shadow: var(--shadow);
95
+ }
96
+
97
+ button:active {
98
+ transform: translateY(0);
99
+ }
100
+
101
+ .small-btn {
102
+ padding: 8px 12px;
103
+ font-size: 0.9rem;
104
+ margin: 5px;
105
+ display: inline-block;
106
+ width: auto;
107
+ }
108
+
109
+ #verification-section, #result, #service-field, #amount-field, #execute-btn {
110
+ display: none;
111
+ }
112
+
113
+ hr {
114
+ margin: 20px 0;
115
+ border: none;
116
+ border-top: 1px solid var(--border);
117
+ }
118
+
119
+ #overlay {
120
+ display: none;
121
+ position: fixed;
122
+ top: 0;
123
+ left: 0;
124
+ width: 100%;
125
+ height: 100%;
126
+ background: rgba(0,0,0,0.5);
127
+ z-index: 999;
128
+ backdrop-filter: blur(3px);
129
+ }
130
+
131
+ #result {
132
+ display: none;
133
+ position: fixed;
134
+ top: 50%;
135
+ left: 50%;
136
+ transform: translate(-50%, -50%);
137
+ width: 90%;
138
+ max-width: 400px;
139
+ background: white;
140
+ padding: 25px;
141
+ border-radius: 12px;
142
+ box-shadow: 0 5px 15px rgba(0,0,0,0.3);
143
+ z-index: 1000;
144
+ animation: popIn 0.4s ease;
145
+ }
146
+
147
+ @keyframes popIn {
148
+ 0% { transform: translate(-50%, -50%) scale(0.8); opacity: 0; }
149
+ 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
150
+ }
151
+
152
+ #result h2 {
153
+ color: var(--success);
154
+ font-size: 1.5rem;
155
+ text-align: center;
156
+ margin-top: 0;
157
+ margin-bottom: 20px;
158
+ }
159
+
160
+ .close-btn {
161
+ background: var(--success);
162
+ padding: 10px 15px;
163
+ float: right;
164
+ }
165
+
166
+ .transaction-detail {
167
+ margin-bottom: 10px;
168
+ font-size: 1rem;
169
+ }
170
+
171
+ .transaction-detail strong {
172
+ color: var(--dark);
173
+ font-weight: 500;
174
+ }
175
+
176
+ .balance-display {
177
+ margin-top: 15px;
178
+ padding-top: 15px;
179
+ border-top: 1px dashed var(--border);
180
+ font-weight: bold;
181
+ }
182
+
183
+ .low-balance {
184
+ color: var(--warning);
185
+ }
186
+
187
+ .normal-balance {
188
+ color: var(--success);
189
+ }
190
+
191
+ .qr-container {
192
+ text-align: center;
193
+ margin: 15px 0;
194
+ }
195
+
196
+ .progress-steps {
197
+ display: flex;
198
+ justify-content: space-between;
199
+ margin-bottom: 20px;
200
+ position: relative;
201
+ }
202
+
203
+ .progress-steps::before {
204
+ content: '';
205
+ position: absolute;
206
+ top: 15px;
207
+ left: 0;
208
+ right: 0;
209
+ height: 2px;
210
+ background: var(--border);
211
+ z-index: 1;
212
+ }
213
+
214
+ .step {
215
+ position: relative;
216
+ z-index: 2;
217
+ text-align: center;
218
+ width: 30px;
219
+ height: 30px;
220
+ line-height: 30px;
221
+ border-radius: 50%;
222
+ background: var(--border);
223
+ color: var(--gray);
224
+ font-weight: bold;
225
+ }
226
+
227
+ .step.active {
228
+ background: var(--primary);
229
+ color: white;
230
+ }
231
+
232
+ .step.completed {
233
+ background: var(--success);
234
+ color: white;
235
+ }
236
+
237
+ .step-label {
238
+ display: block;
239
+ margin-top: 5px;
240
+ font-size: 0.8rem;
241
+ color: var(--gray);
242
+ }
243
+
244
+ .verification-option {
245
+ margin-bottom: 20px;
246
+ padding: 15px;
247
+ border-radius: 8px;
248
+ background: var(--light);
249
+ animation: fadeIn 0.5s ease;
250
+ }
251
+
252
+ .verification-option h3 {
253
+ margin-top: 0;
254
+ color: var(--dark);
255
+ font-size: 1rem;
256
+ }
257
+
258
+ .custom-select {
259
+ position: relative;
260
+ }
261
+
262
+ .custom-select select {
263
+ appearance: none;
264
+ -webkit-appearance: none;
265
+ -moz-appearance: none;
266
+ background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
267
+ background-repeat: no-repeat;
268
+ background-position: right 10px center;
269
+ background-size: 15px;
270
+ padding-right: 35px;
271
+ }
272
+ </style>
273
+ </head>
274
+ <body>
275
+ <div id="overlay"></div>
276
+ <div class="container">
277
+ <h1>نظام الدفع متعدد المحافظ</h1>
278
+
279
+ <div class="progress-steps">
280
+ <div class="step active" id="step1">1</div>
281
+ <div class="step" id="step2">2</div>
282
+ <div class="step" id="step3">3</div>
283
+ </div>
284
+
285
+ <div class="form-group custom-select">
286
+ <label>من محفظتي:</label>
287
+ <select id="from-wallet">
288
+ <option value="jawali">جوالي (1000 ر.ي)</option>
289
+ <option value="kash">كاش (500 ر.ي)</option>
290
+ <option value="moneymobile">موبايل موني (0 ر.ي)</option>
291
+ <option value="jeep">جيب (0 ر.ي)</option>
292
+ <option value="shaamil">شامل (0 ر.ي)</option>
293
+ <option value="yemenpay">يمن والت (0 ر.ي)</option>
294
+ </select>
295
+ </div>
296
+
297
+ <div class="form-group custom-select">
298
+ <label>إلى محفظة:</label>
299
+ <select id="to-wallet">
300
+ <option value="">-- اختر المحفظة المستقبلة --</option>
301
+ <option value="jawali">جوالي</option>
302
+ <option value="kash">كاش</option>
303
+ <option value="moneymobile">موبايل موني</option>
304
+ <option value="jeep">جيب</option>
305
+ <option value="shaamil">شامل</option>
306
+ <option value="yemenpay">يمن والت</option>
307
+ </select>
308
+ </div>
309
+
310
+ <div class="form-group">
311
+ <label>رقم النقطة / هاتف المستقبل:</label>
312
+ <input type="text" id="point-number" placeholder="أدخل رقم النقطة أو الهاتف">
313
+ </div>
314
+
315
+ <div class="form-group" id="service-field">
316
+ <label>الخدمة:</label>
317
+ <select id="service" class="custom-select">
318
+ <option value="">-- اختر الخدمة --</option>
319
+ <option value="تسديد باقة اتصالات">تسديد باقة اتصالات</option>
320
+ <option value="فاتورة مياه">فاتورة مياه</option>
321
+ <option value="فاتورة كهرباء">فاتورة كهرباء</option>
322
+ <option value="مشتريات سوبر ماركت">مشتريات سوبر ماركت</option>
323
+ </select>
324
+ </div>
325
+
326
+ <div class="form-group" id="amount-field">
327
+ <label>المبلغ (ر.ي):</label>
328
+ <input type="number" id="amount" placeholder="أدخل المبلغ">
329
+ </div>
330
+
331
+ <button id="execute-btn">تنفيذ الدفع</button>
332
+
333
+ <div id="verification-section">
334
+ <div class="verification-option">
335
+ <h3>1. الرمز الثابت (1234):</h3>
336
+ <input type="password" id="verify-code" placeholder="أدخل الرمز">
337
+ <button class="small-btn" onclick="confirmVerification()">تأكيد الرمز</button>
338
+ </div>
339
+
340
+ <div class="verification-option">
341
+ <h3>2. مصادقة البصمة:</h3>
342
+ <button class="small-btn" onclick="registerFingerprint()">تسجيل البصمة</button>
343
+ <button class="small-btn" onclick="verifyFingerprint()">التحقق بالبصمة</button>
344
+ </div>
345
+
346
+ <div class="verification-option">
347
+ <h3>3. QR للتأكيد:</h3>
348
+ <div class="qr-container">
349
+ <a href="https://example.com/confirm?code=1234" target="_blank">
350
+ <img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://example.com/confirm?code=1234" alt="QR Code">
351
+ </a>
352
+ </div>
353
+ </div>
354
+ </div>
355
+ </div>
356
+
357
+ <div id="result">
358
+ <h2>تمت العملية بنجاح</h2>
359
+ <div id="transaction-details">
360
+ <div class="transaction-detail">الخدمة: <strong id="detail-service"></strong></div>
361
+ <div class="transaction-detail">المبلغ المستحق: <strong id="detail-amount"></strong></div>
362
+ <div class="transaction-detail">مبلغ العمولة: <strong id="detail-fee"></strong></div>
363
+ <div class="transaction-detail">المبلغ المخصوم: <strong id="detail-total"></strong></div>
364
+ <div class="transaction-detail" id="detail-transfer"></div>
365
+ <div class="transaction-detail">رقم النقطة / الهاتف: <strong id="detail-point"></strong></div>
366
+ <div class="transaction-detail">الرصيد المتبقي: <strong id="detail-balance"></strong></div>
367
+ <div class="balance-display" id="current-balance-display"></div>
368
+ </div>
369
+ <button class="close-btn" onclick="closeResult()">إغلاق</button>
370
+ </div>
371
+
372
+ <script>
373
+ // Source wallet balances
374
+ const wallets = {
375
+ jawali: {balance: 1000, name: "جوالي"},
376
+ kash: {balance: 500, name: "كاش"},
377
+ moneymobile: {balance: 0, name: "Mobile Money"},
378
+ jeep: {balance: 0, name: "Jeep"},
379
+ shaamil: {balance: 0, name: "شامل"},
380
+ yemenpay: {balance: 0, name: "يمن والت"}
381
+ };
382
+
383
+ // Wallet display names
384
+ const walletDisplayNames = {
385
+ jawali: "جوالي",
386
+ kash: "كاش",
387
+ moneymobile: "Mobile Money",
388
+ jeep: "Jeep",
389
+ shaamil: "شامل",
390
+ yemenpay: "يمن والت"
391
+ };
392
+
393
+ let storedCredential = null;
394
+ let currentStep = 1;
395
+
396
+ // Initialize wallet balances display
397
+ function initWalletBalances() {
398
+ const fromWalletSelect = document.getElementById("from-wallet");
399
+ const options = fromWalletSelect.options;
400
+
401
+ for (let i = 0; i < options.length; i++) {
402
+ const walletId = options[i].value;
403
+ if (wallets[walletId]) {
404
+ options[i].text = `${wallets[walletId].name} (${wallets[walletId].balance} ر.ي)`;
405
+ }
406
+ }
407
+ }
408
+
409
+ // Dynamic form navigation
410
+ document.getElementById("point-number").addEventListener("input", function() {
411
+ if (this.value.trim()) {
412
+ document.getElementById("service-field").style.display = "block";
413
+ updateStep(2);
414
+ } else {
415
+ document.getElementById("service-field").style.display = "none";
416
+ updateStep(1);
417
+ }
418
+ });
419
+
420
+ document.getElementById("service").addEventListener("change", function() {
421
+ if (this.value) {
422
+ document.getElementById("amount-field").style.display = "block";
423
+ updateStep(3);
424
+ } else {
425
+ document.getElementById("amount-field").style.display = "none";
426
+ updateStep(2);
427
+ }
428
+ });
429
+
430
+ document.getElementById("amount").addEventListener("input", function() {
431
+ if (+this.value > 0) {
432
+ document.getElementById("execute-btn").style.display = "block";
433
+ } else {
434
+ document.getElementById("execute-btn").style.display = "none";
435
+ }
436
+ });
437
+
438
+ document.getElementById("execute-btn").addEventListener("click", startVerification);
439
+
440
+ function updateStep(step) {
441
+ currentStep = step;
442
+ document.querySelectorAll('.step').forEach((el, index) => {
443
+ if (index + 1 < step) {
444
+ el.classList.remove('active');
445
+ el.classList.add('completed');
446
+ } else if (index + 1 === step) {
447
+ el.classList.add('active');
448
+ el.classList.remove('completed');
449
+ } else {
450
+ el.classList.remove('active', 'completed');
451
+ }
452
+ });
453
+ }
454
+
455
+ function startVerification() {
456
+ const toWallet = document.getElementById("to-wallet").value;
457
+ const pt = document.getElementById("point-number").value.trim();
458
+ const service = document.getElementById("service").value;
459
+ const amt = +document.getElementById("amount").value;
460
+
461
+ if (!toWallet || !pt || !service || !amt) {
462
+ return alert("يرجى ملء جميع الحقول أولاً");
463
+ }
464
+
465
+ document.getElementById("verification-section").style.display = "block";
466
+ document.getElementById("execute-btn").style.display = "none";
467
+ window.scrollTo(0, document.body.scrollHeight);
468
+ }
469
+
470
+ function confirmVerification() {
471
+ if (document.getElementById("verify-code").value === "1234") {
472
+ doPayment();
473
+ } else {
474
+ alert("الرمز غير صحيح");
475
+ }
476
+ }
477
+
478
+ async function registerFingerprint() {
479
+ if (!window.PublicKeyCredential) return alert("المتصفح لا يدعم WebAuthn");
480
+ try {
481
+ const cred = await navigator.credentials.create({
482
+ publicKey: {
483
+ challenge: new Uint8Array(32),
484
+ rp: {name: "Payment System"},
485
+ user: {id: Uint8Array.from([1,2,3,4]), name: "user", displayName: "User"},
486
+ pubKeyCredParams: [{type: "public-key", alg: -7}],
487
+ timeout: 60000,
488
+ attestation: "none"
489
+ }
490
+ });
491
+ storedCredential = cred;
492
+ alert("تم تسجيل بصمتك بنجاح");
493
+ } catch {
494
+ alert("فشل تسجيل البصمة");
495
+ }
496
+ }
497
+
498
+ async function verifyFingerprint() {
499
+ if (!storedCredential) return alert("الرجاء تسجيل البصمة أولاً");
500
+ try {
501
+ await navigator.credentials.get({
502
+ publicKey: {
503
+ challenge: new Uint8Array(32),
504
+ allowCredentials: [{type: "public-key", id: storedCredential.rawId}],
505
+ timeout: 60000,
506
+ userVerification: "preferred"
507
+ }
508
+ });
509
+ alert("تم التحقق بالبصمة");
510
+ doPayment();
511
+ } catch {
512
+ alert("فشل التحقق بالبصمة");
513
+ }
514
+ }
515
+
516
+ function doPayment() {
517
+ const from = document.getElementById("from-wallet").value;
518
+ const to = document.getElementById("to-wallet").value;
519
+ const service = document.getElementById("service").value;
520
+ const pt = document.getElementById("point-number").value;
521
+ const amt = +document.getElementById("amount").value;
522
+ const fee = 20;
523
+
524
+ // Check source wallet balance
525
+ if (wallets[from].balance < amt + fee) {
526
+ return alert("رصيد غير كافٍ في محفظتك");
527
+ }
528
+
529
+ // Deduct from source wallet
530
+ wallets[from].balance -= amt + fee;
531
+
532
+ // Get display names for wallets
533
+ const fromDisplay = wallets[from].name;
534
+ const toDisplay = walletDisplayNames[to] || to;
535
+
536
+ // Update transaction details
537
+ document.getElementById("detail-service").textContent = service;
538
+ document.getElementById("detail-amount").textContent = amt + " ر.ي";
539
+ document.getElementById("detail-fee").textContent = fee + " ر.ي";
540
+ document.getElementById("detail-total").textContent = (amt + fee) + " ر.ي";
541
+ document.getElementById("detail-transfer").innerHTML =
542
+ `تم تحويل <strong>${amt} ر.ي</strong> من <strong>${fromDisplay}</strong> إلى <strong>${toDisplay}</strong>`;
543
+ document.getElementById("detail-point").textContent = pt;
544
+ document.getElementById("detail-balance").textContent =
545
+ `${fromDisplay}: ${wallets[from].balance} ر.ي`;
546
+
547
+ // Show current balance in a prominent way
548
+ const balanceDisplay = document.getElementById("current-balance-display");
549
+ balanceDisplay.innerHTML = `
550
+ الرصيد المتوفر حالياً: <strong>${wallets[from].balance} ر.ي</strong>
551
+ `;
552
+ balanceDisplay.className = wallets[from].balance < 500 ?
553
+ "balance-display low-balance" : "balance-display normal-balance";
554
+
555
+ // Show result
556
+ document.getElementById("overlay").style.display = "block";
557
+ document.getElementById("result").style.display = "block";
558
+
559
+ // Update the source wallet balance in dropdown
560
+ updateWalletBalances();
561
+ }
562
+
563
+ // Update wallet balances in dropdown
564
+ function updateWalletBalances() {
565
+ const fromWalletSelect = document.getElementById("from-wallet");
566
+ const options = fromWalletSelect.options;
567
+
568
+ for (let i = 0; i < options.length; i++) {
569
+ const walletId = options[i].value;
570
+ if (wallets[walletId]) {
571
+ options[i].text = `${wallets[walletId].name} (${wallets[walletId].balance} ر.ي)`;
572
+ }
573
+ }
574
+ }
575
+
576
+ function closeResult() {
577
+ document.getElementById("result").style.display = "none";
578
+ document.getElementById("overlay").style.display = "none";
579
+ document.getElementById("verification-section").style.display = "none";
580
+
581
+ // Reset form
582
+ document.getElementById("to-wallet").value = "";
583
+ document.getElementById("point-number").value = "";
584
+ document.getElementById("service").value = "";
585
+ document.getElementById("amount").value = "";
586
+ document.getElementById("verify-code").value = "";
587
+
588
+ // Reset steps
589
+ updateStep(1);
590
+
591
+ // Update wallet balances in UI
592
+ updateWalletBalances();
593
+ }
594
+
595
+ // Initialize on page load
596
+ document.addEventListener("DOMContentLoaded", function() {
597
+ // Change labels as requested
598
+ document.querySelector('label[for="from-wallet"]').textContent = "من محفظتي:";
599
+ document.querySelector('label[for="to-wallet"]').textContent = "إلى محفظة:";
600
+
601
+ // Initialize wallet balances display
602
+ initWalletBalances();
603
+ });
604
+ </script>
605
+
606
+ <!-- تذييل الصفحة مع حقوق الملكية -->
607
+ <footer style="text-align: center; margin-top: 20px; color: #666; font-size: 0.9rem; padding: 10px;">
608
+ <p>المدى للخدمات البرمجية التسويقية والإعلانية</p>
609
+ <p>المدير العام: المهندس/ محمد المرتضى</p>
610
+ <p>© <span id="current-year">2023</span> جميع الحقوق محفوظة</p>
611
+ </footer>
612
+
613
+ <script>
614
+ // Update year automatically
615
+ document.getElementById('current-year').textContent = new Date().getFullYear();
616
+ </script>
617
+ </body>
618
+ </html>