diff --git a/android.keystore b/android.keystore
new file mode 100644
index 00000000..76491275
Binary files /dev/null and b/android.keystore differ
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 00000000..3332c14e
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import groovy.xml.MarkupBuilder
+
+plugins {
+ id 'com.android.application'
+}
+
+def twaManifest = [
+ applicationId: 'ir.mysalona.testapp.twa',
+ hostName: 'testapp.mysalona.ir', // The domain being opened in the TWA.
+ launchUrl: '/', // The start path for the TWA. Must be relative to the domain.
+ name: 'Salona', // The application name.
+ launcherName: 'Salona', // The name shown on the Android Launcher.
+ themeColor: '#AB25C0', // The color used for the status bar.
+ themeColorDark: '#000000', // The color used for the dark status bar.
+ navigationColor: '#000000', // The color used for the navigation bar.
+ navigationColorDark: '#000000', // The color used for the dark navbar.
+ navigationDividerColor: '#000000', // The navbar divider color.
+ navigationDividerColorDark: '#000000', // The dark navbar divider color.
+ backgroundColor: '#AB25C0', // The color used for the splash screen background.
+ enableNotifications: true, // Set to true to enable notification delegation.
+ // Every shortcut must include the following fields:
+ // - name: String that will show up in the shortcut.
+ // - short_name: Shorter string used if |name| is too long.
+ // - url: Absolute path of the URL to launch the app with (e.g '/create').
+ // - icon: Name of the resource in the drawable folder to use as an icon.
+ shortcuts: [],
+ // The duration of fade out animation in milliseconds to be played when removing splash screen.
+ splashScreenFadeOutDuration: 300,
+ generatorApp: 'bubblewrap-cli', // Application that generated the Android Project
+ // The fallback strategy for when Trusted Web Activity is not available. Possible values are
+ // 'customtabs' and 'webview'.
+ fallbackType: 'customtabs',
+ enableSiteSettingsShortcut: 'true',
+ orientation: 'default',
+]
+
+android {
+ compileSdkVersion 36
+ namespace "ir.mysalona.testapp.twa"
+ defaultConfig {
+ applicationId "ir.mysalona.testapp.twa"
+ minSdkVersion 21
+ targetSdkVersion 35
+ versionCode 1
+ versionName "1"
+
+ // The name for the application
+ resValue "string", "appName", twaManifest.name
+
+ // The name for the application on the Android Launcher
+ resValue "string", "launcherName", twaManifest.launcherName
+
+ // The URL that will be used when launching the TWA from the Android Launcher
+ def launchUrl = "https://" + twaManifest.hostName + twaManifest.launchUrl
+ resValue "string", "launchUrl", launchUrl
+
+
+
+
+ // The URL the Web Manifest for the Progressive Web App that the TWA points to. This
+ // is used by Chrome OS and Meta Quest to open the Web version of the PWA instead of
+ // the TWA, as it will probably give a better user experience for non-mobile devices.
+ resValue "string", "webManifestUrl", 'https://testapp.mysalona.ir/manifest.webmanifest'
+
+
+
+ // This is used by Meta Quest.
+ resValue "string", "fullScopeUrl", 'https://testapp.mysalona.ir/'
+
+
+
+
+ // The hostname is used when building the intent-filter, so the TWA is able to
+ // handle Intents to open host url of the application.
+ resValue "string", "hostName", twaManifest.hostName
+
+ // This attribute sets the status bar color for the TWA. It can be either set here or in
+ // `res/values/colors.xml`. Setting in both places is an error and the app will not
+ // compile. If not set, the status bar color defaults to #FFFFFF - white.
+ resValue "color", "colorPrimary", twaManifest.themeColor
+
+ // This attribute sets the dark status bar color for the TWA. It can be either set here or in
+ // `res/values/colors.xml`. Setting in both places is an error and the app will not
+ // compile. If not set, the status bar color defaults to #000000 - white.
+ resValue "color", "colorPrimaryDark", twaManifest.themeColorDark
+
+ // This attribute sets the navigation bar color for the TWA. It can be either set here or
+ // in `res/values/colors.xml`. Setting in both places is an error and the app will not
+ // compile. If not set, the navigation bar color defaults to #FFFFFF - white.
+ resValue "color", "navigationColor", twaManifest.navigationColor
+
+ // This attribute sets the dark navigation bar color for the TWA. It can be either set here
+ // or in `res/values/colors.xml`. Setting in both places is an error and the app will not
+ // compile. If not set, the navigation bar color defaults to #000000 - black.
+ resValue "color", "navigationColorDark", twaManifest.navigationColorDark
+
+ // This attribute sets the navbar divider color for the TWA. It can be either
+ // set here or in `res/values/colors.xml`. Setting in both places is an error and the app
+ // will not compile. If not set, the divider color defaults to #00000000 - transparent.
+ resValue "color", "navigationDividerColor", twaManifest.navigationDividerColor
+
+ // This attribute sets the dark navbar divider color for the TWA. It can be either
+ // set here or in `res/values/colors.xml`. Setting in both places is an error and the
+ //app will not compile. If not set, the divider color defaults to #000000 - black.
+ resValue "color", "navigationDividerColorDark", twaManifest.navigationDividerColorDark
+
+ // Sets the color for the background used for the splash screen when launching the
+ // Trusted Web Activity.
+ resValue "color", "backgroundColor", twaManifest.backgroundColor
+
+ // Defines a provider authority for the Splash Screen
+ resValue "string", "providerAuthority", twaManifest.applicationId + '.fileprovider'
+
+ // The enableNotification resource is used to enable or disable the
+ // TrustedWebActivityService, by changing the android:enabled and android:exported
+ // attributes
+ resValue "bool", "enableNotification", twaManifest.enableNotifications.toString()
+
+ twaManifest.shortcuts.eachWithIndex { shortcut, index ->
+ resValue "string", "shortcut_name_$index", "$shortcut.name"
+ resValue "string", "shortcut_short_name_$index", "$shortcut.short_name"
+ }
+
+ // The splashScreenFadeOutDuration resource is used to set the duration of fade out animation in milliseconds
+ // to be played when removing splash screen. The default is 0 (no animation).
+ resValue "integer", "splashScreenFadeOutDuration", twaManifest.splashScreenFadeOutDuration.toString()
+
+ resValue "string", "generatorApp", twaManifest.generatorApp
+
+ resValue "string", "fallbackType", twaManifest.fallbackType
+
+ resValue "bool", "enableSiteSettingsShortcut", twaManifest.enableSiteSettingsShortcut
+ resValue "string", "orientation", twaManifest.orientation
+
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled true
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ lintOptions {
+ checkReleaseBuilds false
+ }
+}
+
+task generateShorcutsFile {
+ assert twaManifest.shortcuts.size() < 5, "You can have at most 4 shortcuts."
+ twaManifest.shortcuts.eachWithIndex { s, i ->
+ assert s.name != null, 'Missing `name` in shortcut #' + i
+ assert s.short_name != null, 'Missing `short_name` in shortcut #' + i
+ assert s.url != null, 'Missing `icon` in shortcut #' + i
+ assert s.icon != null, 'Missing `url` in shortcut #' + i
+ }
+
+ def shortcutsFile = new File("$projectDir/src/main/res/xml", "shortcuts.xml")
+
+ def xmlWriter = new StringWriter()
+ def xmlMarkup = new MarkupBuilder(new IndentPrinter(xmlWriter, " ", true))
+
+ xmlMarkup
+ .'shortcuts'('xmlns:android': 'http://schemas.android.com/apk/res/android') {
+ twaManifest.shortcuts.eachWithIndex { s, i ->
+ 'shortcut'(
+ 'android:shortcutId': 'shortcut' + i,
+ 'android:enabled': 'true',
+ 'android:icon': '@drawable/' + s.icon,
+ 'android:shortcutShortLabel': '@string/shortcut_short_name_' + i,
+ 'android:shortcutLongLabel': '@string/shortcut_name_' + i) {
+ 'intent'(
+ 'android:action': 'android.intent.action.MAIN',
+ 'android:targetPackage': twaManifest.applicationId,
+ 'android:targetClass': twaManifest.applicationId + '.LauncherActivity',
+ 'android:data': s.url)
+ 'categories'('android:name': 'android.intent.category.LAUNCHER')
+ }
+ }
+ }
+ shortcutsFile.text = xmlWriter.toString() + '\n'
+}
+
+preBuild.dependsOn(generateShorcutsFile)
+
+repositories {
+
+}
+
+dependencies {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+
+ implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.6.2'
+
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..5d5c0f30
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
-- افزودن خدمات پرسنل -
+افزودن خدمات پرسنل
) : filteredServices.length > 0 ? ( void;
- serviceList?: any[];
- onSelectPersonelServiceId?: (id?: number) => void;
- onSelectPersonelId?: (id?: number) => void;
- personnelId?: number | null; // ✅ اضافه کنید
- setPersonnelId?: (id: number | null) => void; // ✅ اضافه کنید
+ onChange?: (v: string) => void;
+ serviceList?: any[];
+ onSelectPersonelServiceId?: (id?: number) => void;
+ onSelectPersonelId?: (id?: number) => void;
+ personnelId?: number | null;
+ setPersonnelId?: (id: number | null) => void;
};
const PRICE_KEY = "servicePrice";
const PERSONEL_SERVICE_ID_KEY = "selectedPersonelServiceId";
-const PERSONEL_ID_KEY = "selectedPersonelId"; // ✅ کلید جدید localStorage
+const PERSONEL_ID_KEY = "selectedPersonelId";
const PersonnelServicesQA: React.FC
- {svc}
-
+ {svc}
+ {svc}
- {svc}
- {"پرسنلی وجود ندارد"} +
- افزودن خدمات پرسنل
- {"پرسنلی وجود ندارد"} + افزودن خدمات پرسنل {title} {title} {title}
-
- خدمات
-
-
+ خدمات
+
-//
+
-