Initial commit
2
.env
Normal file
@ -0,0 +1,2 @@
|
||||
API_URL=https://venbait.in/nhance/dev/employeeRest/
|
||||
TICKET_API_URL=https://venbait.in/nhance/helpdesk/dev/api/
|
||||
2
.env.development
Normal file
@ -0,0 +1,2 @@
|
||||
API_URL=https://venbait.in/nhance/dev/employeeRest/
|
||||
TICKET_API_URL=https://venbait.in/nhance/helpdesk/dev/api/
|
||||
2
.env.production
Normal file
@ -0,0 +1,2 @@
|
||||
API_URL=https://venbait.in/nhance/dev/employeeRest/
|
||||
TICKET_API_URL=https://venbait.in/nhance/helpdesk/dev/api/
|
||||
104
.gitignore
vendored
@ -1,50 +1,68 @@
|
||||
# These are some examples of commonly ignored file patterns.
|
||||
# You should customize this list as applicable to your project.
|
||||
# Learn more about .gitignore:
|
||||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
|
||||
|
||||
# Node artifact files
|
||||
node_modules/
|
||||
dist/
|
||||
|
||||
# Compiled Java class files
|
||||
# Miscellaneous
|
||||
*.class
|
||||
|
||||
# Compiled Python bytecode
|
||||
*.py[cod]
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Package files
|
||||
*.jar
|
||||
|
||||
# Maven
|
||||
target/
|
||||
dist/
|
||||
|
||||
# JetBrains IDE
|
||||
.idea/
|
||||
|
||||
# Unit test reports
|
||||
TEST*.xml
|
||||
|
||||
# Generated by MacOS
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
migrate_working_dir/
|
||||
|
||||
# Generated by Windows
|
||||
Thumbs.db
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.lock
|
||||
*.packages
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Applications
|
||||
*.app
|
||||
*.exe
|
||||
*.war
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Large media files
|
||||
*.mp4
|
||||
*.tiff
|
||||
*.avi
|
||||
*.flv
|
||||
*.mov
|
||||
*.wmv
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Android specific files
|
||||
*.android/
|
||||
*.android.iml
|
||||
*.apk
|
||||
*.ap_
|
||||
|
||||
# iOS specific files
|
||||
*.ios/
|
||||
*.ios.iml
|
||||
*.ipa
|
||||
*.xcworkspace
|
||||
*.xcodeproj/
|
||||
*.xcuserdatad/
|
||||
|
||||
# macOS specific files
|
||||
.idea/workspace.xml
|
||||
|
||||
|
||||
# Dependency lock files
|
||||
.pubspec.lock
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
|
||||
45
.metadata
Normal file
@ -0,0 +1,45 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: "300451adae589accbece3490f4396f10bdf15e6e"
|
||||
channel: "stable"
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: android
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: ios
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: linux
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: macos
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: web
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
- platform: windows
|
||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# nhance_app_pwa
|
||||
|
||||
Nhance App Flutter
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
28
analysis_options.yaml
Normal file
@ -0,0 +1,28 @@
|
||||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at https://dart.dev/lints.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
13
android/.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
67
android/app/build.gradle
Normal file
@ -0,0 +1,67 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "com.example.nhance_app_pwa"
|
||||
compileSdk flutter.compileSdkVersion
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.example.nhance_app_pwa"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {}
|
||||
7
android/app/src/debug/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
49
android/app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,49 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<application
|
||||
android:label="nhance_app_pwa"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility?hl=en and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@ -0,0 +1,5 @@
|
||||
package com.example.nhance_app_pwa
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity()
|
||||
12
android/app/src/main/res/drawable-v21/launch_background.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
12
android/app/src/main/res/drawable/launch_background.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 996 B |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
18
android/app/src/main/res/values-night/styles.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
18
android/app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
7
android/app/src/profile/AndroidManifest.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
18
android/build.gradle
Normal file
@ -0,0 +1,18 @@
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
3
android/gradle.properties
Normal file
@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx4G
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
|
||||
26
android/settings.gradle
Normal file
@ -0,0 +1,26 @@
|
||||
pluginManagement {
|
||||
def flutterSdkPath = {
|
||||
def properties = new Properties()
|
||||
file("local.properties").withInputStream { properties.load(it) }
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
return flutterSdkPath
|
||||
}
|
||||
settings.ext.flutterSdkPath = flutterSdkPath()
|
||||
|
||||
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||
id "com.android.application" version "7.3.0" apply false
|
||||
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
|
||||
}
|
||||
|
||||
include ":app"
|
||||
BIN
assets/Female.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
assets/Group.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/Group_3.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
assets/Male.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
assets/Solid_gray.png
Normal file
|
After Width: | Height: | Size: 99 B |
BIN
assets/Template_File.xlsx
Normal file
BIN
assets/Vector.png
Normal file
|
After Width: | Height: | Size: 840 B |
BIN
assets/emoji.png
Normal file
|
After Width: | Height: | Size: 747 B |
BIN
assets/help.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/hrLogin.jpg
Normal file
|
After Width: | Height: | Size: 476 KiB |
BIN
assets/img1.png
Normal file
|
After Width: | Height: | Size: 125 KiB |
BIN
assets/login_web.jpg
Normal file
|
After Width: | Height: | Size: 833 KiB |
BIN
assets/navbarLogo.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/nhance-loader.gif
Normal file
|
After Width: | Height: | Size: 493 KiB |
BIN
assets/nhance_app_logo.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
assets/nhance_client_logo.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
assets/policy.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/slider1.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/slider2.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
assets/slider3.png
Normal file
|
After Width: | Height: | Size: 1001 KiB |
BIN
assets/tickets.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
34
ios/.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
**/dgph
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
||||
26
ios/Flutter/AppFrameworkInfo.plist
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
1
ios/Flutter/Debug.xcconfig
Normal file
@ -0,0 +1 @@
|
||||
#include "Generated.xcconfig"
|
||||
1
ios/Flutter/Release.xcconfig
Normal file
@ -0,0 +1 @@
|
||||
#include "Generated.xcconfig"
|
||||
13
ios/Runner/AppDelegate.swift
Normal file
@ -0,0 +1,13 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
|
||||
@UIApplicationMain
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
||||
122
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 494 B |
|
After Width: | Height: | Size: 772 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 772 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
23
ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
5
ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
||||
37
ios/Runner/Base.lproj/LaunchScreen.storyboard
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
26
ios/Runner/Base.lproj/Main.storyboard
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
49
ios/Runner/Info.plist
Normal file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Nhance App Pwa</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>nhance_app_pwa</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
1
ios/Runner/Runner-Bridging-Header.h
Normal file
@ -0,0 +1 @@
|
||||
#import "GeneratedPluginRegistrant.h"
|
||||
12
ios/RunnerTests/RunnerTests.swift
Normal file
@ -0,0 +1,12 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
import XCTest
|
||||
|
||||
class RunnerTests: XCTestCase {
|
||||
|
||||
func testExample() {
|
||||
// If you add code to the Runner application, consider adding tests here.
|
||||
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
|
||||
}
|
||||
|
||||
}
|
||||
139
lib/customAppBar/customAppBar.dart
Normal file
@ -0,0 +1,139 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:adaptive_navbar/adaptive_navbar.dart';
|
||||
import 'package:nhance_app_pwa/customAppBar/responsive.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(kToolbarHeight);
|
||||
|
||||
Future<void> logout(BuildContext context) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String? hrtoken = prefs.getString('hrtoken');
|
||||
final String? token = prefs.getString('token');
|
||||
|
||||
if (token != null && token.isNotEmpty) {
|
||||
if (hrtoken != null && hrtoken.isNotEmpty) {
|
||||
prefs.remove('token');
|
||||
Navigator.pushNamed(context, 'hrDashboard');
|
||||
} else {
|
||||
await prefs.clear();
|
||||
Navigator.pushNamed(context, 'phone');
|
||||
}
|
||||
} else if (hrtoken != null && hrtoken.isNotEmpty) {
|
||||
await prefs.clear();
|
||||
Navigator.pushNamed(context, 'hrLogin');
|
||||
}
|
||||
// Navigator.pushNamed(context, "phone");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sw = MediaQuery.of(context).size.width;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFFFFCE5), // Set background color for AppBar
|
||||
appBar: PreferredSize(
|
||||
preferredSize: preferredSize,
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(horizontal: 16.0)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Row(
|
||||
children: [
|
||||
// Logo Column
|
||||
Expanded(
|
||||
flex: Responsive.isDesktop(context) ? 3 : 9,
|
||||
child: Row(
|
||||
mainAxisAlignment: Responsive.isDesktop(context)
|
||||
? MainAxisAlignment.spaceEvenly
|
||||
: MainAxisAlignment
|
||||
.start, // Adjust the alignment as needed
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
width: Responsive.isDesktop(context) ? 230 : 170,
|
||||
height: Responsive.isDesktop(context) ? 230 : 170,
|
||||
child: Image.asset(
|
||||
'assets/nhance_client_logo.png',
|
||||
fit: BoxFit.contain, // Adjust the fit as needed
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// AdaptiveNavBar Column
|
||||
if (Responsive.isDesktop(context))
|
||||
Expanded(
|
||||
flex: Responsive.isDesktop(context) ? 9 : 3,
|
||||
child: AdaptiveNavBar(
|
||||
screenWidth: sw,
|
||||
backgroundColor: Color(0xFFFFFCE5),
|
||||
leading:
|
||||
Container(), // Set an empty container as we have the logo separately
|
||||
title: Text(''),
|
||||
navBarItems: [
|
||||
NavBarItem(
|
||||
text: "Home",
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
},
|
||||
),
|
||||
NavBarItem(
|
||||
text: "Claim",
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
},
|
||||
),
|
||||
NavBarItem(
|
||||
text: "Help",
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
},
|
||||
),
|
||||
NavBarItem(
|
||||
text: "Profile",
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Expanded(
|
||||
// flex: Responsive.isDesktop(context) ? 1 : 3,
|
||||
// child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// children: [
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment
|
||||
// .end, // Aligns the content to the right
|
||||
// children: [
|
||||
// Icon(Icons.notifications, color: Colors.black),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: Responsive.isDesktop(context) ? 10 : 3),
|
||||
// if (Responsive.isDesktop(context))
|
||||
// Expanded(
|
||||
// flex: Responsive.isDesktop(context) ? 2 : 3,
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Icon(Icons.account_circle, color: Colors.black),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: Responsive.isDesktop(context) ? 5 : 0),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
23
lib/customAppBar/customFooter.dart
Normal file
@ -0,0 +1,23 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomFooter extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
color: Color(0xFFFFFBDE), // Background color of the footer
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'Copyright@ 2024 Nhance - Jubiliant',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600], // Text color
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
47
lib/customAppBar/responsive.dart
Normal file
@ -0,0 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Responsive extends StatelessWidget {
|
||||
final Widget mobile;
|
||||
final Widget tablet;
|
||||
final Widget desktop;
|
||||
|
||||
const Responsive({
|
||||
required Key key,
|
||||
required this.mobile,
|
||||
required this.tablet,
|
||||
required this.desktop,
|
||||
}) : super(key: key);
|
||||
|
||||
// This size work fine on my design, maybe you need some customization depends on your design
|
||||
|
||||
// This isMobile, isTablet, isDesktop helep us later
|
||||
static bool isMobile(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 650;
|
||||
|
||||
static bool isTablet(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width < 1100 &&
|
||||
MediaQuery.of(context).size.width >= 650;
|
||||
|
||||
static bool isDesktop(BuildContext context) =>
|
||||
MediaQuery.of(context).size.width >= 1100;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
// If our width is more than 1100 then we consider it a desktop
|
||||
builder: (context, constraints) {
|
||||
if (constraints.maxWidth >= 1100) {
|
||||
return desktop;
|
||||
}
|
||||
// If width it less then 1100 and more then 650 we consider it as tablet
|
||||
else if (constraints.maxWidth >= 650) {
|
||||
return tablet;
|
||||
}
|
||||
// Or less then that we called it mobile
|
||||
else {
|
||||
return mobile;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
78
lib/customAppBar/tabs.dart
Normal file
@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
|
||||
|
||||
class CustomBottomNavigationBar extends StatefulWidget {
|
||||
final Function(int) onTabChanged;
|
||||
final List<IconData> icons;
|
||||
final List<String> labels; // Add labels list
|
||||
final int initialIndex;
|
||||
|
||||
const CustomBottomNavigationBar({
|
||||
Key? key,
|
||||
required this.onTabChanged,
|
||||
required this.icons,
|
||||
required this.labels,
|
||||
this.initialIndex = 0,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CustomBottomNavigationBarState createState() =>
|
||||
_CustomBottomNavigationBarState();
|
||||
}
|
||||
|
||||
class _CustomBottomNavigationBarState extends State<CustomBottomNavigationBar> {
|
||||
late int _currentIndex;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_currentIndex = widget.initialIndex;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBottomNavigationBar.builder(
|
||||
itemCount: widget.icons.length,
|
||||
tabBuilder: (int index, bool isActive) {
|
||||
Color backgroundColor = Color(0xFFFFFCE5);
|
||||
Color iconColor = isActive ? Color(0xFFE26728) : Color(0xFF404040);
|
||||
TextStyle textStyle = TextStyle(
|
||||
color: iconColor,
|
||||
fontSize: 10,
|
||||
fontWeight: isActive ? FontWeight.w400 : FontWeight.normal,
|
||||
);
|
||||
return Container(
|
||||
color: backgroundColor,
|
||||
padding: EdgeInsets.all(8), // Adjust padding as needed
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
widget.icons[index],
|
||||
size: 24,
|
||||
color: iconColor,
|
||||
),
|
||||
SizedBox(height: 2), // Spacing between icon and text
|
||||
Text(
|
||||
widget.labels[index],
|
||||
style: textStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
activeIndex: _currentIndex,
|
||||
gapLocation: GapLocation.none,
|
||||
notchSmoothness: NotchSmoothness.verySmoothEdge,
|
||||
leftCornerRadius: 32,
|
||||
rightCornerRadius: 32,
|
||||
onTap: (index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
widget.onTabChanged(index);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
223
lib/customAppBar/toastHelper.dart
Normal file
@ -0,0 +1,223 @@
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:toastification/toastification.dart';
|
||||
|
||||
class ToastHelper {
|
||||
static void showSuccessToast(BuildContext context, String message) {
|
||||
toastification.show(
|
||||
context: context,
|
||||
type: ToastificationType.success,
|
||||
style: ToastificationStyle.flatColored,
|
||||
autoCloseDuration: const Duration(seconds: 2),
|
||||
title: Text(message),
|
||||
// you can also use RichText widget for title and description parameters
|
||||
// description: RichText(
|
||||
// text: const TextSpan(text: 'This is a sample toast message. ')),
|
||||
alignment: Alignment.topRight,
|
||||
direction: TextDirection.ltr,
|
||||
animationDuration: const Duration(milliseconds: 100),
|
||||
animationBuilder: (context, animation, alignment, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.check),
|
||||
primaryColor: Colors.green,
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.black,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x07000000),
|
||||
blurRadius: 16,
|
||||
offset: Offset(0, 16),
|
||||
spreadRadius: 0,
|
||||
)
|
||||
],
|
||||
showProgressBar: true,
|
||||
closeButtonShowType: CloseButtonShowType.onHover,
|
||||
closeOnClick: false,
|
||||
pauseOnHover: true,
|
||||
dragToClose: true,
|
||||
applyBlurEffect: true,
|
||||
callbacks: ToastificationCallbacks(
|
||||
onTap: (toastItem) => print('Toast ${toastItem.id} tapped'),
|
||||
onCloseButtonTap: (toastItem) =>
|
||||
print('Toast ${toastItem.id} close button tapped'),
|
||||
onAutoCompleteCompleted: (toastItem) =>
|
||||
print('Toast ${toastItem.id} auto complete completed'),
|
||||
onDismissed: (toastItem) => print('Toast ${toastItem.id} dismissed'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static void showWarningToast(BuildContext context, String message) {
|
||||
toastification.show(
|
||||
context: context,
|
||||
type: ToastificationType.warning,
|
||||
style: ToastificationStyle.flatColored,
|
||||
autoCloseDuration: const Duration(seconds: 2),
|
||||
title: Text(message),
|
||||
// you can also use RichText widget for title and description parameters
|
||||
// description: RichText(
|
||||
// text: const TextSpan(text: 'This is a sample toast message. ')),
|
||||
alignment: Alignment.topRight,
|
||||
direction: TextDirection.ltr,
|
||||
animationDuration: const Duration(milliseconds: 100),
|
||||
animationBuilder: (context, animation, alignment, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.warning),
|
||||
primaryColor: Colors.amberAccent,
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.black,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x07000000),
|
||||
blurRadius: 16,
|
||||
offset: Offset(0, 16),
|
||||
spreadRadius: 0,
|
||||
)
|
||||
],
|
||||
showProgressBar: true,
|
||||
closeButtonShowType: CloseButtonShowType.onHover,
|
||||
closeOnClick: false,
|
||||
pauseOnHover: true,
|
||||
dragToClose: true,
|
||||
applyBlurEffect: true,
|
||||
callbacks: ToastificationCallbacks(
|
||||
onTap: (toastItem) => print('Toast ${toastItem.id} tapped'),
|
||||
onCloseButtonTap: (toastItem) =>
|
||||
print('Toast ${toastItem.id} close button tapped'),
|
||||
onAutoCompleteCompleted: (toastItem) =>
|
||||
print('Toast ${toastItem.id} auto complete completed'),
|
||||
onDismissed: (toastItem) => print('Toast ${toastItem.id} dismissed'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static void showErrorToast(BuildContext context, String message) {
|
||||
toastification.show(
|
||||
context: context,
|
||||
type: ToastificationType.error,
|
||||
style: ToastificationStyle.flatColored,
|
||||
autoCloseDuration: const Duration(seconds: 2),
|
||||
title: Text(message),
|
||||
// you can also use RichText widget for title and description parameters
|
||||
// description: RichText(
|
||||
// text: const TextSpan(text: 'This is a sample toast message. ')),
|
||||
alignment: Alignment.topRight,
|
||||
direction: TextDirection.ltr,
|
||||
animationDuration: const Duration(milliseconds: 100),
|
||||
animationBuilder: (context, animation, alignment, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.error),
|
||||
primaryColor: Colors.redAccent,
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.black,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x07000000),
|
||||
blurRadius: 16,
|
||||
offset: Offset(0, 16),
|
||||
spreadRadius: 0,
|
||||
)
|
||||
],
|
||||
showProgressBar: true,
|
||||
closeButtonShowType: CloseButtonShowType.onHover,
|
||||
closeOnClick: false,
|
||||
pauseOnHover: true,
|
||||
dragToClose: true,
|
||||
applyBlurEffect: true,
|
||||
callbacks: ToastificationCallbacks(
|
||||
onTap: (toastItem) => print('Toast ${toastItem.id} tapped'),
|
||||
onCloseButtonTap: (toastItem) =>
|
||||
print('Toast ${toastItem.id} close button tapped'),
|
||||
onAutoCompleteCompleted: (toastItem) =>
|
||||
print('Toast ${toastItem.id} auto complete completed'),
|
||||
onDismissed: (toastItem) => print('Toast ${toastItem.id} dismissed'),
|
||||
),
|
||||
);
|
||||
// _showToast(context, message, Colors.red);
|
||||
}
|
||||
|
||||
static void showInfoToast(BuildContext context, String message) {
|
||||
toastification.show(
|
||||
context: context,
|
||||
type: ToastificationType.info,
|
||||
style: ToastificationStyle.flatColored,
|
||||
autoCloseDuration: const Duration(seconds: 2),
|
||||
title: Text(message),
|
||||
// you can also use RichText widget for title and description parameters
|
||||
// description: RichText(
|
||||
// text: const TextSpan(text: 'This is a sample toast message. ')),
|
||||
alignment: Alignment.topRight,
|
||||
direction: TextDirection.ltr,
|
||||
animationDuration: const Duration(milliseconds: 100),
|
||||
animationBuilder: (context, animation, alignment, child) {
|
||||
return FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.info),
|
||||
primaryColor: Colors.lightBlue,
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: Colors.black,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: const [
|
||||
BoxShadow(
|
||||
color: Color(0x07000000),
|
||||
blurRadius: 16,
|
||||
offset: Offset(0, 16),
|
||||
spreadRadius: 0,
|
||||
)
|
||||
],
|
||||
showProgressBar: true,
|
||||
closeButtonShowType: CloseButtonShowType.onHover,
|
||||
closeOnClick: false,
|
||||
pauseOnHover: true,
|
||||
dragToClose: true,
|
||||
applyBlurEffect: true,
|
||||
callbacks: ToastificationCallbacks(
|
||||
onTap: (toastItem) => print('Toast ${toastItem.id} tapped'),
|
||||
onCloseButtonTap: (toastItem) =>
|
||||
print('Toast ${toastItem.id} close button tapped'),
|
||||
onAutoCompleteCompleted: (toastItem) =>
|
||||
print('Toast ${toastItem.id} auto complete completed'),
|
||||
onDismissed: (toastItem) => print('Toast ${toastItem.id} dismissed'),
|
||||
),
|
||||
);
|
||||
// _showToast(context, message, Colors.red);
|
||||
}
|
||||
|
||||
static void _showToast(BuildContext context, String message, Color color) {
|
||||
// Fluttertoast.showToast(
|
||||
// msg: message,
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.TOP,
|
||||
// timeInSecForIosWeb: 5,
|
||||
// backgroundColor: color,
|
||||
// textColor: Colors.white,
|
||||
// fontSize: 16.0,
|
||||
// );
|
||||
}
|
||||
}
|
||||
30
lib/main.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:nhance_app_pwa/pages/claimprocess.dart';
|
||||
import 'package:nhance_app_pwa/pages/claims.dart';
|
||||
import 'package:nhance_app_pwa/pages/help.dart';
|
||||
import 'package:nhance_app_pwa/pages/home.dart';
|
||||
import 'package:nhance_app_pwa/pages/login.dart';
|
||||
import 'package:nhance_app_pwa/pages/policies.dart';
|
||||
import 'package:nhance_app_pwa/pages/profile.dart';
|
||||
import 'package:nhance_app_pwa/pages/verify.dart';
|
||||
import 'models/environment.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
await dotenv.load(fileName: Environment.fileName);
|
||||
|
||||
runApp(MaterialApp(
|
||||
initialRoute: 'login',
|
||||
debugShowCheckedModeBanner: false,
|
||||
routes: {
|
||||
'login': (context) => login(),
|
||||
'verify': (context) => MyVerify(),
|
||||
'home': (context) => MyApp(),
|
||||
'policies': (context) => policies(),
|
||||
'claims': (context) => claims(),
|
||||
'help': (context) => help(),
|
||||
'claimprocess': (context) => claimprocess(),
|
||||
'profile': (context) => profile(),
|
||||
},
|
||||
));
|
||||
}
|
||||
24
lib/models/environment.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class Environment {
|
||||
static String get fileName {
|
||||
if (kReleaseMode) {
|
||||
return '.env.production';
|
||||
}
|
||||
|
||||
return '.env.development';
|
||||
}
|
||||
|
||||
static String get apiUrl {
|
||||
return dotenv.env['API_URL'] ?? 'API_URL not found!';
|
||||
}
|
||||
|
||||
static String get apiUrlTicket {
|
||||
return dotenv.env['TICKET_API_URL'] ?? 'API_URL not found!';
|
||||
}
|
||||
|
||||
static String get ticketToken {
|
||||
return 'uncp8FvG310bEyYdV9MmStlo7KDRZ65fLWTeXCI2JzwPrNHjBqQhUiAgxsaO';
|
||||
}
|
||||
}
|
||||
546
lib/pages/claimprocess.dart
Normal file
@ -0,0 +1,546 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/tabs.dart';
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class claimprocess extends StatefulWidget {
|
||||
const claimprocess({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<claimprocess> createState() => _claimprocessState();
|
||||
}
|
||||
|
||||
class _claimprocessState extends State<claimprocess> {
|
||||
int _currentIndex = 0;
|
||||
bool isActive = true;
|
||||
dynamic _token;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
List<Map<String, String>> employeeDetails = [];
|
||||
dynamic argumentsData;
|
||||
|
||||
void _onTabChanged(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getActiveAndInactivePolicyDetails('Active');
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'phone');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getActiveAndInactivePolicyDetails(Status) async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getEmployeeActiveOrInactivePolicy?client_id=$client_id&emp_code=$empCodeString&type=$Status');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
if (data['status'] == 'success') {
|
||||
setState(() {
|
||||
policyList = data['data'];
|
||||
});
|
||||
// Assuming data is a List
|
||||
print(policyList);
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 0, bottom: 0, left: 0, right: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (!Responsive.isDesktop(context))
|
||||
Icon(
|
||||
Icons
|
||||
.chevron_left, // Replace with your desired icon
|
||||
color: Color(0xFF000000),
|
||||
size: 30,
|
||||
),
|
||||
SizedBox(
|
||||
width: Responsive.isDesktop(context)
|
||||
? 0
|
||||
: 5), // Adjust space between icon and text
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Health Insurance Claim Process',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Add more rows as needed
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Color(0xFFF6FAFF), // Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActive = true;
|
||||
policyList.clear();
|
||||
});
|
||||
getActiveAndInactivePolicyDetails(
|
||||
'Active');
|
||||
},
|
||||
child: isActive
|
||||
? Material(
|
||||
elevation: 5,
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.white,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 80
|
||||
: 40,
|
||||
vertical: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 12
|
||||
: 7),
|
||||
// primary: Color(0xFF000000),
|
||||
),
|
||||
child: Text(
|
||||
'Cashless Claim',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
color: Color(
|
||||
0xFF593AFF)),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Cashless Claim',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF636363),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActive = false;
|
||||
});
|
||||
},
|
||||
child: !isActive
|
||||
? Material(
|
||||
elevation: 5,
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.white,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 80
|
||||
: 40,
|
||||
vertical: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 12
|
||||
: 7),
|
||||
// primary: Color(0xFF000000),
|
||||
),
|
||||
child: Text(
|
||||
'Reimbursement Claims',
|
||||
style:
|
||||
GoogleFonts.poppins(
|
||||
fontSize: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
color:
|
||||
Color(0xFF593AFF),
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Reimbursement Claims',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF636363),
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
if (isActive)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'111 Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. Amet ut enim nisi in et sed ut feugiat pellentesque. Ultricies.',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. Amet ut enim nisi in et sed ut feugiat .',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. ',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. ',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
)
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!isActive)
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. Amet ut enim nisi in et sed ut feugiat pellentesque. Ultricies.',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. Amet ut enim nisi in et sed ut feugiat .',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. ',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet consectetur. Fames duis nulla etiam eu. ',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
]),
|
||||
)),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Add your onPressed logic here
|
||||
// },
|
||||
// child: Icon(Icons.add),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.centerDocked,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home,
|
||||
Icons.sticky_note_2_sharp,
|
||||
Icons.account_circle,
|
||||
Icons.help,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
],
|
||||
initialIndex: 1, // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
1972
lib/pages/claims.dart
Normal file
492
lib/pages/help.dart
Normal file
@ -0,0 +1,492 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/tabs.dart';
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class help extends StatefulWidget {
|
||||
const help({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<help> createState() => _helpState();
|
||||
}
|
||||
|
||||
class _helpState extends State<help> {
|
||||
int _currentIndex = 0;
|
||||
bool isActive = true;
|
||||
dynamic _token;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
List<Map<String, String>> employeeDetails = [];
|
||||
dynamic argumentsData;
|
||||
|
||||
void _onTabChanged(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getActiveAndInactivePolicyDetails('Active');
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'phone');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getActiveAndInactivePolicyDetails(Status) async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getEmployeeActiveOrInactivePolicy?client_id=$client_id&emp_code=$empCodeString&type=$Status');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
if (data['status'] == 'success') {
|
||||
setState(() {
|
||||
policyList = data['data'];
|
||||
});
|
||||
// Assuming data is a List
|
||||
print(policyList);
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 0, bottom: 0, left: 0, right: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/help.png',
|
||||
width: 300,
|
||||
height: 300,
|
||||
),
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
// Add more rows as needed
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: Color(0xFFD9D9D9), // Set the border color here
|
||||
width: 1.0, // Set the border width here
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0), // Set the border radius here
|
||||
),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors
|
||||
.white, // Set background color for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 11,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/tickets.png',
|
||||
width: 60,
|
||||
height: 60,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
10), // Adjust space between icon and text
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'No service request yet!',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth:
|
||||
250), // Adjust the maximum width as needed
|
||||
child: Text(
|
||||
'Please raise a service request, if you have any concerns with your policy.',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 14
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF777777),
|
||||
),
|
||||
softWrap:
|
||||
true, // Ensure text automatically wraps
|
||||
),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
])),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 75,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 20, bottom: 20, left: 30, right: 30)
|
||||
: EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10), // Add padding to the container
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Container(
|
||||
width: 300,
|
||||
height: 150,
|
||||
alignment: Alignment.center,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {},
|
||||
child: Text(
|
||||
'Raise a request',
|
||||
style: GoogleFonts.poppins(color: Colors.white),
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFFE26728),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
]),
|
||||
)),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Add your onPressed logic here
|
||||
// },
|
||||
// child: Icon(Icons.add),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.centerDocked,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home,
|
||||
Icons.sticky_note_2_sharp,
|
||||
Icons.account_circle,
|
||||
Icons.help,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
],
|
||||
initialIndex: 3, // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> generateCards(List<dynamic> data) {
|
||||
print('generateCards');
|
||||
print(data);
|
||||
return [
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 1,
|
||||
crossAxisSpacing: 20.0,
|
||||
mainAxisSpacing: 20.0,
|
||||
childAspectRatio: 10.5,
|
||||
),
|
||||
itemCount: data.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var item = data[index];
|
||||
String policyHeading = item['heading'];
|
||||
String policyName = item['policy_name'];
|
||||
String si_value = item['si_value'];
|
||||
String policyEndDate = item['policy_end_date'];
|
||||
List<dynamic> employeePolicy = item['EmployeePolicy'];
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'policies', arguments: item);
|
||||
},
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: Color(0xFFD9D9D9), // Set the border color here
|
||||
width: 1.0, // Set the border width here
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8.0), // Set the border radius here
|
||||
),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors
|
||||
.white, // Set background color for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Supplier',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF979797),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
policyName ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Cover Amount',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF979797),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'₹ $si_value',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.chevron_right, // Replace with your desired icon
|
||||
color: Color(0xFFE26728),
|
||||
size: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
])),
|
||||
));
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
807
lib/pages/home.dart
Normal file
@ -0,0 +1,807 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_image_slideshow/flutter_image_slideshow.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/tabs.dart';
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MyApp> createState() => _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
int _currentIndex = 0;
|
||||
bool isActive = true;
|
||||
dynamic _token;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
dynamic emp_name;
|
||||
|
||||
void _onTabChanged(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getActiveAndInactivePolicyDetails('Active');
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'phone');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getActiveAndInactivePolicyDetails(Status) async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getEmployeeActiveOrInactivePolicy?client_id=$client_id&emp_code=$empCodeString&type=$Status');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
if (data['status'] == 'success') {
|
||||
setState(() {
|
||||
policyList = data['data'];
|
||||
emp_name = data['emp_name'];
|
||||
});
|
||||
// Assuming data is a List
|
||||
print(policyList);
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
String formatToCroresLakhsAndThousands(String value) {
|
||||
double numValue = double.parse(value);
|
||||
|
||||
if (numValue >= 10000000) {
|
||||
// 1 crore is 10,000,000
|
||||
return "₹ ${(numValue / 10000000).toStringAsFixed(0)} Crores";
|
||||
} else if (numValue >= 100000) {
|
||||
// 1 lakh is 100,000
|
||||
return "₹ ${(numValue / 100000).toStringAsFixed(0)} Lakhs";
|
||||
} else if (numValue >= 1000) {
|
||||
// 1 thousand is 1,000
|
||||
return "₹ ${(numValue / 1000).toStringAsFixed(0)} Thousands";
|
||||
} else {
|
||||
return "₹ $numValue"; // This handles the case where value is less than 1 thousand
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Hello, $emp_name!',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 20
|
||||
: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Image.asset(
|
||||
'assets/emoji.png', // Replace 'path_to_your_image' with the actual path to your image asset
|
||||
width: 24, // Adjust the width as needed
|
||||
height: 24, // Adjust the height as needed
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 12 : 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF7A7A7A),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: ImageSlideshow(
|
||||
/// Width of the [ImageSlideshow].
|
||||
width: double.infinity,
|
||||
|
||||
/// Height of the [ImageSlideshow].
|
||||
height: Responsive.isDesktop(context) ? 200 : 130,
|
||||
|
||||
/// The page to show when first creating the [ImageSlideshow].
|
||||
initialPage: 0,
|
||||
|
||||
/// The color to paint the indicator.
|
||||
indicatorColor: Color(0xFFE26728),
|
||||
|
||||
/// The color to paint behind th indicator.
|
||||
indicatorBackgroundColor: Colors.grey,
|
||||
|
||||
/// The widgets to display in the [ImageSlideshow].
|
||||
/// Add the sample image file into the images folder
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/slider1.png',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Image.asset(
|
||||
'assets/slider2.png',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
Image.asset(
|
||||
'assets/slider3.png',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
],
|
||||
|
||||
/// Called whenever the page in the center of the viewport changes.
|
||||
onPageChanged: (value) {
|
||||
print('Page changed: $value');
|
||||
},
|
||||
|
||||
/// Auto scroll interval.
|
||||
/// Do not auto scroll with null or 0.
|
||||
autoPlayInterval: 3000,
|
||||
|
||||
/// Loops back to first slide.
|
||||
isLoop: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'Your Policies',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'Lorem ipsum dolor sit amet',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 12 : 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF7A7A7A),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Color(0xFFEEF5FF), // Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActive = true;
|
||||
policyList.clear();
|
||||
});
|
||||
getActiveAndInactivePolicyDetails(
|
||||
'Active');
|
||||
},
|
||||
child: isActive
|
||||
? Material(
|
||||
elevation: 5,
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.white,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 80
|
||||
: 40,
|
||||
vertical: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 12
|
||||
: 7),
|
||||
),
|
||||
child: Text(
|
||||
'Active',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
color: Color(
|
||||
0xFF593AFF)),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Active',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF636363),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
isActive = false;
|
||||
policyList.clear();
|
||||
});
|
||||
getActiveAndInactivePolicyDetails(
|
||||
'Inactive');
|
||||
},
|
||||
child: !isActive
|
||||
? Material(
|
||||
elevation: 5,
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.white,
|
||||
child: TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 80
|
||||
: 40,
|
||||
vertical: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 12
|
||||
: 7),
|
||||
// primary: Color(0xFF000000),
|
||||
),
|
||||
child: Text(
|
||||
'Inactive',
|
||||
style:
|
||||
GoogleFonts.poppins(
|
||||
fontSize: Responsive
|
||||
.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
color:
|
||||
Color(0xFF593AFF),
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Inactive',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF636363),
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
if (policyList != null && policyList.length > 0)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
...generateCards(policyList),
|
||||
],
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
]),
|
||||
)),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Add your onPressed logic here
|
||||
// },
|
||||
// child: Icon(Icons.add),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.miniCenterDocked,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home,
|
||||
Icons.sticky_note_2_sharp,
|
||||
Icons.account_circle,
|
||||
Icons.help,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
],
|
||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String getMemberNames(List<dynamic> employeePolicy) {
|
||||
List<String> names = [];
|
||||
for (var member in employeePolicy) {
|
||||
if (member['name'] != null) {
|
||||
names.add(member['name']);
|
||||
}
|
||||
}
|
||||
return names.join(' ~ ');
|
||||
}
|
||||
|
||||
List<Widget> generateCards(List<dynamic> data) {
|
||||
print('generateCards');
|
||||
print(data);
|
||||
return [
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: Responsive.isDesktop(context) ? 2 : 1,
|
||||
crossAxisSpacing: 20.0,
|
||||
mainAxisSpacing: 20.0,
|
||||
childAspectRatio: Responsive.isDesktop(context) ? 3.2 : 3.6,
|
||||
),
|
||||
itemCount: data.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var item = data[index];
|
||||
String policyHeading = item['heading'];
|
||||
String policyName = item['policy_name'];
|
||||
String si_value = item['si_value'];
|
||||
String policyEndDate = item['policy_end_date'];
|
||||
List<dynamic> employeePolicy = item['EmployeePolicy'];
|
||||
String memberNames = getMemberNames(employeePolicy);
|
||||
|
||||
DateTime parsedDate = DateFormat('dd-MMM-yyyy').parse(policyEndDate);
|
||||
String formattedDate = DateFormat('d MMM, yyyy').format(parsedDate);
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'policies', arguments: item);
|
||||
},
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: Card(
|
||||
elevation: 5,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(15.0), // Set border radius here
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, // Set background color to white
|
||||
borderRadius: BorderRadius.circular(
|
||||
15.0), // Set border radius for Container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 15, bottom: 15, left: 15, right: 15)
|
||||
: EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10), // Add padding to the container
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Icon(
|
||||
// Icons.circle,
|
||||
// size: 5, // Your icon here
|
||||
// color: Color(
|
||||
// 0xFF785EFF), // Customize the icon color if needed
|
||||
// ),
|
||||
// SizedBox(width: 5),
|
||||
Text(
|
||||
policyHeading ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 10
|
||||
: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF785EFF),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
'Expires on $formattedDate',
|
||||
textAlign: TextAlign.right,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 10
|
||||
: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF747474),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 8,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
policyName ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
formatToCroresLakhsAndThousands(
|
||||
si_value),
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
alignment:
|
||||
Alignment.centerRight,
|
||||
child: Icon(
|
||||
Icons.chevron_right,
|
||||
color: Color(
|
||||
0xFFE26728), // Replace with your desired icon
|
||||
size: Responsive.isDesktop(
|
||||
context)
|
||||
? 30
|
||||
: 26,
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
memberNames ?? '',
|
||||
textAlign: TextAlign.left,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 13,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
],
|
||||
))),
|
||||
// Expanded(
|
||||
// flex: 1,
|
||||
// child: Container(
|
||||
// alignment: Alignment.centerRight,
|
||||
// child: Center(
|
||||
// child: Icon(
|
||||
// Icons.chevron_right,
|
||||
// color: Color(
|
||||
// 0xFFE26728), // Replace with your desired icon
|
||||
// size:
|
||||
// Responsive.isDesktop(context) ? 30 : 24,
|
||||
// ),
|
||||
// ),
|
||||
// ))
|
||||
],
|
||||
),
|
||||
),
|
||||
)));
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
569
lib/pages/login.dart
Normal file
@ -0,0 +1,569 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter_animated_button/flutter_animated_button.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
|
||||
class login extends StatefulWidget {
|
||||
const login({Key? key});
|
||||
|
||||
@override
|
||||
State<login> createState() => _loginState();
|
||||
}
|
||||
|
||||
class _loginState extends State<login> {
|
||||
TextEditingController countryController = TextEditingController();
|
||||
TextEditingController mobileController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
countryController.text = "+91";
|
||||
super.initState();
|
||||
checkTokenAvailability();
|
||||
}
|
||||
|
||||
Future<void> checkTokenAvailability() async {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
|
||||
if (token != null && token.isNotEmpty) {
|
||||
// Token available, navigate to home page
|
||||
Navigator.pushReplacementNamed(context, 'home');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> verifyMobileNumber() async {
|
||||
try {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
// var enteredMobileNumber = countryController.text + mobileController.text;
|
||||
var enteredMobileNumber = mobileController.text;
|
||||
final response = await http.post(
|
||||
Uri.parse(Environment.apiUrl + 'verifyEmployeeNumber'),
|
||||
body: json.encode({'mobile_number': enteredMobileNumber}),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
bool userVerification = data['data']['user_verification'];
|
||||
String message = data['data']['message'];
|
||||
if (userVerification) {
|
||||
ToastHelper.showSuccessToast(context, message);
|
||||
Navigator.pushNamed(context, 'verify',
|
||||
arguments: enteredMobileNumber);
|
||||
} else {
|
||||
ToastHelper.showErrorToast(context, message);
|
||||
print('Invalid mobile number');
|
||||
}
|
||||
} else {
|
||||
ToastHelper.showErrorToast(context, 'Something went wrong');
|
||||
throw Exception('Failed to verify mobile number');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
ToastHelper.showErrorToast(context, 'Something went wrong');
|
||||
print('Error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size _size = MediaQuery.of(context).size;
|
||||
EdgeInsets marginInsets = EdgeInsets.zero;
|
||||
|
||||
if (Responsive.isDesktop(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
);
|
||||
} else if (Responsive.isMobile(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 25, // Example value for mobile
|
||||
right: 25, // Example value for mobile
|
||||
bottom: 0, // Example value for mobile
|
||||
top: 0, // Example value for mobile
|
||||
);
|
||||
} else if (Responsive.isTablet(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 25, //// Example value for mobile
|
||||
right: 25, // Example value for mobile
|
||||
bottom: 0, // Example value for mobile
|
||||
top: 0, // Example value for mobile
|
||||
);
|
||||
}
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
child: Container(
|
||||
height: _size.height,
|
||||
color: Colors.white,
|
||||
child: Stack(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: _size.width <= 1100,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(30),
|
||||
bottomRight: Radius.circular(30),
|
||||
),
|
||||
child: Container(
|
||||
height: _size.height / 3,
|
||||
width: double.infinity,
|
||||
color: Color(0xFFFFFCE5),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: _size.height /
|
||||
6.4), // Adjust the spacing between the rows
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.center, // Align to the center
|
||||
children: [
|
||||
Expanded(
|
||||
flex: Responsive.isDesktop(context) ? 10 : 12,
|
||||
child: Align(
|
||||
alignment: Responsive.isDesktop(context)
|
||||
? Alignment.centerLeft
|
||||
: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!Responsive.isMobile(context) &&
|
||||
!Responsive.isTablet(context))
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// Add your navigation logic here
|
||||
// For example, you can use Navigator.push to navigate to another page
|
||||
Navigator.pushNamed(
|
||||
context, 'hrLogin');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.end, // Align to the end (right)
|
||||
children: [
|
||||
Text(
|
||||
'HR Login',
|
||||
style: TextStyle(
|
||||
color: Color(
|
||||
0xFF000000), // Text color
|
||||
// Add other text styles as needed
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Icon(
|
||||
Icons
|
||||
.east, // Icon for customer login
|
||||
color: Colors
|
||||
.black, // Adjust color as needed
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: marginInsets,
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: _size.width < 1100 ? 6 : 12,
|
||||
child: Container(
|
||||
margin: _size.width > 1100
|
||||
? EdgeInsets.only(left: 20, right: 20)
|
||||
: EdgeInsets.only(left: 0, right: 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (!Responsive.isMobile(context) &&
|
||||
!Responsive.isTablet(context))
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Align(
|
||||
alignment: Responsive.isDesktop(
|
||||
context)
|
||||
? Alignment.centerLeft
|
||||
: Alignment
|
||||
.bottomCenter, // Align to the start
|
||||
child: _size.width <= 1100
|
||||
? Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
)
|
||||
: _size.width > 1100
|
||||
? Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
)
|
||||
: Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Welcome to Nhance",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Login with your mobile number and OTP to review and enroll for exciting health benefits for you and your family",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF000000)),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Container(
|
||||
height: 55,
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
width: 1, color: Colors.grey),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 40,
|
||||
child: TextField(
|
||||
controller: countryController,
|
||||
keyboardType:
|
||||
TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"|",
|
||||
style: TextStyle(
|
||||
fontSize: 33,
|
||||
color: Colors.grey),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: mobileController,
|
||||
keyboardType: TextInputType.phone,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText:
|
||||
"Enter your mobile number",
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null ||
|
||||
value.isEmpty) {
|
||||
return 'Please enter your mobile number';
|
||||
}
|
||||
if (value.length != 10) {
|
||||
return 'Mobile number must be 10 digits';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter
|
||||
.digitsOnly,
|
||||
LengthLimitingTextInputFormatter(
|
||||
10),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF00989E),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
onPressed: verifyMobileNumber,
|
||||
child: Text(
|
||||
"Login With OTP",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFFFFFFFF)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: _size.width <= 1100 ? 0 : 0,
|
||||
),
|
||||
_size.width > 1100
|
||||
? Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 150),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 30),
|
||||
Text(
|
||||
"Benefits of Login",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
))
|
||||
: SizedBox(),
|
||||
_size.width > 1100
|
||||
? Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 150),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(
|
||||
vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets
|
||||
.symmetric(
|
||||
vertical:
|
||||
12),
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
border: Border(
|
||||
right:
|
||||
BorderSide(
|
||||
width: 1,
|
||||
color: Colors
|
||||
.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.policy,
|
||||
color: Color(
|
||||
0xFFE26728)),
|
||||
SizedBox(
|
||||
height: 10),
|
||||
Text(
|
||||
"View Policy"),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets
|
||||
.symmetric(
|
||||
vertical:
|
||||
12),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.edit,
|
||||
color: Color(
|
||||
0xFFE26728)),
|
||||
SizedBox(
|
||||
height: 10),
|
||||
Text(
|
||||
"Manage Claims"),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
height:
|
||||
Responsive.isDesktop(context)
|
||||
? _size.height * 0.1
|
||||
: _size.height * 0.2,
|
||||
),
|
||||
SizedBox(
|
||||
height: _size.height * 0.1,
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 8),
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text:
|
||||
'By continuing, you agree with our ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black,
|
||||
fontSize: 9,
|
||||
),
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: 'privacy policy ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF00989E),
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'and ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black,
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'terms of use',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF00989E),
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_size.width > 1100)
|
||||
Expanded(
|
||||
flex: _size.width < 1100 ? 6 : 12,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context,
|
||||
BoxConstraints constraints) {
|
||||
if (constraints.maxWidth > 600) {
|
||||
return Image.asset(
|
||||
'assets/login_web.jpg',
|
||||
height: _size.height,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
} else {
|
||||
return SizedBox();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
994
lib/pages/policies.dart
Normal file
@ -0,0 +1,994 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:accordion/controllers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_image_slideshow/flutter_image_slideshow.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/tabs.dart';
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:accordion/accordion.dart';
|
||||
|
||||
class policies extends StatefulWidget {
|
||||
const policies({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<policies> createState() => _policiesState();
|
||||
}
|
||||
|
||||
class _policiesState extends State<policies> {
|
||||
int _currentIndex = 0;
|
||||
bool isActive = true;
|
||||
dynamic _token;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
List<Map<String, String>> employeeDetails = [];
|
||||
dynamic argumentsData;
|
||||
|
||||
void _onTabChanged(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getActiveAndInactivePolicyDetails('Active');
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'phone');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getActiveAndInactivePolicyDetails(Status) async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getEmployeeActiveOrInactivePolicy?client_id=$client_id&emp_code=$empCodeString&type=$Status');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
if (data['status'] == 'success') {
|
||||
setState(() {
|
||||
policyList = data['data'];
|
||||
});
|
||||
// Assuming data is a List
|
||||
print(policyList);
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
policyDataIsEmpty = 0;
|
||||
});
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
String convertDateFormat(String date) {
|
||||
// Define input and output date formats
|
||||
DateFormat inputFormat = DateFormat('dd-MMM-yyyy');
|
||||
DateFormat outputFormat = DateFormat('d MMM, yyyy');
|
||||
|
||||
// Parse the input date string
|
||||
DateTime parsedDate = inputFormat.parse(date);
|
||||
|
||||
// Format the parsed date to the desired output format
|
||||
String formattedDate = outputFormat.format(parsedDate);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
_launchURL(String ecardURL) async {
|
||||
if (await canLaunch(ecardURL)) {
|
||||
await launch(ecardURL);
|
||||
} else {
|
||||
print('Could not launch $ecardURL');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
dynamic arguments = ModalRoute.of(context)!.settings.arguments;
|
||||
print('arguments');
|
||||
print(arguments);
|
||||
if (arguments != null && arguments is Map<String, dynamic>) {
|
||||
argumentsData = arguments;
|
||||
if (argumentsData.containsKey('EmployeePolicy') &&
|
||||
argumentsData['EmployeePolicy'] is List) {
|
||||
// Clear the employeeDetails list to remove previous data
|
||||
employeeDetails.clear();
|
||||
// Iterate over each employee in the 'EmployeePolicy' list
|
||||
argumentsData['EmployeePolicy'].forEach((employee) {
|
||||
// Extract name and relationship and add to employeeDetails array
|
||||
String name = employee['name'];
|
||||
String relationship = employee['relationship'];
|
||||
employeeDetails.add({'name': name, 'relationship': relationship});
|
||||
});
|
||||
}
|
||||
print('employeeDetails');
|
||||
print(employeeDetails);
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(0),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color:
|
||||
Color(0xFFFFFCE5), // Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (!Responsive.isDesktop(context))
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
},
|
||||
child: Icon(
|
||||
Icons
|
||||
.chevron_left, // Replace with your desired icon
|
||||
color: Color(0xFF000000),
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 11,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
// Icon(
|
||||
// Icons
|
||||
// .subtitles, // Replace with your desired icon
|
||||
// color: Color(0xFFE26728),
|
||||
// size: 20,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width:
|
||||
// 3), // Adjust space between icon and text
|
||||
Text(
|
||||
'',
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 0 : 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Text(
|
||||
argumentsData['policy_name'] ?? '',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context) ? 20 : 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: Responsive.isDesktop(context)
|
||||
? 40
|
||||
: 20), // Space between rows
|
||||
Column(
|
||||
children: [
|
||||
Responsive.isDesktop(context)
|
||||
? buildDesktopLayout(context)
|
||||
: buildMobileLayout(context)
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: Responsive.isDesktop(context)
|
||||
? 40
|
||||
: 20), // Space between rows
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Expanded(
|
||||
// flex: Responsive.isDesktop(context) ? 4 : 6,
|
||||
// child: Container(
|
||||
// alignment: Alignment.center,
|
||||
// child: GestureDetector(
|
||||
// onTap: () {
|
||||
// setState(() {});
|
||||
// },
|
||||
// child: Material(
|
||||
// elevation: 0,
|
||||
// borderRadius: BorderRadius.circular(5),
|
||||
// color: Color(0xFFFFF8BF),
|
||||
// child: SizedBox(
|
||||
// width: Responsive.isDesktop(context)
|
||||
// ? 200
|
||||
// : 160,
|
||||
// child: TextButton(
|
||||
// onPressed: () {},
|
||||
// style: TextButton.styleFrom(
|
||||
// padding:
|
||||
// Responsive.isDesktop(context)
|
||||
// ? EdgeInsets.only(
|
||||
// top: 5,
|
||||
// bottom: 5,
|
||||
// left: 15,
|
||||
// right: 15)
|
||||
// : EdgeInsets.only(
|
||||
// top: 3,
|
||||
// bottom: 3,
|
||||
// left: 10,
|
||||
// right: 10)
|
||||
// // primary: Color(0xFF000000),
|
||||
// ),
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons
|
||||
// .download, // Replace with your desired icon
|
||||
// color: Color(0xFFE26728),
|
||||
// size:
|
||||
// Responsive.isDesktop(context)
|
||||
// ? 25
|
||||
// : 20,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// width:
|
||||
// 8), // Adjust space between icon and text
|
||||
// Text(
|
||||
// 'Download Policy',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: Responsive.isDesktop(
|
||||
// context)
|
||||
// ? 16
|
||||
// : 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Color(0xFF000000),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ))),
|
||||
// )),
|
||||
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {});
|
||||
},
|
||||
child: Material(
|
||||
elevation: 0,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: Color(0xFFFFF8BF),
|
||||
child: SizedBox(
|
||||
width: Responsive.isDesktop(context)
|
||||
? 200
|
||||
: 150,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
_launchURL(
|
||||
argumentsData['eCardDownload']);
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.only(
|
||||
top: 5,
|
||||
bottom: 5,
|
||||
left: 15,
|
||||
right: 15),
|
||||
// primary: Color(0xFF000000),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.subtitles, // Replace with your desired icon
|
||||
color: Color(0xFFE26728),
|
||||
size:
|
||||
Responsive.isDesktop(context)
|
||||
? 25
|
||||
: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
8), // Adjust space between icon and text
|
||||
Text(
|
||||
'E-Card',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(
|
||||
context)
|
||||
? 18
|
||||
: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
))),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () {},
|
||||
child: Material(
|
||||
elevation: 0,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: Color(0xFFFFF8BF),
|
||||
child: SizedBox(
|
||||
width: Responsive.isDesktop(context)
|
||||
? 200
|
||||
: 160,
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(
|
||||
context, 'claims');
|
||||
},
|
||||
style: TextButton.styleFrom(
|
||||
padding:
|
||||
Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 5,
|
||||
bottom: 5,
|
||||
left: 15,
|
||||
right: 15)
|
||||
: EdgeInsets.only(
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 10,
|
||||
right: 10)
|
||||
// primary: Color(0xFF000000),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.fact_check, // Replace with your desired icon
|
||||
color: Color(0xFFE26728),
|
||||
size:
|
||||
Responsive.isDesktop(context)
|
||||
? 25
|
||||
: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
8), // Adjust space between icon and text
|
||||
Text(
|
||||
'File a Claim',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(
|
||||
context)
|
||||
? 16
|
||||
: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
))),
|
||||
)),
|
||||
],
|
||||
),
|
||||
// Add more rows as needed
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 20 : 0),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
10), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(top: 0, bottom: 0, left: 0, right: 0)
|
||||
: EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Card(
|
||||
elevation: 4,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Color(
|
||||
0xFFECF2FF), // Set background color for the container
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(5),
|
||||
topRight: Radius.circular(
|
||||
5)), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 15, bottom: 15, left: 15, right: 15)
|
||||
: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Insured Members',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 14,
|
||||
color: Color(0xFF404040),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.all(30)
|
||||
: EdgeInsets.all(15),
|
||||
child: Column(
|
||||
children: employeeDetails.map((detail) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFBDBDBD),
|
||||
width:
|
||||
1.0, // Adjust the width as needed
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: 7,
|
||||
left: 7,
|
||||
right: 7),
|
||||
child: Text(
|
||||
detail['name']!,
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF000000),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
detail['relationship']!,
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF404040),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
])),
|
||||
SizedBox(height: 10),
|
||||
Accordion(
|
||||
headerBorderColor: Color(0xFFD9D9D9),
|
||||
headerBorderColorOpened: Color(0xFFD9D9D9),
|
||||
headerBorderWidth: 1,
|
||||
headerBackgroundColor: Colors.white,
|
||||
headerBackgroundColorOpened: Colors.white,
|
||||
contentBackgroundColor: Colors.white,
|
||||
contentBorderColor: Color(0xFFD9D9D9),
|
||||
contentBorderWidth: 1,
|
||||
contentHorizontalPadding: 20,
|
||||
scaleWhenAnimating: true,
|
||||
openAndCloseAnimation: true,
|
||||
headerPadding:
|
||||
EdgeInsets.symmetric(vertical: 15, horizontal: 15),
|
||||
sectionOpeningHapticFeedback: SectionHapticFeedback.heavy,
|
||||
sectionClosingHapticFeedback: SectionHapticFeedback.light,
|
||||
children: [
|
||||
AccordionSection(
|
||||
isOpen: false,
|
||||
contentVerticalPadding: 20,
|
||||
rightIcon: Icon(
|
||||
Icons.arrow_drop_down, // Custom arrow icon
|
||||
color: Color(
|
||||
0xFFE26728), // Set the color for the arrow icon
|
||||
size: 25,
|
||||
),
|
||||
leftIcon: Icon(
|
||||
Icons
|
||||
.switch_account, // Replace with your desired icon
|
||||
color: Color(0xFF855000),
|
||||
size: 25,
|
||||
),
|
||||
header: Text(
|
||||
'Policy coverage',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF404040),
|
||||
),
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: argumentsData['policy_terms']
|
||||
.entries
|
||||
.where((entry) => entry.value is String)
|
||||
.map<Widget>((entry) => Container(
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFD9D9D9),
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
entry.key,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF777777),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
entry.value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
)),
|
||||
]),
|
||||
Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: Color(0xFFD9D9D9), // Set the border color here
|
||||
width: 1.0, // Set the border width here
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8.0), // Set the border radius here
|
||||
),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// Set background color for the container
|
||||
borderRadius: BorderRadius.circular(
|
||||
5), // Set border radius for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 15, bottom: 15, left: 25, right: 25)
|
||||
: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.question_mark, // Replace with your desired icon
|
||||
color: Color(0xFF9B85B4),
|
||||
size: 25,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Need Help',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(context)
|
||||
? 14
|
||||
: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF404040),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, 'claims',
|
||||
arguments: 0);
|
||||
},
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.emoji_flags, // Replace with your desired icon
|
||||
color: Color(0xFF2CCEFE),
|
||||
size: 25,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'Claim history',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
Responsive.isDesktop(
|
||||
context)
|
||||
? 14
|
||||
: 10,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF404040),
|
||||
),
|
||||
),
|
||||
],
|
||||
))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
])),
|
||||
SizedBox(height: 10),
|
||||
Card(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: Color(0xFFD9D9D9), // Set the border color here
|
||||
width: 1.0, // Set the border width here
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8.0), // Set the border radius here
|
||||
),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors
|
||||
.white, // Set background color for the container
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 15, bottom: 15, left: 15, right: 15)
|
||||
: EdgeInsets.only(
|
||||
top: 10, bottom: 10, left: 10, right: 10),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.phonelink_ring, // Replace with your desired icon
|
||||
color: Color(0xFF038500),
|
||||
size: 25,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
10), // Adjust space between icon and text
|
||||
Text(
|
||||
'Cashless Hospitals',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 18
|
||||
: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF404040),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
])),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
)),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Add your onPressed logic here
|
||||
// },
|
||||
// child: Icon(Icons.add),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.centerDocked,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home,
|
||||
Icons.sticky_note_2_sharp,
|
||||
Icons.account_circle,
|
||||
Icons.help,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
], // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDesktopLayout(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
buildExpandedColumn(
|
||||
context, 'Cover Amount', '₹ ${argumentsData['si_value']}'),
|
||||
buildExpandedColumn(context, 'Policy No', argumentsData['policy_no']),
|
||||
buildExpandedColumn(context, 'Policy Expiry',
|
||||
convertDateFormat(argumentsData['policy_end_date'])),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildMobileLayout(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
buildExpandedColumn(
|
||||
context, 'Cover Amount', '₹ ${argumentsData['si_value']}'),
|
||||
buildExpandedColumn(
|
||||
context, 'Policy No', argumentsData['policy_no']),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
buildExpandedColumn(context, 'Policy Expiry',
|
||||
convertDateFormat(argumentsData['policy_end_date'])),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildExpandedColumn(BuildContext context, String title, String value) {
|
||||
return Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context) ? 18 : 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 10 : 5),
|
||||
Text(
|
||||
value,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context) ? 18 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
647
lib/pages/profile.dart
Normal file
@ -0,0 +1,647 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../customAppBar/customAppBar.dart';
|
||||
import '../customAppBar/customFooter.dart';
|
||||
import '../customAppBar/tabs.dart';
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class profile extends StatefulWidget {
|
||||
const profile({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<profile> createState() => _profileState();
|
||||
}
|
||||
|
||||
class _profileState extends State<profile> {
|
||||
int _currentIndex = 0;
|
||||
bool isActive = true;
|
||||
dynamic _token;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic client_id;
|
||||
dynamic policyList;
|
||||
dynamic policyDataIsEmpty = 1;
|
||||
dynamic policyHeading;
|
||||
dynamic policyName;
|
||||
dynamic EmployeePolicy;
|
||||
List<Map<String, String>> employeeDetails = [];
|
||||
dynamic argumentsData;
|
||||
dynamic selfRelationship;
|
||||
dynamic selfName;
|
||||
dynamic selfMobile;
|
||||
dynamic selfDesignation;
|
||||
dynamic selfDob;
|
||||
dynamic selfDoj;
|
||||
dynamic selfGender;
|
||||
dynamic selfEmailCorporate;
|
||||
dynamic selfEmailPersonal;
|
||||
dynamic selfEmpCode;
|
||||
dynamic selfFamilyFloaterKey;
|
||||
dynamic selfEmpStatus;
|
||||
|
||||
void _onTabChanged(int index) {
|
||||
setState(() {
|
||||
_currentIndex = index;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadToken();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _loadToken() async {
|
||||
print('_loadToken');
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
setState(() {
|
||||
_token = token;
|
||||
});
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||
print(decodedToken);
|
||||
empCodeString = prefs.getString('empCode');
|
||||
print(empCodeString); // Check if emp_code is correct
|
||||
empPrimaryId = prefs.getString('empPrimaryId');
|
||||
client_id = prefs.getString('client_id');
|
||||
print(client_id);
|
||||
getSelfEmployeeProfile();
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'login');
|
||||
}
|
||||
}
|
||||
|
||||
String convertDate(String dateString) {
|
||||
DateTime date = DateTime.parse(dateString);
|
||||
DateFormat formatter = DateFormat('dd MMMM, yyyy');
|
||||
return formatter.format(date);
|
||||
}
|
||||
|
||||
Future<void> getSelfEmployeeProfile() async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getEmployeeProfile?emp_code=$empCodeString&client_id=$client_id');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
// print('response.statusCode == 200');
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
// print(data);
|
||||
|
||||
if (data.containsKey('data')) {
|
||||
setState(() {
|
||||
dynamic selfDetails = data['data'];
|
||||
print(selfDetails);
|
||||
selfRelationship = selfDetails['relationship'];
|
||||
selfName = selfDetails['name'];
|
||||
selfMobile = selfDetails['mobile'];
|
||||
selfDesignation = selfDetails['designation'];
|
||||
selfDob = convertDate(selfDetails['dob']);
|
||||
selfDoj = convertDate(selfDetails['doj']);
|
||||
selfGender = selfDetails['gender'];
|
||||
selfEmailCorporate = selfDetails['email_corporate'];
|
||||
selfEmailPersonal = selfDetails['email_personal'];
|
||||
selfEmpCode = selfDetails['emp_code'];
|
||||
selfFamilyFloaterKey = selfDetails['family_floater_key'];
|
||||
// print(clientDetails);
|
||||
selfEmpStatus = selfDetails['emp_status'];
|
||||
});
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString('selfEmpStatus', selfEmpStatus);
|
||||
} else {
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> logout(BuildContext context) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.clear();
|
||||
Navigator.pushNamed(context, 'login');
|
||||
// Navigator.pushNamed(context, "phone");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(),
|
||||
body: Stack(children: [
|
||||
SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width *
|
||||
0.2, // 30% of screen width as horizontal padding
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0.03, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(10),
|
||||
color: Colors.white,
|
||||
child: Column(children: [
|
||||
if (selfName != null)
|
||||
Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (!Responsive.isDesktop(context))
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: EdgeInsets.only(top: 10, left: 10),
|
||||
child: Icon(
|
||||
Icons
|
||||
.chevron_left, // Replace with your desired icon
|
||||
color: Color(0xFF000000),
|
||||
size: 30,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: Responsive.isDesktop(context) ? 12 : 11,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// Adjust space between icon and text
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
AvatarDesign(
|
||||
gender:
|
||||
selfGender, // Replace with your image URL
|
||||
radius: 50.0,
|
||||
borderColor: Color(0xFFFEEDED),
|
||||
borderWidth: 4.0,
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
selfName ?? '',
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
RichText(
|
||||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: 'Emp: Id - ',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight
|
||||
.w600, // Bold style for "Emp: Id -"
|
||||
color: Color(0xFF000000),
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: selfEmpCode ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight
|
||||
.w400, // Normal style for the ID number
|
||||
color: Color(0xFF747474),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
// Add more rows as needed
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
if (selfName != null)
|
||||
Card(
|
||||
elevation: 5,
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.all(30)
|
||||
: EdgeInsets.all(15),
|
||||
child: Column(children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFBDBDBD),
|
||||
width: 1.0, // Adjust the width as needed
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: 7,
|
||||
left: 7,
|
||||
right: 7),
|
||||
child: Text(
|
||||
'Gender',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF777777),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
selfGender == 'M' ? 'Male' : 'Female',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF2D5A82),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFBDBDBD),
|
||||
width: 1.0, // Adjust the width as needed
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: 7,
|
||||
left: 7,
|
||||
right: 7),
|
||||
child: Text(
|
||||
'Date of birth',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF777777),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
selfDob ?? '',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF2D5A82),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFBDBDBD),
|
||||
width: 1.0, // Adjust the width as needed
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: 7,
|
||||
left: 7,
|
||||
right: 7),
|
||||
child: Text(
|
||||
'Phone No',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF777777),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
selfMobile ?? '',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF2D5A82),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Color(0xFFBDBDBD),
|
||||
width: 1.0, // Adjust the width as needed
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: Responsive.isDesktop(context)
|
||||
? EdgeInsets.only(
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
right: 10)
|
||||
: EdgeInsets.only(
|
||||
top: 7,
|
||||
bottom: 7,
|
||||
left: 7,
|
||||
right: 7),
|
||||
child: Text(
|
||||
'Email id',
|
||||
textAlign: TextAlign.start,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF777777),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
selfEmailCorporate ?? '',
|
||||
textAlign: TextAlign.end,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: Responsive.isDesktop(context)
|
||||
? 16
|
||||
: 12,
|
||||
color: Color(0xFF2D5A82),
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
]),
|
||||
)
|
||||
])),
|
||||
SizedBox(height: 12),
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 12,
|
||||
child: Container(
|
||||
width: 150,
|
||||
height: Responsive.isDesktop(context) ? 150 : 100,
|
||||
alignment: Alignment.center,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
logout(context);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.logout,
|
||||
color: Color(0xFFE26728),
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
8), // Adjust space between icon and text
|
||||
Text(
|
||||
'Logout',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFFE26728)),
|
||||
),
|
||||
],
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
side: BorderSide(color: Color(0xFFE26728)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
||||
]),
|
||||
)),
|
||||
if (Responsive.isDesktop(context))
|
||||
Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
width: double.infinity, // Make the footer full width
|
||||
child: CustomFooter(),
|
||||
),
|
||||
),
|
||||
]),
|
||||
// floatingActionButton: Responsive.isDesktop(context)
|
||||
// ? null
|
||||
// : FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Add your onPressed logic here
|
||||
// },
|
||||
// child: Icon(Icons.add),
|
||||
// ),
|
||||
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||
? null
|
||||
: FloatingActionButtonLocation.centerDocked,
|
||||
bottomNavigationBar: Responsive.isDesktop(context)
|
||||
? null
|
||||
: CustomBottomNavigationBar(
|
||||
onTabChanged: (index) {
|
||||
// Add your navigation logic here
|
||||
// For example:
|
||||
if (index == 0) {
|
||||
Navigator.pushNamed(context, 'home');
|
||||
} else if (index == 1) {
|
||||
Navigator.pushNamed(context, 'claims');
|
||||
} else if (index == 2) {
|
||||
Navigator.pushNamed(context, 'profile');
|
||||
} else if (index == 3) {
|
||||
Navigator.pushNamed(context, 'help');
|
||||
}
|
||||
},
|
||||
icons: [
|
||||
Icons.home,
|
||||
Icons.sticky_note_2_sharp,
|
||||
Icons.account_circle,
|
||||
Icons.help,
|
||||
],
|
||||
labels: [
|
||||
"Home",
|
||||
"Claim",
|
||||
"Profile",
|
||||
"Help",
|
||||
],
|
||||
initialIndex: 2, // Initial index of the bottom navigation bar
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarDesign extends StatelessWidget {
|
||||
final String gender;
|
||||
final double radius;
|
||||
final Color borderColor;
|
||||
final double borderWidth;
|
||||
|
||||
const AvatarDesign({
|
||||
Key? key,
|
||||
required this.gender,
|
||||
this.radius = 40.0,
|
||||
this.borderColor = Colors.white,
|
||||
this.borderWidth = 2.0,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Define URLs for male and female avatars
|
||||
final String maleAvatarUrl = 'assets/Male.png';
|
||||
final String femaleAvatarUrl = 'assets/Female.png';
|
||||
|
||||
// Select the appropriate avatar URL based on the gender
|
||||
final String avatarUrl = gender == 'M' ? maleAvatarUrl : femaleAvatarUrl;
|
||||
return Container(
|
||||
padding: EdgeInsets.all(borderWidth), // Add border width as padding
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: borderColor, // Border color
|
||||
),
|
||||
child: CircleAvatar(
|
||||
radius: radius,
|
||||
backgroundImage: NetworkImage(avatarUrl),
|
||||
backgroundColor: Color(
|
||||
0xFFFEEDED), // Background color in case the image fails to load
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
729
lib/pages/verify.dart
Normal file
@ -0,0 +1,729 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:pinput/pinput.dart';
|
||||
import 'dart:async';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:jwt_decode/jwt_decode.dart';
|
||||
|
||||
import '../customAppBar/responsive.dart';
|
||||
import '../customAppBar/toastHelper.dart';
|
||||
import '../models/environment.dart';
|
||||
|
||||
class MyVerify extends StatefulWidget {
|
||||
const MyVerify({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<MyVerify> createState() => _MyVerifyState();
|
||||
}
|
||||
|
||||
class _MyVerifyState extends State<MyVerify> {
|
||||
TextEditingController _otpController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
late Timer _timer;
|
||||
int _secondsRemaining = 30;
|
||||
bool _isTimerRunning = false;
|
||||
dynamic empCodeString;
|
||||
dynamic empPrimaryId;
|
||||
dynamic gpaEmpName;
|
||||
dynamic client_id;
|
||||
dynamic _token;
|
||||
dynamic clientName;
|
||||
dynamic clientLogo;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
checkTokenAvailability();
|
||||
// Start the timer when the widget is initialized
|
||||
startTimer();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void startTimer() {
|
||||
_isTimerRunning = true;
|
||||
_timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
|
||||
setState(() {
|
||||
if (_secondsRemaining > 0) {
|
||||
_secondsRemaining--;
|
||||
} else {
|
||||
_isTimerRunning = false;
|
||||
_timer.cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> checkTokenAvailability() async {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
final String? token = prefs.getString('token');
|
||||
|
||||
if (token != null && token.isNotEmpty) {
|
||||
// Token available, navigate to home page
|
||||
Navigator.pushReplacementNamed(context, 'home');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> resendOTP(String mobileNumber) async {
|
||||
print(mobileNumber);
|
||||
// Update the UI as needed
|
||||
setState(() {
|
||||
_secondsRemaining = 30;
|
||||
_isTimerRunning = true;
|
||||
});
|
||||
startTimer();
|
||||
try {
|
||||
final response = await http.post(
|
||||
Uri.parse(Environment.apiUrl + 'verifyEmployeeNumber'),
|
||||
body: json.encode({'mobile_number': mobileNumber}),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
// Handle successful response
|
||||
ToastHelper.showSuccessToast(context, 'OTP resent successfully');
|
||||
} else {
|
||||
// Handle other response status codes
|
||||
ToastHelper.showErrorToast(context, 'Failed to resend OTP');
|
||||
throw Exception('Failed to resend OTP');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle API call errors
|
||||
print('Error: $e');
|
||||
ToastHelper.showErrorToast(
|
||||
context, 'Failed to resend OTP. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
void verifyOTP(String otp) async {
|
||||
// Retrieve the passed mobile number value
|
||||
final String mobileNumber =
|
||||
ModalRoute.of(context)!.settings.arguments as String;
|
||||
try {
|
||||
final response = await http.post(
|
||||
Uri.parse(Environment.apiUrl + 'getVerifiedUserData'),
|
||||
body: json.encode({'mobile_number': mobileNumber, 'otp': otp}),
|
||||
headers: {
|
||||
HttpHeaders.contentTypeHeader: 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
print(data);
|
||||
_token = data['data'];
|
||||
String status = data['status'];
|
||||
print(status);
|
||||
if (status == 'success') {
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString('token', data['data']);
|
||||
|
||||
// Decode the JWT token received from the API response
|
||||
Map<String, dynamic>? decodedToken = Jwt.parseJwt(data['data']);
|
||||
print(decodedToken);
|
||||
empCodeString = decodedToken['emp_code'].toString();
|
||||
prefs.setString('empCode', empCodeString);
|
||||
empPrimaryId = decodedToken['id'];
|
||||
prefs.setString('empPrimaryId', empPrimaryId);
|
||||
gpaEmpName = decodedToken['name'].toString();
|
||||
prefs.setString('gpaEmpName', gpaEmpName);
|
||||
client_id = decodedToken['client_id'];
|
||||
prefs.setString('client_id', client_id);
|
||||
getClientLogoAndDetails();
|
||||
|
||||
print('Successfully Login');
|
||||
|
||||
// Redirect to another page
|
||||
final token = prefs.getString('token');
|
||||
if (token != null && token.isNotEmpty) {
|
||||
ToastHelper.showSuccessToast(context, 'Successfully Login');
|
||||
Navigator.pushReplacementNamed(context, 'home',
|
||||
arguments: {'mobile': ''});
|
||||
} else {
|
||||
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
|
||||
// For now, let's navigate to the login screen
|
||||
ToastHelper.showErrorToast(context, 'Session Out');
|
||||
Navigator.pushReplacementNamed(context, 'phone');
|
||||
}
|
||||
} else {
|
||||
ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
// Show a Snackbar if the OTP is invalid
|
||||
// ToastHelper.showErrorToast(context, 'Invalid OTP. Please try again');
|
||||
print('Invalid OTP. Please try again');
|
||||
}
|
||||
} else {
|
||||
ToastHelper.showWarningToast(context, 'Something went wrong');
|
||||
throw Exception('Failed to verify OTP');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error: $e');
|
||||
ToastHelper.showWarningToast(context, 'Something went wrong');
|
||||
// Show a Snackbar if there's an error while verifying OTP
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Failed to verify OTP. Please try again.');
|
||||
print('Failed to verify OTP. Please try again.');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getClientLogoAndDetails() async {
|
||||
var url = Uri.parse(Environment.apiUrl +
|
||||
'getClientDetails?client_id=$client_id&emp_code=$empCodeString');
|
||||
try {
|
||||
var response = await http.get(
|
||||
url,
|
||||
headers: {
|
||||
'Authorization':
|
||||
'Bearer $_token', // Add token to the Authorization header
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
// print('response.statusCode == 200');
|
||||
Map<String, dynamic> data = json.decode(response.body);
|
||||
// print(data);
|
||||
|
||||
if (data.containsKey('data')) {
|
||||
dynamic clientDetails = data['data'];
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
prefs.setString('clientLogo', clientDetails['client']['client_logo']);
|
||||
prefs.setString('clientName', clientDetails['client']['client_name']);
|
||||
setState(() {
|
||||
// dynamic clientDetails = data['data'];
|
||||
// print(clientDetails);
|
||||
clientName = clientDetails['client']['client_name'];
|
||||
print(clientName);
|
||||
clientLogo = clientDetails['client']['client_logo'];
|
||||
print(clientLogo);
|
||||
});
|
||||
} else {
|
||||
// Handle other status messages if needed
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'API request failed with status: ${data['status']}');
|
||||
print('API request failed with status: ${data['status']}');
|
||||
}
|
||||
} else {
|
||||
// Handle other status codes
|
||||
// ToastHelper.showErrorToast(
|
||||
// context, 'Request failed with status: ${response.statusCode}');
|
||||
print('Request failed with status: ${response.statusCode}');
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle exceptions
|
||||
print('Exception occurred: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Retrieve the passed mobile number value
|
||||
final String mobileNumber =
|
||||
ModalRoute.of(context)!.settings.arguments as String;
|
||||
Size _size = MediaQuery.of(context).size;
|
||||
EdgeInsets marginInsets = EdgeInsets.zero;
|
||||
if (Responsive.isDesktop(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
top: 0,
|
||||
);
|
||||
} else if (Responsive.isMobile(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 25, // Example value for mobile
|
||||
right: 25, // Example value for mobile
|
||||
bottom: 0, // Example value for mobile
|
||||
top: 0, // Example value for mobile
|
||||
);
|
||||
} else if (Responsive.isTablet(context)) {
|
||||
marginInsets = const EdgeInsets.only(
|
||||
left: 25, // Example value for mobile
|
||||
right: 25, // Example value for mobile
|
||||
bottom: 0, // Example value for mobile
|
||||
top: 0, // Example value for mobile
|
||||
);
|
||||
}
|
||||
final defaultPinTheme = PinTheme(
|
||||
width: 56,
|
||||
height: 56,
|
||||
textStyle: TextStyle(
|
||||
fontSize: 20,
|
||||
color: Color.fromRGBO(30, 60, 87, 1),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
);
|
||||
|
||||
final focusedPinTheme = defaultPinTheme.copyDecorationWith(
|
||||
border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
);
|
||||
|
||||
final submittedPinTheme = defaultPinTheme.copyWith(
|
||||
decoration: defaultPinTheme.decoration?.copyWith(
|
||||
color: Color.fromRGBO(234, 239, 243, 1),
|
||||
),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
child: Container(
|
||||
height: _size.height,
|
||||
color: Colors.white,
|
||||
child: Stack(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: _size.width <= 1100,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(30),
|
||||
bottomRight: Radius.circular(30),
|
||||
),
|
||||
child: Container(
|
||||
height: _size.height / 3,
|
||||
width: double.infinity,
|
||||
color: Color(0xFFFFFCE5),
|
||||
child: Stack(
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: _size.height /
|
||||
6.4), // Adjust the spacing between the rows
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.center, // Align to the center
|
||||
children: [
|
||||
Expanded(
|
||||
flex: Responsive.isDesktop(context) ? 10 : 12,
|
||||
child: Align(
|
||||
alignment: Responsive.isDesktop(context)
|
||||
? Alignment.centerLeft
|
||||
: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!Responsive.isMobile(context) &&
|
||||
!Responsive.isTablet(context))
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// Add your navigation logic here
|
||||
// For example, you can use Navigator.push to navigate to another page
|
||||
Navigator.pushNamed(
|
||||
context, 'hrLogin');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.end, // Align to the end (right)
|
||||
children: [
|
||||
Text(
|
||||
'HR Login',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(
|
||||
0xFF000000), // Text color
|
||||
// Add other text styles as needed
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Icon(
|
||||
Icons
|
||||
.east, // Icon for customer login
|
||||
color: Colors
|
||||
.black, // Adjust color as needed
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: marginInsets,
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: _size.width < 1100 ? 6 : 12,
|
||||
child: Container(
|
||||
margin: _size.width > 1100
|
||||
? EdgeInsets.only(left: 20, right: 20)
|
||||
: EdgeInsets.only(left: 0, right: 0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (!Responsive.isMobile(context) &&
|
||||
!Responsive.isTablet(context))
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 10,
|
||||
child: Align(
|
||||
alignment: Responsive.isDesktop(
|
||||
context)
|
||||
? Alignment.centerLeft
|
||||
: Alignment
|
||||
.bottomCenter, // Align to the start
|
||||
child: _size.width <= 1100
|
||||
? Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
)
|
||||
: _size.width > 1100
|
||||
? Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
)
|
||||
: Image.asset(
|
||||
'assets/nhance_app_logo.png',
|
||||
width: 150,
|
||||
height: 150,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"Welcome to Nhance",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text:
|
||||
"Please enter the one-time usage code sent to your mobile number $mobileNumber",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1.5,
|
||||
color: Color(0xFF000000)),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: " (Change Number)",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(
|
||||
0xFFE26728)), // Change color as desired
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// Navigate to the page where the user can change the phone number
|
||||
Navigator.pushNamed(
|
||||
context, 'phone');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Pinput(
|
||||
length: 6,
|
||||
// defaultPinTheme: defaultPinTheme,
|
||||
// focusedPinTheme: focusedPinTheme,
|
||||
// submittedPinTheme: submittedPinTheme,
|
||||
showCursor: true,
|
||||
controller: _otpController,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment
|
||||
.end, // Align text to the right
|
||||
children: [
|
||||
_isTimerRunning
|
||||
? Text(
|
||||
"Resend OTP in $_secondsRemaining seconds",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black),
|
||||
)
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
resendOTP(mobileNumber);
|
||||
},
|
||||
child: Text(
|
||||
"Resend OTP",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.blue),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
margin: Responsive.isDesktop(context)
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal: 150)
|
||||
: EdgeInsets.symmetric(horizontal: 0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF00989E),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!
|
||||
.validate()) {
|
||||
_formKey.currentState!
|
||||
.save(); // Save form fields before calling verifyOTP
|
||||
verifyOTP(_otpController.text);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
"Submit",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFFFFFFFF)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
_size.width > 1100
|
||||
? Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 150),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 20),
|
||||
Text(
|
||||
"Benefits of Login",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
))
|
||||
: SizedBox(),
|
||||
_size.width > 1100
|
||||
? Container(
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 150),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 6,
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(
|
||||
vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets
|
||||
.symmetric(
|
||||
vertical:
|
||||
12),
|
||||
decoration:
|
||||
BoxDecoration(
|
||||
border: Border(
|
||||
right:
|
||||
BorderSide(
|
||||
width: 1,
|
||||
color: Colors
|
||||
.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.policy,
|
||||
color: Color(
|
||||
0xFFE26728)),
|
||||
SizedBox(
|
||||
height: 10),
|
||||
Text(
|
||||
"View Policy",
|
||||
style: GoogleFonts
|
||||
.poppins()),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets
|
||||
.symmetric(
|
||||
vertical:
|
||||
12),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.edit,
|
||||
color: Color(
|
||||
0xFFE26728)),
|
||||
SizedBox(
|
||||
height: 10),
|
||||
Text(
|
||||
"Manage Claims",
|
||||
style: GoogleFonts
|
||||
.poppins()),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SizedBox(
|
||||
height:
|
||||
Responsive.isDesktop(context)
|
||||
? _size.height * 0.1
|
||||
: _size.height * 0.2,
|
||||
),
|
||||
SizedBox(
|
||||
height: _size.height * 0.1,
|
||||
),
|
||||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 8),
|
||||
child: RichText(
|
||||
textAlign: TextAlign.center,
|
||||
text: TextSpan(
|
||||
text:
|
||||
'By continuing, you agree with our ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black,
|
||||
fontSize: 9,
|
||||
),
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
text: 'privacy policy ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF00989E),
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'and ',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black,
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'terms of use',
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF00989E),
|
||||
fontSize: 9,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_size.width > 1100)
|
||||
Expanded(
|
||||
flex: _size.width < 1100 ? 6 : 12,
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context,
|
||||
BoxConstraints constraints) {
|
||||
if (constraints.maxWidth > 600) {
|
||||
return Image.asset(
|
||||
'assets/login_web.jpg',
|
||||
height: _size.height,
|
||||
fit: BoxFit.cover,
|
||||
);
|
||||
} else {
|
||||
return SizedBox();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
1
linux/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
flutter/ephemeral
|
||||
145
linux/CMakeLists.txt
Normal file
@ -0,0 +1,145 @@
|
||||
# Project-level configuration.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(runner LANGUAGES CXX)
|
||||
|
||||
# The name of the executable created for the application. Change this to change
|
||||
# the on-disk name of your application.
|
||||
set(BINARY_NAME "nhance_app_pwa")
|
||||
# The unique GTK application identifier for this application. See:
|
||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||
set(APPLICATION_ID "com.example.nhance_app_pwa")
|
||||
|
||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||
# versions of CMake.
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
|
||||
# Load bundled libraries from the lib/ directory relative to the binary.
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
|
||||
|
||||
# Root filesystem for cross-building.
|
||||
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
|
||||
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
endif()
|
||||
|
||||
# Define build configuration options.
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE
|
||||
STRING "Flutter build mode" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"Debug" "Profile" "Release")
|
||||
endif()
|
||||
|
||||
# Compilation settings that should be applied to most targets.
|
||||
#
|
||||
# Be cautious about adding new options here, as plugins use this function by
|
||||
# default. In most cases, you should add new options to specific targets instead
|
||||
# of modifying this function.
|
||||
function(APPLY_STANDARD_SETTINGS TARGET)
|
||||
target_compile_features(${TARGET} PUBLIC cxx_std_14)
|
||||
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
|
||||
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
|
||||
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
|
||||
endfunction()
|
||||
|
||||
# Flutter library and tool build rules.
|
||||
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
||||
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
||||
|
||||
# System-level dependencies.
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||
|
||||
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
|
||||
|
||||
# Define the application target. To change its name, change BINARY_NAME above,
|
||||
# not the value here, or `flutter run` will no longer work.
|
||||
#
|
||||
# Any new source files that you add to the application should be added here.
|
||||
add_executable(${BINARY_NAME}
|
||||
"main.cc"
|
||||
"my_application.cc"
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
)
|
||||
|
||||
# Apply the standard set of build settings. This can be removed for applications
|
||||
# that need different build settings.
|
||||
apply_standard_settings(${BINARY_NAME})
|
||||
|
||||
# Add dependency libraries. Add any application-specific dependencies here.
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
|
||||
|
||||
# Run the Flutter tool portions of the build. This must not be removed.
|
||||
add_dependencies(${BINARY_NAME} flutter_assemble)
|
||||
|
||||
# Only the install-generated bundle's copy of the executable will launch
|
||||
# correctly, since the resources must in the right relative locations. To avoid
|
||||
# people trying to run the unbundled copy, put it in a subdirectory instead of
|
||||
# the default top-level location.
|
||||
set_target_properties(${BINARY_NAME}
|
||||
PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
|
||||
)
|
||||
|
||||
|
||||
# Generated plugin build rules, which manage building the plugins and adding
|
||||
# them to the application.
|
||||
include(flutter/generated_plugins.cmake)
|
||||
|
||||
|
||||
# === Installation ===
|
||||
# By default, "installing" just makes a relocatable bundle in the build
|
||||
# directory.
|
||||
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
||||
endif()
|
||||
|
||||
# Start with a clean build bundle directory every time.
|
||||
install(CODE "
|
||||
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
|
||||
" COMPONENT Runtime)
|
||||
|
||||
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
||||
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
|
||||
install(FILES "${bundled_library}"
|
||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
endforeach(bundled_library)
|
||||
|
||||
# Copy the native assets provided by the build.dart from all packages.
|
||||
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/")
|
||||
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
|
||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
|
||||
# Fully re-copy the assets directory on each build to avoid having stale files
|
||||
# from a previous install.
|
||||
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
||||
install(CODE "
|
||||
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
|
||||
" COMPONENT Runtime)
|
||||
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
|
||||
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
|
||||
|
||||
# Install the AOT library on non-Debug builds only.
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
||||
COMPONENT Runtime)
|
||||
endif()
|
||||
88
linux/flutter/CMakeLists.txt
Normal file
@ -0,0 +1,88 @@
|
||||
# This file controls Flutter-level build steps. It should not be edited.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
||||
|
||||
# Configuration provided via flutter tool.
|
||||
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||
|
||||
# TODO: Move the rest of this into files in ephemeral. See
|
||||
# https://github.com/flutter/flutter/issues/57146.
|
||||
|
||||
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
|
||||
# which isn't available in 3.10.
|
||||
function(list_prepend LIST_NAME PREFIX)
|
||||
set(NEW_LIST "")
|
||||
foreach(element ${${LIST_NAME}})
|
||||
list(APPEND NEW_LIST "${PREFIX}${element}")
|
||||
endforeach(element)
|
||||
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# === Flutter Library ===
|
||||
# System-level dependencies.
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
|
||||
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
|
||||
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
|
||||
|
||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
|
||||
|
||||
# Published to parent scope for install step.
|
||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
|
||||
|
||||
list(APPEND FLUTTER_LIBRARY_HEADERS
|
||||
"fl_basic_message_channel.h"
|
||||
"fl_binary_codec.h"
|
||||
"fl_binary_messenger.h"
|
||||
"fl_dart_project.h"
|
||||
"fl_engine.h"
|
||||
"fl_json_message_codec.h"
|
||||
"fl_json_method_codec.h"
|
||||
"fl_message_codec.h"
|
||||
"fl_method_call.h"
|
||||
"fl_method_channel.h"
|
||||
"fl_method_codec.h"
|
||||
"fl_method_response.h"
|
||||
"fl_plugin_registrar.h"
|
||||
"fl_plugin_registry.h"
|
||||
"fl_standard_message_codec.h"
|
||||
"fl_standard_method_codec.h"
|
||||
"fl_string_codec.h"
|
||||
"fl_value.h"
|
||||
"fl_view.h"
|
||||
"flutter_linux.h"
|
||||
)
|
||||
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
|
||||
add_library(flutter INTERFACE)
|
||||
target_include_directories(flutter INTERFACE
|
||||
"${EPHEMERAL_DIR}"
|
||||
)
|
||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
|
||||
target_link_libraries(flutter INTERFACE
|
||||
PkgConfig::GTK
|
||||
PkgConfig::GLIB
|
||||
PkgConfig::GIO
|
||||
)
|
||||
add_dependencies(flutter flutter_assemble)
|
||||
|
||||
# === Flutter tool backend ===
|
||||
# _phony_ is a non-existent file to force this command to run every time,
|
||||
# since currently there's no way to get a full input/output list from the
|
||||
# flutter tool.
|
||||
add_custom_command(
|
||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/_phony_
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
${FLUTTER_TOOL_ENVIRONMENT}
|
||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
|
||||
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
|
||||
VERBATIM
|
||||
)
|
||||
add_custom_target(flutter_assemble DEPENDS
|
||||
"${FLUTTER_LIBRARY}"
|
||||
${FLUTTER_LIBRARY_HEADERS}
|
||||
)
|
||||
19
linux/flutter/generated_plugin_registrant.cc
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <smart_auth/smart_auth_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) smart_auth_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SmartAuthPlugin");
|
||||
smart_auth_plugin_register_with_registrar(smart_auth_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
}
|
||||
15
linux/flutter/generated_plugin_registrant.h
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Generated file. Do not edit.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
||||
#define GENERATED_PLUGIN_REGISTRANT_
|
||||
|
||||
#include <flutter_linux/flutter_linux.h>
|
||||
|
||||
// Registers Flutter plugins.
|
||||
void fl_register_plugins(FlPluginRegistry* registry);
|
||||
|
||||
#endif // GENERATED_PLUGIN_REGISTRANT_
|
||||
25
linux/flutter/generated_plugins.cmake
Normal file
@ -0,0 +1,25 @@
|
||||
#
|
||||
# Generated file, do not edit.
|
||||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
smart_auth
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
||||
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
||||
endforeach(plugin)
|
||||
|
||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
|
||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
||||
endforeach(ffi_plugin)
|
||||
6
linux/main.cc
Normal file
@ -0,0 +1,6 @@
|
||||
#include "my_application.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
g_autoptr(MyApplication) app = my_application_new();
|
||||
return g_application_run(G_APPLICATION(app), argc, argv);
|
||||
}
|
||||