├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ ├── flutter_export_environment.sh │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-50x50@1x.png │ │ │ ├── Icon-App-50x50@2x.png │ │ │ ├── Icon-App-57x57@1x.png │ │ │ ├── Icon-App-57x57@2x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-72x72@1x.png │ │ │ ├── Icon-App-72x72@2x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ └── contents.xcworkspacedata ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj └── .gitignore ├── assets ├── mec.png ├── icon.png └── icon2.png ├── android ├── app │ ├── steev.jks │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── drawable │ │ │ │ │ └── launch_background.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── mec │ │ │ │ │ └── attendance │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── key.properties ├── gradle.properties ├── .gitignore ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── README.md ├── .metadata ├── lib ├── Pages │ ├── ChooseDetails │ │ ├── Widgets │ │ │ ├── customRadio.dart │ │ │ ├── classToString.dart │ │ │ ├── selectClass.dart │ │ │ └── selectSemester.dart │ │ └── chooseDetails.dart │ ├── Attendance │ │ ├── Widgets │ │ │ ├── convertdata.dart │ │ │ ├── customAppbar.dart │ │ │ ├── getData.dart │ │ │ └── createList.dart │ │ └── attendancepage.dart │ ├── Splashscreen │ │ └── splashscreen.dart │ └── Timetable │ │ ├── timetable.dart │ │ └── Widgets │ │ └── singleDaySchedule.dart ├── main.dart ├── Theme │ └── theme.dart ├── Widgets │ └── fadeIn.dart └── NotificationHandler │ └── notifications.dart ├── .gitignore ├── pubspec.yaml └── pubspec.lock /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /assets/mec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/assets/mec.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/assets/icon.png -------------------------------------------------------------------------------- /assets/icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/assets/icon2.png -------------------------------------------------------------------------------- /android/app/steev.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/steev.jks -------------------------------------------------------------------------------- /android/key.properties: -------------------------------------------------------------------------------- 1 | storePassword=mykeystorepassword 2 | keyPassword=mykeystorepassword 3 | keyAlias=steev 4 | storeFile=steev.jks -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MEC Attendance & Timetable 2 | 3 | If it doesn't compile, use flutter version 1.17.0 4 | 5 | 6 | 7 | Feel free to make changes and submit PR's. 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steevjames/MEC-Attendance-Flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/mec/attendance/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.mec.attendance 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/Pages/ChooseDetails/Widgets/customRadio.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class CustomRadio extends StatelessWidget { 4 | final int value; 5 | final int groupValue; 6 | final Function handleChange; 7 | CustomRadio({this.value, this.groupValue, this.handleChange}); 8 | @override 9 | Widget build(BuildContext context) { 10 | return Radio( 11 | value: value, 12 | groupValue: groupValue, 13 | onChanged: handleChange, 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=D:\flutter" 4 | export "FLUTTER_APPLICATION_PATH=E:\MEC-Attendance-Flutter" 5 | export "FLUTTER_TARGET=lib\main.dart" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "SYMROOT=${SOURCE_ROOT}/../build\ios" 8 | export "OTHER_LDFLAGS=$(inherited) -framework Flutter" 9 | export "FLUTTER_FRAMEWORK_DIR=D:\flutter\bin\cache\artifacts\engine\ios" 10 | export "FLUTTER_BUILD_NAME=1.0.5" 11 | export "FLUTTER_BUILD_NUMBER=18" 12 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Pages/ChooseDetails/chooseDetails.dart'; 3 | import 'package:mec_attendance/Pages/Attendance/attendancepage.dart'; 4 | import 'package:mec_attendance/Pages/Splashscreen/splashscreen.dart'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | title: 'Attendance', 15 | theme: ThemeData( 16 | primarySwatch: Colors.blue, 17 | ), 18 | routes: { 19 | '/': (BuildContext context) => Splashscreen(), 20 | '/choose': (BuildContext context) => ChooseDetails(), 21 | '/attendance': (BuildContext context) => AttendancePage(), 22 | }, 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/Pages/ChooseDetails/Widgets/classToString.dart: -------------------------------------------------------------------------------- 1 | String classToString(_radioValue, _radioValue2) { 2 | String cls = ''; 3 | 4 | if (_radioValue.toString() == '0' || _radioValue.toString() == '1') { 5 | cls = cls + 'C'; 6 | cls = cls + _radioValue2.toString(); 7 | if (_radioValue.toString() == '0') 8 | cls = cls + 'A'; 9 | else 10 | cls = cls + 'B'; 11 | } 12 | if (_radioValue.toString() == '3' || _radioValue.toString() == '4') { 13 | cls = cls + 'E'; 14 | cls = cls + _radioValue2.toString(); 15 | if (_radioValue.toString() == '3') 16 | cls = cls + 'A'; 17 | else 18 | cls = cls + 'B'; 19 | } 20 | 21 | if (_radioValue.toString() == '2') { 22 | cls = 'EE' + _radioValue2.toString(); 23 | } 24 | 25 | if (_radioValue.toString() == '5') { 26 | cls = 'B' + _radioValue2.toString(); 27 | } 28 | return cls; 29 | } 30 | -------------------------------------------------------------------------------- /lib/Theme/theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // General 4 | 5 | String fontName = 'default'; 6 | Color maincolor = Color(0xFF2680C1); 7 | 8 | // Splash screen 9 | 10 | var splashGradientStart = Color(0xff2c9fc0); 11 | var splashGradientEnd = Color(0xff3464BB); 12 | 13 | // Attendance page 14 | 15 | Color gradientAppbarStart = Colors.cyan; 16 | Color gradientAppbarEnd = Colors.indigo; 17 | 18 | Color attendaneGradientStart = Color(0xff1c9fc0); 19 | Color attendaneGradientEnd = Color(0xff3464BB); 20 | 21 | Color gradientWhenUnderStart = Color(0xFF880000); 22 | Color gradientWhenUnderEnd = Color(0xFF880000); 23 | 24 | Color floatingButtonColor = Color(0xFF2c7ec4); 25 | Color pageBackgroundColor = Color(0xFFe7e7e7); 26 | 27 | // Timetable page 28 | 29 | Color gradientTimetableCircleStart = Color(0xFF19AAD5); 30 | Color gradientTimetableCircleEnd = Color(0xFF2680C1); 31 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/Widgets/fadeIn.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:simple_animations/simple_animations.dart'; 3 | 4 | class FadeIn extends StatelessWidget { 5 | final double delay; 6 | final Widget child; 7 | 8 | FadeIn({@required this.delay, @required this.child}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | final tween = MultiTrackTween([ 13 | Track("opacity") 14 | .add(Duration(milliseconds: 500), Tween(begin: 0.0, end: 1.0)), 15 | Track("translateX").add( 16 | Duration(milliseconds: 500), Tween(begin: 0.0, end: 0.0), 17 | curve: Curves.easeOut) 18 | ]); 19 | 20 | return ControlledAnimation( 21 | delay: Duration(milliseconds: (300 * delay).round()), 22 | // duration: tween.duration, 23 | duration: Duration(milliseconds: 150), 24 | tween: tween, 25 | child: child, 26 | builderWithChild: (context, child, animation) => Opacity( 27 | opacity: animation["opacity"], 28 | child: Transform.translate( 29 | offset: Offset(animation["translateX"], 0), child: child), 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mec_attendance 2 | description: An app for MECians to check their attendance. 3 | version: 1.0.5+18 4 | 5 | environment: 6 | sdk: ">=2.1.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | gradient_app_bar: ^0.1.3 12 | cupertino_icons: ^0.1.3 13 | http: ^0.12.1 14 | beautifulsoup: ^0.0.1 15 | shared_preferences: ^0.5.8 16 | url_launcher: ^5.5.0 17 | percent_indicator: ^2.1.5 18 | simple_animations: ^1.3.11 19 | onesignal_flutter: ^2.6.0 20 | 21 | 22 | dev_dependencies: 23 | flutter_test: 24 | sdk: flutter 25 | flutter_launcher_icons: "^0.7.2+1" 26 | 27 | flutter_icons: 28 | image_path: "assets/icon2.png" 29 | android: true 30 | ios: true 31 | 32 | 33 | flutter: 34 | 35 | # The following line ensures that the Material Icons font is 36 | uses-material-design: true 37 | 38 | # To add assets to your application, add an assets section, like this: 39 | assets: 40 | - assets/mec.png 41 | 42 | 43 | # fonts: 44 | # - family: poppins 45 | # fonts: 46 | # - asset: assets/fonts/Poppins-Regular.ttf 47 | # - family: avenir 48 | # fonts: 49 | # - asset: assets/fonts/font.ttf 50 | 51 | # - family: Trajan Pro 52 | # fonts: 53 | # - asset: fonts/TrajanPro.ttf 54 | # - asset: fonts/TrajanPro_Bold.ttf 55 | # weight: 700 56 | 57 | -------------------------------------------------------------------------------- /lib/Pages/Attendance/Widgets/convertdata.dart: -------------------------------------------------------------------------------- 1 | import 'package:beautifulsoup/beautifulsoup.dart'; 2 | 3 | // 1st Argument : Table, 2nd Argument : Required Row 4 | getTableRow(tablelist, row) { 5 | var tablelistdoc = Beautifulsoup(tablelist); 6 | var tablerows2 = 7 | tablelistdoc.find_all("tr").map((e) => (e.outerHtml)).toList(); 8 | var tablerows = ''; 9 | if (tablerows2.length > row) 10 | tablerows = tablerows2[row]; 11 | else 12 | tablerows = ''; 13 | var tabledoc = Beautifulsoup(tablerows).get_text(); 14 | var tabledoclist = tabledoc.split('\n'); 15 | for (int i = 0; i < tabledoclist.length; i++) 16 | tabledoclist[i] = tabledoclist[i].trim(); 17 | 18 | tabledoclist.removeWhere((value) => value == ''); 19 | return tabledoclist; 20 | } 21 | 22 | getTimeTableRow(tablelist, row) { 23 | var tablelistdoc = Beautifulsoup(tablelist); 24 | var tablerows2 = 25 | tablelistdoc.find_all("tr").map((e) => (e.outerHtml)).toList(); 26 | var tablerows = ''; 27 | if (tablerows2.length > row) 28 | tablerows = tablerows2[row]; 29 | else 30 | tablerows = ''; 31 | var tabledoc = Beautifulsoup(tablerows).get_text(); 32 | var tabledoclist = tabledoc.split('\n'); 33 | // for (int i = 0; i < tabledoclist.length; i++) 34 | // tabledoclist[i] = tabledoclist[i].trim(); 35 | 36 | // tabledoclist.removeWhere((value) => value == ''); 37 | return tabledoclist; 38 | } 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /lib/NotificationHandler/notifications.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | //import OneSignal 4 | import 'package:onesignal_flutter/onesignal_flutter.dart'; 5 | 6 | 7 | 8 | Future setUpNotifications() async { 9 | var notifs=[]; 10 | String _debugLabelString = ""; 11 | 12 | // bool _enableConsentButton = false; 13 | // if (!mounted) return; 14 | 15 | var settings = { 16 | OSiOSSettings.autoPrompt: false, 17 | OSiOSSettings.promptBeforeOpeningPushUrl: true 18 | }; 19 | 20 | OneSignal.shared 21 | .setNotificationReceivedHandler((OSNotification notification) { 22 | _debugLabelString = 23 | "Received notification: \n${notification.jsonRepresentation().replaceAll("\\n", "\n")}"; 24 | notifs.add(_debugLabelString); 25 | print('\n\n--------------------\n'+notifs.toString()+'\n\n\n-----------\n\n\n'); 26 | }); 27 | 28 | OneSignal.shared 29 | .setNotificationOpenedHandler((OSNotificationOpenedResult result) { 30 | _debugLabelString = 31 | "Opened notification: \n${result.notification.jsonRepresentation().replaceAll("\\n", "\n")}"; 32 | }); 33 | 34 | OneSignal.shared.setInAppMessageClickedHandler((OSInAppMessageAction action) { 35 | _debugLabelString = 36 | "In App Message Clicked: \n${action.jsonRepresentation().replaceAll("\\n", "\n")}"; 37 | }); 38 | 39 | // NOTE: Replace with your own app ID from https://www.onesignal.com 40 | await OneSignal.shared 41 | .init("39dbd0e1-985e-4af9-98ad-764bc9caa73f", iOSSettings: settings); 42 | 43 | OneSignal.shared 44 | .setInFocusDisplayType(OSNotificationDisplayType.notification); 45 | } 46 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | attendance 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/Pages/Splashscreen/splashscreen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/NotificationHandler/notifications.dart'; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | import 'package:mec_attendance/Theme/theme.dart'; 5 | 6 | class Splashscreen extends StatefulWidget { 7 | @override 8 | _SplashscreenState createState() => _SplashscreenState(); 9 | } 10 | 11 | class _SplashscreenState extends State { 12 | getDetailsFromStorage() async { 13 | SharedPreferences pref = await SharedPreferences.getInstance(); 14 | var classname = pref.getString('class'); 15 | var rollno2 = pref.getString('rollno'); 16 | if (classname == null || rollno2 == null) 17 | Navigator.pushReplacementNamed(context, '/choose'); 18 | else 19 | Navigator.pushReplacementNamed(context, '/attendance'); 20 | } 21 | 22 | @override 23 | void initState() { 24 | setUpNotifications(); 25 | Future.delayed(const Duration(milliseconds: 500), () { 26 | getDetailsFromStorage(); 27 | }); 28 | super.initState(); 29 | } 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return Center( 34 | child: Container( 35 | decoration: BoxDecoration( 36 | gradient: LinearGradient( 37 | begin: Alignment.topRight, 38 | end: Alignment.bottomLeft, 39 | stops: [0.1, 0.9], 40 | colors: [splashGradientStart, splashGradientEnd], 41 | ), 42 | ), 43 | child: Center( 44 | child: Image( 45 | image: AssetImage('assets/mec.png'), 46 | width: 225, 47 | color: Colors.white, 48 | ), 49 | ), 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/Pages/ChooseDetails/Widgets/selectClass.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Pages/ChooseDetails/Widgets/customRadio.dart'; 3 | import 'package:mec_attendance/Theme/theme.dart'; 4 | 5 | class SelectClass extends StatelessWidget { 6 | final int radioValue; 7 | final Function onRadio1Change; 8 | SelectClass({this.radioValue, this.onRadio1Change}); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | decoration: BoxDecoration( 13 | border: Border.all(width: 1.2, color: maincolor), 14 | ), 15 | margin: EdgeInsets.all(5.0), 16 | child: Column( 17 | children: [ 18 | Row( 19 | mainAxisAlignment: MainAxisAlignment.center, 20 | children: [ 21 | CustomRadio( 22 | value: 0, 23 | groupValue: radioValue, 24 | handleChange: onRadio1Change, 25 | ), 26 | Text('CSA'), 27 | CustomRadio( 28 | value: 1, 29 | groupValue: radioValue, 30 | handleChange: onRadio1Change, 31 | ), 32 | Text('CSB'), 33 | CustomRadio( 34 | value: 2, 35 | groupValue: radioValue, 36 | handleChange: onRadio1Change, 37 | ), 38 | Text('EEE'), 39 | ], 40 | ), 41 | Row( 42 | mainAxisAlignment: MainAxisAlignment.center, 43 | children: [ 44 | CustomRadio( 45 | value: 3, 46 | groupValue: radioValue, 47 | handleChange: onRadio1Change, 48 | ), 49 | Text('ECA'), 50 | CustomRadio( 51 | value: 4, 52 | groupValue: radioValue, 53 | handleChange: onRadio1Change, 54 | ), 55 | Text('ECB'), 56 | CustomRadio( 57 | value: 5, 58 | groupValue: radioValue, 59 | handleChange: onRadio1Change, 60 | ), 61 | Text('EB'), 62 | ], 63 | ), 64 | ], 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/Pages/Timetable/timetable.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gradient_app_bar/gradient_app_bar.dart'; 3 | import 'package:mec_attendance/Widgets/fadeIn.dart'; 4 | import 'package:mec_attendance/Theme/theme.dart'; 5 | import './Widgets/singleDaySchedule.dart'; 6 | 7 | class TimeTable extends StatefulWidget { 8 | final List timeTable; 9 | final classname; 10 | 11 | TimeTable({this.timeTable, this.classname}); 12 | 13 | @override 14 | _TimeTableState createState() => _TimeTableState(); 15 | } 16 | 17 | class _TimeTableState extends State 18 | with SingleTickerProviderStateMixin { 19 | @override 20 | Widget build(BuildContext context) { 21 | var timeTable = widget.timeTable; 22 | var classname = widget.classname; 23 | 24 | // print(timeTable); 25 | DateTime date = DateTime.now(); 26 | // 1 is Monday and 7 is Sunday. 27 | var day = date.weekday; 28 | //We convert it to day to 0 as Monday and so on 29 | day = day - 1; 30 | if (day > 4) day = 0; 31 | return DefaultTabController( 32 | initialIndex: day, 33 | length: 5, 34 | child: Scaffold( 35 | backgroundColor: Color(0xFFeeeeee), 36 | appBar: GradientAppBar( 37 | gradient: 38 | LinearGradient(colors: [gradientAppbarStart, gradientAppbarEnd]), 39 | bottom: TabBar( 40 | labelStyle: TextStyle(fontFamily: fontName), 41 | indicatorWeight: 3, 42 | indicatorColor: Colors.white, 43 | tabs: [ 44 | Tab( 45 | text: 'Mon', 46 | ), 47 | Tab( 48 | text: 'Tue', 49 | ), 50 | Tab( 51 | text: 'Wed', 52 | ), 53 | Tab( 54 | text: 'Thu', 55 | ), 56 | Tab( 57 | text: 'Fri', 58 | ), 59 | ], 60 | ), 61 | title: FadeIn( 62 | delay: .3, 63 | child: Text( 64 | classname + ' Timetable', 65 | style: TextStyle(fontFamily: fontName), 66 | ), 67 | ), 68 | centerTitle: true, 69 | ), 70 | body: Container( 71 | child: TabBarView( 72 | children: [ 73 | Schedule(timetable: timeTable[0], day: 0), 74 | Schedule(timetable: timeTable[1], day: 1), 75 | Schedule(timetable: timeTable[2], day: 2), 76 | Schedule(timetable: timeTable[3], day: 3), 77 | Schedule(timetable: timeTable[4], day: 4), 78 | ], 79 | ), 80 | ), 81 | ), 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/Pages/ChooseDetails/Widgets/selectSemester.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Pages/ChooseDetails/Widgets/customRadio.dart'; 3 | import 'package:mec_attendance/Theme/theme.dart'; 4 | 5 | class SelectSemester extends StatelessWidget { 6 | final int radioValue; 7 | final Function onRadio2Change; 8 | SelectSemester({this.radioValue, this.onRadio2Change}); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | decoration: BoxDecoration( 13 | border: Border.all(width: 1.2, color: maincolor), 14 | ), 15 | margin: EdgeInsets.all(5.0), 16 | alignment: Alignment.center, 17 | width: double.infinity, 18 | child: Column( 19 | children: [ 20 | Row( 21 | mainAxisAlignment: MainAxisAlignment.center, 22 | children: [ 23 | CustomRadio( 24 | value: 1, 25 | groupValue: radioValue, 26 | handleChange: onRadio2Change, 27 | ), 28 | Text('1'), 29 | CustomRadio( 30 | value: 2, 31 | groupValue: radioValue, 32 | handleChange: onRadio2Change, 33 | ), 34 | Text('2'), 35 | CustomRadio( 36 | value: 3, 37 | groupValue: radioValue, 38 | handleChange: onRadio2Change, 39 | ), 40 | Text('3'), 41 | CustomRadio( 42 | value: 4, 43 | groupValue: radioValue, 44 | handleChange: onRadio2Change, 45 | ), 46 | Text('4'), 47 | ], 48 | ), 49 | Row( 50 | mainAxisAlignment: MainAxisAlignment.center, 51 | children: [ 52 | CustomRadio( 53 | value: 5, 54 | groupValue: radioValue, 55 | handleChange: onRadio2Change, 56 | ), 57 | Text('5'), 58 | CustomRadio( 59 | value: 6, 60 | groupValue: radioValue, 61 | handleChange: onRadio2Change, 62 | ), 63 | Text('6'), 64 | CustomRadio( 65 | value: 7, 66 | groupValue: radioValue, 67 | handleChange: onRadio2Change, 68 | ), 69 | Text('7'), 70 | CustomRadio( 71 | value: 8, 72 | groupValue: radioValue, 73 | handleChange: onRadio2Change, 74 | ), 75 | Text('8'), 76 | ], 77 | ), 78 | ], 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | // Adding For OneSignal 2 | buildscript { 3 | repositories { 4 | // ... 5 | maven { url 'https://plugins.gradle.org/m2/' } // Gradle Plugin Portal 6 | } 7 | dependencies { 8 | // ... 9 | // OneSignal-Gradle-Plugin 10 | classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.1, 0.99.99]' 11 | } 12 | } 13 | 14 | repositories { 15 | maven { url 'https://maven.google.com' } 16 | } 17 | 18 | apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin' 19 | 20 | // One Signal End 21 | 22 | 23 | def localProperties = new Properties() 24 | def localPropertiesFile = rootProject.file('local.properties') 25 | if (localPropertiesFile.exists()) { 26 | localPropertiesFile.withReader('UTF-8') { reader -> 27 | localProperties.load(reader) 28 | } 29 | } 30 | 31 | def flutterRoot = localProperties.getProperty('flutter.sdk') 32 | if (flutterRoot == null) { 33 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 34 | } 35 | 36 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 37 | if (flutterVersionCode == null) { 38 | flutterVersionCode = '1' 39 | } 40 | 41 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 42 | if (flutterVersionName == null) { 43 | flutterVersionName = '1.0' 44 | } 45 | 46 | apply plugin: 'com.android.application' 47 | apply plugin: 'kotlin-android' 48 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 49 | 50 | 51 | def keystoreProperties = new Properties() 52 | def keystorePropertiesFile = rootProject.file('key.properties') 53 | if (keystorePropertiesFile.exists()) { 54 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 55 | } 56 | 57 | 58 | android { 59 | compileSdkVersion 30 60 | 61 | sourceSets { 62 | main.java.srcDirs += 'src/main/kotlin' 63 | } 64 | 65 | lintOptions { 66 | disable 'InvalidPackage' 67 | } 68 | 69 | defaultConfig { 70 | manifestPlaceholders = [ 71 | onesignal_app_id: '39dbd0e1-985e-4af9-98ad-764bc9caa73f', 72 | // Project number pulled from dashboard, local value is ignored. 73 | onesignal_google_project_number: 'REMOTE' 74 | ] 75 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 76 | applicationId "com.mec.attendance" 77 | minSdkVersion 16 78 | targetSdkVersion 30 79 | versionCode flutterVersionCode.toInteger() 80 | versionName flutterVersionName 81 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 82 | } 83 | 84 | signingConfigs { 85 | release { 86 | keyAlias keystoreProperties['keyAlias'] 87 | keyPassword keystoreProperties['keyPassword'] 88 | storeFile file(keystoreProperties['storeFile']) 89 | storePassword keystoreProperties['storePassword'] 90 | } 91 | } 92 | buildTypes { 93 | release { 94 | signingConfig signingConfigs.release 95 | 96 | } 97 | } 98 | } 99 | 100 | flutter { 101 | source '../..' 102 | } 103 | 104 | dependencies { 105 | implementation 'com.onesignal:OneSignal:[3.13.0, 3.99.99]' // One Signal 106 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 107 | testImplementation 'junit:junit:4.12' 108 | androidTestImplementation 'androidx.test:runner:1.1.1' 109 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 110 | } 111 | -------------------------------------------------------------------------------- /lib/Pages/Attendance/Widgets/customAppbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Theme/theme.dart'; 3 | import 'package:url_launcher/url_launcher.dart'; 4 | import 'package:gradient_app_bar/gradient_app_bar.dart'; 5 | 6 | dialogWithContent({@required context}) { 7 | showDialog( 8 | useRootNavigator: false, 9 | context: context, 10 | builder: (context) { 11 | return AlertDialog( 12 | content: Column( 13 | mainAxisSize: MainAxisSize.min, 14 | children: [ 15 | Text( 16 | "This app was developed using Flutter by Steev James of CSA 2021 batch. The app gets data from the college attendance website to and shows processed data to the user. Currently looking for someone to maintain the app. To contact the developer, use the link below", 17 | style: TextStyle( 18 | color: Colors.black54, 19 | fontSize: 14, 20 | ), 21 | textAlign: TextAlign.center, 22 | ), 23 | SizedBox(height: 15), 24 | Row( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | children: [ 27 | RaisedButton( 28 | child: Text("Contact"), 29 | shape: RoundedRectangleBorder( 30 | borderRadius: BorderRadius.circular(7), 31 | ), 32 | color: Color(0xFF2c7ec4), 33 | visualDensity: VisualDensity.compact, 34 | textColor: Colors.white, 35 | onPressed: () { 36 | launch("https://wa.me/919539415481"); 37 | }), 38 | SizedBox(width: 20), 39 | RaisedButton( 40 | child: Text("Source code"), 41 | shape: RoundedRectangleBorder( 42 | borderRadius: BorderRadius.circular(7), 43 | ), 44 | color: Color(0xFF2c7ec4), 45 | visualDensity: VisualDensity.compact, 46 | textColor: Colors.white, 47 | onPressed: () { 48 | launch( 49 | "https://github.com/steevjames/MEC-Attendance-Flutter"); 50 | }) 51 | ], 52 | ) 53 | ], 54 | ), 55 | ); 56 | }); 57 | } 58 | 59 | customAppbar({classname, onbackbutton, studname, context}) { 60 | _launchURL(url) async { 61 | // if (await canLaunch(url) && url != '') { 62 | await launch(url); 63 | // } else { 64 | // throw 'Could not launch $url'; 65 | // } 66 | } 67 | 68 | return GradientAppBar( 69 | actions: [ 70 | PopupMenuButton( 71 | onSelected: (val) { 72 | // if (val == 1) 73 | // _launchURL( 74 | // 'mailto:steevjames11@gmail.com?subject=[MEC Attendance Bug/Suggestion Submission]'); 75 | // else 76 | if (val == 2) 77 | _launchURL( 78 | 'http://attendance.mec.ac.in/view4stud.php?class=' + classname); 79 | else if (val == 3) 80 | _launchURL( 81 | 'https://play.google.com/store/apps/details?id=com.mec.attendance'); 82 | else if (val == 4) dialogWithContent(context: context); 83 | }, 84 | itemBuilder: (BuildContext context) => [ 85 | PopupMenuItem( 86 | value: 2, 87 | child: Text( 88 | 'View on Site', 89 | style: TextStyle(fontFamily: fontName, fontSize: 14), 90 | ), 91 | ), 92 | PopupMenuItem( 93 | value: 4, 94 | child: Text( 95 | 'About ', 96 | style: TextStyle(fontFamily: fontName, fontSize: 14), 97 | ), 98 | ), 99 | PopupMenuItem( 100 | value: 3, 101 | child: Text( 102 | 'Find on Google Play', 103 | style: TextStyle(fontFamily: fontName, fontSize: 14), 104 | ), 105 | ), 106 | ], 107 | ) 108 | ], 109 | // Back button on appbar 110 | leading: IconButton( 111 | icon: Icon(Icons.arrow_back), 112 | onPressed: onbackbutton, 113 | ), 114 | centerTitle: true, 115 | // Title of page 116 | title: Text( 117 | studname, 118 | style: TextStyle(fontSize: 19.0, fontFamily: fontName), 119 | ), 120 | gradient: LinearGradient(colors: [gradientAppbarStart, gradientAppbarEnd]), 121 | ); 122 | } 123 | -------------------------------------------------------------------------------- /lib/Pages/Attendance/Widgets/getData.dart: -------------------------------------------------------------------------------- 1 | import 'package:beautifulsoup/beautifulsoup.dart'; 2 | import 'package:http/http.dart' as http; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | import 'dart:convert'; 5 | import 'convertdata.dart'; 6 | 7 | class FetchData { 8 | var rollno = 0; 9 | var classname = ''; 10 | var studname = "Attendance"; 11 | var timeTable = []; 12 | var noOfClassesList = []; 13 | var subjectAndLastUpdated; 14 | var noOfSubjects; 15 | var studentattendance = []; 16 | 17 | // Fetch Data from the Site 18 | getData() async { 19 | print("Trying to get Data"); 20 | 21 | // Data from storage 22 | SharedPreferences pref = await SharedPreferences.getInstance(); 23 | var classname = pref.getString('class'); 24 | var rollno2 = pref.getString('rollno'); 25 | rollno = int.parse(rollno2); 26 | // print(timeTable); 27 | print('--- Got Data from Storage ---'); 28 | 29 | var response = await fetchDataFromNet(classname); 30 | var soup = Beautifulsoup(response.body.toString()); 31 | // Converts fetched Data. 32 | convertData(soup); 33 | // Replaces loading with attendance list. 34 | print('--- Got Data from Website ---'); 35 | 36 | return { 37 | "rollno": rollno, 38 | "classname": classname, 39 | "timeTable": timeTable, 40 | "noOfClassesList": noOfClassesList, 41 | "subjectAndLastUpdated": subjectAndLastUpdated, 42 | "noOfSubjects": noOfSubjects, 43 | "studentattendance": studentattendance 44 | }; 45 | } 46 | 47 | // Fetches data from net. 48 | fetchDataFromNet(classname) async { 49 | try { 50 | http.Response response = await http 51 | .get('http://attendance.mec.ac.in/view4stud.php?class=' + classname); 52 | 53 | return response; 54 | } catch (_) { 55 | return await Future.delayed(const Duration(seconds: 2), () { 56 | return fetchDataFromNet(classname); 57 | }); 58 | } 59 | } 60 | 61 | // ------------------------------------------------------------------------------ 62 | // 63 | // THE FOLLOWING CODE CONVERTS THE DATA FETCHED FROM WEBSITE TO USUABLE DATA. 64 | // IT USES THE BEUTIFUL SOUP PACKAGE TO DETECT HTML TAGS. 65 | // TRY PRINTING VARIABLES AT ANY INSTANT TO SEE WHAT IS BEING CHANGED. 66 | // 67 | //------------------------------------------------------------------------------ 68 | // Turns Fetched page to Required Data. 69 | convertData(soup) { 70 | // tablelist stores HTML code of all the tables in the page as list of string. 71 | // tablelist[0] stores first table, that is, the one with all student names & attendance. 72 | // tablelist[1] stores the table with Subject name & Last updated. 73 | // tablelist[2] stores the last table, that is, the one with timetable. 74 | var tablelist = soup.find_all("table").map((e) => (e.outerHtml)).toList(); 75 | studentattendance = getTableRow(tablelist[0], rollno + 1); 76 | if (studentattendance.length != 0) studentattendance.removeAt(0); 77 | noOfSubjects = studentattendance.length; 78 | subjectAndLastUpdated = []; 79 | for (int i = 0; i < noOfSubjects; i++) { 80 | subjectAndLastUpdated.add(getTableRow(tablelist[1], i)); 81 | } 82 | if (subjectAndLastUpdated.length != 0) subjectAndLastUpdated.removeAt(0); 83 | 84 | // Get first row to calculate number of classes finished. 85 | var firstrow = getTableRow(tablelist[0], 0); 86 | if (firstrow.length != 0) firstrow.removeAt(0); 87 | if (firstrow.length != 0) firstrow.removeAt(0); 88 | for (int i = 0; i < firstrow.length; i++) { 89 | var classno = firstrow[i].split('(')[1].split(')')[0]; 90 | var str = firstrow[i].substring(6); 91 | str = str.substring(0, str.length - 1); 92 | // noOfClassesList.add(int.parse(str)); 93 | noOfClassesList.add(int.parse(classno)); 94 | } 95 | // print(noOfClassesList); 96 | 97 | timeTable = []; 98 | 99 | //Getting Time Table 100 | for (int i = 0; i < 7; i++) { 101 | timeTable.add(getTimeTableRow(tablelist[2], i)); 102 | } 103 | timeTable.removeAt(0); 104 | timeTable.removeAt(0); 105 | for (int i = 0; i < timeTable.length; i++) { 106 | for (int j = 3; j < timeTable[i].length; j++) { 107 | timeTable[i].removeAt(j); 108 | } 109 | } 110 | 111 | //Removes Spaces from Time Table 112 | for (int i = 0; i < timeTable.length; i++) { 113 | for (int j = 0; j < timeTable[i].length; j++) { 114 | // print(timeTable[i][j].trim()); 115 | timeTable[i][j] = timeTable[i][j].trim() + ' '; 116 | } 117 | timeTable[i].removeAt(0); 118 | timeTable[i].removeLast(); 119 | } 120 | //Removes blank Elements from Time Table 121 | for (int i = 0; i < timeTable.length; i++) { 122 | timeTable[i].removeWhere((value) => value == ''); 123 | } 124 | 125 | // Saves timetable to apps storage space to make available offline. 126 | savetimetable() async { 127 | SharedPreferences pref = await SharedPreferences.getInstance(); 128 | pref.setString('timetable', json.encode(timeTable)); 129 | } 130 | 131 | savetimetable(); 132 | 133 | // print(studentattendance); 134 | // print(subjectAndLastUpdated); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /lib/Pages/Timetable/Widgets/singleDaySchedule.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Widgets/fadeIn.dart'; 3 | import 'package:mec_attendance/Theme/theme.dart'; 4 | 5 | class Schedule extends StatelessWidget { 6 | final timetable; 7 | final int day; 8 | Schedule({this.timetable, this.day}); 9 | // Here Timetable is list of periods that day. 10 | @override 11 | Widget build(BuildContext context) { 12 | // print(timetable); 13 | var ttcopy = []..addAll(timetable); 14 | ttcopy.removeAt(0); 15 | 16 | // Checks for course code in name & removes it, Makes it title case 17 | for (int i = 0; i < ttcopy.length; i++) { 18 | // if (ttcopy[i].split(' ')[0].contains('0') || 19 | // ttcopy[i].split(' ')[0].contains('1') || 20 | // ttcopy[i].split(' ')[0].contains('2') || 21 | // ttcopy[i].split(' ')[0].contains('3') || 22 | // ttcopy[i].split(' ')[0].contains('4')) 23 | int lastNumIndex = 0; 24 | for (int j = 0; j < ttcopy[i].length; j++) { 25 | if (int.tryParse(ttcopy[i][j]) != null) lastNumIndex = j; 26 | } 27 | 28 | ttcopy[i] = ttcopy[i].substring(lastNumIndex + 1); 29 | // ttcopy[i] = ttcopy[i].substring(ttcopy[i].indexOf(" ") + 1); 30 | 31 | try { 32 | ttcopy[i] = ttcopy[i] 33 | .trim() 34 | .toLowerCase() 35 | .split(' ') 36 | .map((s) => s[0].toUpperCase() + s.substring(1)) 37 | .join(' '); 38 | } catch (_) {} 39 | } 40 | 41 | return SingleChildScrollView( 42 | child: Column( 43 | crossAxisAlignment: CrossAxisAlignment.stretch, 44 | children: [ 45 | SizedBox( 46 | height: 25.0, 47 | ), 48 | ] + 49 | // listofperiods + 50 | List.generate( 51 | ttcopy.length, 52 | (i) => FadeIn( 53 | delay: i / 6.0 + .2, 54 | child: Container( 55 | margin: EdgeInsets.fromLTRB(10, 0, 15, 2), 56 | padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 3.0), 57 | child: Container( 58 | decoration: BoxDecoration( 59 | color: Colors.white, 60 | boxShadow: [ 61 | BoxShadow( 62 | color: Color(0xffaaaaaa), 63 | blurRadius: 3.0, 64 | spreadRadius: -1.0, 65 | ) 66 | ], 67 | borderRadius: BorderRadius.only( 68 | topLeft: Radius.circular(100), 69 | bottomLeft: Radius.circular(100), 70 | topRight: Radius.circular(40), 71 | bottomRight: Radius.circular(40), 72 | ), 73 | ), 74 | child: Row( 75 | crossAxisAlignment: CrossAxisAlignment.center, 76 | children: [ 77 | // Period Number 78 | Container( 79 | margin: EdgeInsets.fromLTRB(0, 0, 5, 0), 80 | width: 50.0, 81 | height: 50.0, 82 | decoration: BoxDecoration( 83 | shape: BoxShape.circle, 84 | color: Color(0xFF19AAD5), 85 | gradient: LinearGradient( 86 | begin: Alignment.topLeft, 87 | end: Alignment.topRight, 88 | stops: [ 89 | 0.1, 90 | 0.9 91 | ], 92 | colors: [ 93 | gradientTimetableCircleStart, 94 | gradientTimetableCircleEnd 95 | ]), 96 | ), 97 | child: Center( 98 | child: Text((i + 1).toString(), 99 | style: TextStyle( 100 | fontSize: 17, 101 | fontFamily: fontName, 102 | color: Colors.white)))), 103 | //Time Table Value 104 | Expanded( 105 | child: Container( 106 | padding: EdgeInsets.symmetric( 107 | vertical: 10.0, horizontal: 5.0), 108 | decoration: BoxDecoration( 109 | color: Colors.white, 110 | borderRadius: BorderRadius.circular(10.0)), 111 | child: Text( 112 | ttcopy[i], 113 | style: TextStyle( 114 | fontSize: 14.5, 115 | fontFamily: fontName, 116 | fontWeight: FontWeight.w400, 117 | color: Color(0xFF555555)), 118 | ), 119 | ), 120 | ) 121 | ], 122 | ), 123 | ), 124 | ), 125 | ), 126 | ) + 127 | [ 128 | SizedBox( 129 | height: 40.0, 130 | ) 131 | ], 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/Pages/Attendance/attendancepage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:mec_attendance/Pages/Attendance/Widgets/customAppbar.dart'; 4 | import 'package:mec_attendance/Pages/Attendance/Widgets/getData.dart'; 5 | import 'Widgets/createList.dart'; 6 | import 'package:shared_preferences/shared_preferences.dart'; 7 | import 'package:mec_attendance/Pages/Timetable/timetable.dart'; 8 | import 'package:mec_attendance/Theme/theme.dart'; 9 | import 'dart:convert'; 10 | 11 | class AttendancePage extends StatefulWidget { 12 | @override 13 | _AttendancePageState createState() => _AttendancePageState(); 14 | } 15 | 16 | class _AttendancePageState extends State { 17 | String classname = ""; 18 | String studname = "Attendance"; 19 | List timeTable; 20 | List studentattendance; 21 | List subjectAndLastUpdated; 22 | int noOfSubjects; 23 | List noOfClassesList; 24 | // Wether to go back on back button press 25 | bool goback = true; 26 | 27 | // Content to be displayed on page 28 | List pageContent = [ 29 | Center( 30 | child: Container( 31 | margin: EdgeInsets.only(top: 110), 32 | height: 60.0, 33 | width: 60.0, 34 | child: CircularProgressIndicator( 35 | strokeWidth: 3, 36 | valueColor: new AlwaysStoppedAnimation( 37 | Colors.blue, 38 | ), 39 | ), 40 | ), 41 | ) 42 | ]; 43 | 44 | // This function switches the title & back function after data recieved. 45 | updateAppbar() { 46 | setState(() { 47 | if (studentattendance != null && studentattendance.length != 0) { 48 | // Convert Student Name To Title Case 49 | try { 50 | studentattendance[0] = studentattendance[0] 51 | .toLowerCase() 52 | .split(' ') 53 | .map((s) => s[0].toUpperCase() + s.substring(1)) 54 | .join(' '); 55 | } catch (_) {} 56 | 57 | // Change name to student name in Appbar. 58 | studname = studentattendance[0]; 59 | 60 | goback = false; 61 | } else { 62 | goback = true; 63 | } 64 | }); 65 | } 66 | 67 | fetchData() async { 68 | SharedPreferences pref = await SharedPreferences.getInstance(); 69 | classname = pref.getString('class'); 70 | var recoveredtimetable = pref.getString('timetable'); 71 | if (recoveredtimetable != null) { 72 | timeTable = json.decode(recoveredtimetable); 73 | } 74 | 75 | // Scrape data from website 76 | var data = await FetchData().getData(); 77 | 78 | setState(() { 79 | classname = data['classname']; 80 | timeTable = data['timeTable']; 81 | studentattendance = data['studentattendance']; 82 | subjectAndLastUpdated = data['subjectAndLastUpdated']; 83 | noOfSubjects = data['noOfSubjects']; 84 | noOfClassesList = data['noOfClassesList']; 85 | 86 | // Update in page body 87 | if (noOfSubjects == 0) { 88 | pageContent = [ 89 | Container( 90 | padding: EdgeInsets.all(20.0), 91 | margin: EdgeInsets.only(top: 100), 92 | alignment: Alignment.center, 93 | child: Text('Data With Given Details Have Not Been Entered.'), 94 | ) 95 | ]; 96 | goback = true; 97 | } 98 | // Displays fetched data 99 | else 100 | pageContent = returnListOfAttendanceInfo(studentattendance, 101 | subjectAndLastUpdated, noOfSubjects, noOfClassesList, context); 102 | }); 103 | goback = false; 104 | 105 | updateAppbar(); 106 | } 107 | 108 | // Controlling what happens when back button of appbar is pushed. 109 | onbackbutton() async { 110 | SharedPreferences pref = await SharedPreferences.getInstance(); 111 | pref.remove('class'); 112 | pref.remove('timetable'); 113 | pref.remove('rollno'); 114 | Navigator.pushReplacementNamed(context, '/choose'); 115 | } 116 | 117 | @override 118 | void initState() { 119 | fetchData(); 120 | super.initState(); 121 | } 122 | 123 | @override 124 | Widget build(BuildContext context) { 125 | return WillPopScope( 126 | onWillPop: () async { 127 | // Controls Back Button 128 | if (goback) 129 | Navigator.pushReplacementNamed(context, '/choose'); 130 | else 131 | return true; // return true if the route to be popped 132 | return false; 133 | }, 134 | child: Scaffold( 135 | backgroundColor: pageBackgroundColor, 136 | appBar: customAppbar( 137 | classname: classname, 138 | onbackbutton: onbackbutton, 139 | studname: studname, 140 | context: context, 141 | ), 142 | // Floating button pushes timetable page if time table has been loaded. 143 | floatingActionButton: FloatingActionButton( 144 | tooltip: 'Timetable', 145 | onPressed: () { 146 | print(timeTable); 147 | if (timeTable != null && timeTable.length != 0) 148 | Navigator.push( 149 | context, 150 | CupertinoPageRoute( 151 | builder: (context) => TimeTable( 152 | timeTable: timeTable, 153 | classname: classname, 154 | ), 155 | ), 156 | ); 157 | }, 158 | child: Icon(Icons.table_chart), 159 | backgroundColor: floatingButtonColor, 160 | ), 161 | body: Container( 162 | child: SingleChildScrollView( 163 | physics: const BouncingScrollPhysics( 164 | parent: AlwaysScrollableScrollPhysics(), 165 | ), 166 | child: Column( 167 | crossAxisAlignment: CrossAxisAlignment.stretch, 168 | children: [ 169 | SizedBox( 170 | height: 10.0, 171 | ) 172 | ] + 173 | pageContent + 174 | [ 175 | SizedBox(height: 20.0), 176 | ], 177 | ), 178 | ), 179 | ), 180 | ), 181 | ); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /lib/Pages/ChooseDetails/chooseDetails.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:mec_attendance/Pages/ChooseDetails/Widgets/selectClass.dart'; 3 | import 'package:mec_attendance/Pages/ChooseDetails/Widgets/selectSemester.dart'; 4 | import 'package:mec_attendance/Pages/ChooseDetails/Widgets/classToString.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | import 'package:mec_attendance/Widgets/fadeIn.dart'; 7 | import 'package:mec_attendance/Theme/theme.dart'; 8 | 9 | class ChooseDetails extends StatefulWidget { 10 | @override 11 | State createState() { 12 | return _ChooseDetailsState(); 13 | } 14 | } 15 | 16 | class _ChooseDetailsState extends State { 17 | @override 18 | void initState() { 19 | getDetailsFromStorage(); 20 | super.initState(); 21 | } 22 | 23 | int _radioValue = 0; 24 | int _radioValue2 = 1; 25 | int _rollno = 0; 26 | int cached = 0; 27 | 28 | var oldSem; 29 | var oldBranch; 30 | 31 | final GlobalKey _formKey = GlobalKey(); 32 | 33 | void onRadio1Change(int value) { 34 | setState(() { 35 | _radioValue = value; 36 | }); 37 | } 38 | 39 | void onRadio2Change(int value) { 40 | setState(() { 41 | _radioValue2 = value; 42 | }); 43 | } 44 | 45 | getDetailsFromStorage() async { 46 | SharedPreferences pref = await SharedPreferences.getInstance(); 47 | oldSem = pref.getInt('oldSem'); 48 | oldBranch = pref.getInt('oldBranch'); 49 | 50 | try { 51 | if (oldSem <= 5 && oldSem >= 0 && oldBranch >= 1 && oldBranch <= 8) 52 | setState(() { 53 | _radioValue = oldSem % 6; 54 | _radioValue2 = oldBranch % 9; 55 | }); 56 | } catch (_) {} 57 | 58 | cached = 1; 59 | print('Stored Details Obtained'); 60 | } 61 | 62 | onSubmit() async { 63 | if (!_formKey.currentState.validate()) { 64 | return; 65 | } 66 | String cls = classToString(_radioValue, _radioValue2); 67 | 68 | // Saves Details - it is used to load attendance page each time. 69 | SharedPreferences pref = await SharedPreferences.getInstance(); 70 | pref.setString('class', cls); 71 | pref.setString('rollno', _rollno.toString()); 72 | pref.remove('timetable'); 73 | 74 | // Setting the selection to show when this page is again visited. 75 | pref.setInt('oldSem', _radioValue); 76 | pref.setInt('oldBranch', _radioValue2); 77 | 78 | Navigator.pushReplacementNamed(context, '/attendance'); 79 | } 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | return Scaffold( 84 | body: Container( 85 | alignment: Alignment.center, 86 | child: ListView( 87 | padding: const EdgeInsets.all(25.0), 88 | children: [ 89 | Container( 90 | margin: const EdgeInsets.all(3.0), 91 | alignment: Alignment.center, 92 | child: Form( 93 | key: _formKey, 94 | child: Column( 95 | children: [ 96 | SizedBox(height: 30), 97 | FadeIn( 98 | delay: .3, 99 | child: Image.asset( 100 | 'assets/mec.png', 101 | height: 130.0, 102 | color: maincolor, 103 | ), 104 | ), 105 | Container( 106 | child: Column( 107 | children: [ 108 | SizedBox( 109 | height: 20.0, 110 | ), 111 | FadeIn( 112 | delay: .8, 113 | child: Text( 114 | 'Choose Class :', 115 | style: TextStyle(fontWeight: FontWeight.bold), 116 | ), 117 | ), 118 | FadeIn( 119 | delay: .8, 120 | child: SelectClass( 121 | radioValue: _radioValue, 122 | onRadio1Change: onRadio1Change, 123 | ), 124 | ), 125 | SizedBox( 126 | height: 20.0, 127 | ), 128 | FadeIn( 129 | delay: 1.3, 130 | child: Text( 131 | 'Choose Semester : ', 132 | style: TextStyle(fontWeight: FontWeight.bold), 133 | ), 134 | ), 135 | FadeIn( 136 | delay: 1.3, 137 | child: SelectSemester( 138 | radioValue: _radioValue2, 139 | onRadio2Change: onRadio2Change, 140 | ), 141 | ), 142 | SizedBox( 143 | height: 15.0, 144 | ), 145 | FadeIn( 146 | delay: 1.8, 147 | child: Container( 148 | width: 220.0, 149 | child: TextFormField( 150 | maxLength: 2, 151 | validator: (String value) { 152 | final n = num.tryParse(value); 153 | if (n == null || n < 0) { 154 | return 'Input is not a valid Roll Number'; 155 | } 156 | _rollno = n; 157 | return null; 158 | }, 159 | keyboardType: TextInputType.number, 160 | decoration: InputDecoration( 161 | hintText: 'Roll No.', 162 | icon: Icon(Icons.event), 163 | ), 164 | ), 165 | ), 166 | ), 167 | ], 168 | ), 169 | ), 170 | FadeIn( 171 | delay: 2.1, 172 | child: RaisedButton( 173 | padding: EdgeInsets.symmetric(horizontal: 30.0), 174 | color: maincolor, 175 | shape: RoundedRectangleBorder( 176 | borderRadius: new BorderRadius.circular(15.0), 177 | ), 178 | child: Text( 179 | 'SUBMIT', 180 | style: TextStyle(color: Colors.white), 181 | ), 182 | onPressed: () { 183 | onSubmit(); 184 | }, 185 | ), 186 | ), 187 | ], 188 | ), 189 | ), 190 | ) 191 | ], 192 | ), 193 | ), 194 | ); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.0.13" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.6.0" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.4.1" 25 | beautifulsoup: 26 | dependency: "direct main" 27 | description: 28 | name: beautifulsoup 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "0.0.1" 32 | boolean_selector: 33 | dependency: transitive 34 | description: 35 | name: boolean_selector 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "2.0.0" 39 | charcode: 40 | dependency: transitive 41 | description: 42 | name: charcode 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.3" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.14.12" 53 | convert: 54 | dependency: transitive 55 | description: 56 | name: convert 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.1" 60 | crypto: 61 | dependency: transitive 62 | description: 63 | name: crypto 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "2.1.4" 67 | csslib: 68 | dependency: transitive 69 | description: 70 | name: csslib 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.15.0" 74 | cupertino_icons: 75 | dependency: "direct main" 76 | description: 77 | name: cupertino_icons 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "0.1.3" 81 | file: 82 | dependency: transitive 83 | description: 84 | name: file 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "5.2.1" 88 | flutter: 89 | dependency: "direct main" 90 | description: flutter 91 | source: sdk 92 | version: "0.0.0" 93 | flutter_launcher_icons: 94 | dependency: "direct dev" 95 | description: 96 | name: flutter_launcher_icons 97 | url: "https://pub.dartlang.org" 98 | source: hosted 99 | version: "0.7.5" 100 | flutter_test: 101 | dependency: "direct dev" 102 | description: flutter 103 | source: sdk 104 | version: "0.0.0" 105 | flutter_web_plugins: 106 | dependency: transitive 107 | description: flutter 108 | source: sdk 109 | version: "0.0.0" 110 | gradient_app_bar: 111 | dependency: "direct main" 112 | description: 113 | name: gradient_app_bar 114 | url: "https://pub.dartlang.org" 115 | source: hosted 116 | version: "0.1.3" 117 | html: 118 | dependency: transitive 119 | description: 120 | name: html 121 | url: "https://pub.dartlang.org" 122 | source: hosted 123 | version: "0.13.4+2" 124 | http: 125 | dependency: "direct main" 126 | description: 127 | name: http 128 | url: "https://pub.dartlang.org" 129 | source: hosted 130 | version: "0.12.1" 131 | http_parser: 132 | dependency: transitive 133 | description: 134 | name: http_parser 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "3.1.4" 138 | image: 139 | dependency: transitive 140 | description: 141 | name: image 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "2.1.12" 145 | intl: 146 | dependency: transitive 147 | description: 148 | name: intl 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "0.16.1" 152 | matcher: 153 | dependency: transitive 154 | description: 155 | name: matcher 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "0.12.6" 159 | meta: 160 | dependency: transitive 161 | description: 162 | name: meta 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.1.8" 166 | onesignal_flutter: 167 | dependency: "direct main" 168 | description: 169 | name: onesignal_flutter 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "2.6.0" 173 | path: 174 | dependency: transitive 175 | description: 176 | name: path 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.6.4" 180 | path_provider_linux: 181 | dependency: transitive 182 | description: 183 | name: path_provider_linux 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "0.0.1+2" 187 | path_provider_platform_interface: 188 | dependency: transitive 189 | description: 190 | name: path_provider_platform_interface 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "1.0.2" 194 | pedantic: 195 | dependency: transitive 196 | description: 197 | name: pedantic 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "1.9.0" 201 | percent_indicator: 202 | dependency: "direct main" 203 | description: 204 | name: percent_indicator 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "2.1.5" 208 | petitparser: 209 | dependency: transitive 210 | description: 211 | name: petitparser 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "2.4.0" 215 | platform: 216 | dependency: transitive 217 | description: 218 | name: platform 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "2.2.1" 222 | platform_detect: 223 | dependency: transitive 224 | description: 225 | name: platform_detect 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "1.4.0" 229 | plugin_platform_interface: 230 | dependency: transitive 231 | description: 232 | name: plugin_platform_interface 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "1.0.2" 236 | process: 237 | dependency: transitive 238 | description: 239 | name: process 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "3.0.13" 243 | pub_semver: 244 | dependency: transitive 245 | description: 246 | name: pub_semver 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "1.4.4" 250 | quiver: 251 | dependency: transitive 252 | description: 253 | name: quiver 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "2.1.3" 257 | shared_preferences: 258 | dependency: "direct main" 259 | description: 260 | name: shared_preferences 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "0.5.8" 264 | shared_preferences_linux: 265 | dependency: transitive 266 | description: 267 | name: shared_preferences_linux 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "0.0.2+1" 271 | shared_preferences_macos: 272 | dependency: transitive 273 | description: 274 | name: shared_preferences_macos 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "0.0.1+10" 278 | shared_preferences_platform_interface: 279 | dependency: transitive 280 | description: 281 | name: shared_preferences_platform_interface 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "1.0.4" 285 | shared_preferences_web: 286 | dependency: transitive 287 | description: 288 | name: shared_preferences_web 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "0.1.2+7" 292 | simple_animations: 293 | dependency: "direct main" 294 | description: 295 | name: simple_animations 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "1.3.12" 299 | sky_engine: 300 | dependency: transitive 301 | description: flutter 302 | source: sdk 303 | version: "0.0.99" 304 | source_span: 305 | dependency: transitive 306 | description: 307 | name: source_span 308 | url: "https://pub.dartlang.org" 309 | source: hosted 310 | version: "1.7.0" 311 | stack_trace: 312 | dependency: transitive 313 | description: 314 | name: stack_trace 315 | url: "https://pub.dartlang.org" 316 | source: hosted 317 | version: "1.9.3" 318 | stream_channel: 319 | dependency: transitive 320 | description: 321 | name: stream_channel 322 | url: "https://pub.dartlang.org" 323 | source: hosted 324 | version: "2.0.0" 325 | string_scanner: 326 | dependency: transitive 327 | description: 328 | name: string_scanner 329 | url: "https://pub.dartlang.org" 330 | source: hosted 331 | version: "1.0.5" 332 | term_glyph: 333 | dependency: transitive 334 | description: 335 | name: term_glyph 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "1.1.0" 339 | test_api: 340 | dependency: transitive 341 | description: 342 | name: test_api 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "0.2.15" 346 | typed_data: 347 | dependency: transitive 348 | description: 349 | name: typed_data 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "1.1.6" 353 | url_launcher: 354 | dependency: "direct main" 355 | description: 356 | name: url_launcher 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "5.5.0" 360 | url_launcher_linux: 361 | dependency: transitive 362 | description: 363 | name: url_launcher_linux 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "0.0.1+1" 367 | url_launcher_macos: 368 | dependency: transitive 369 | description: 370 | name: url_launcher_macos 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "0.0.1+7" 374 | url_launcher_platform_interface: 375 | dependency: transitive 376 | description: 377 | name: url_launcher_platform_interface 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "1.0.7" 381 | url_launcher_web: 382 | dependency: transitive 383 | description: 384 | name: url_launcher_web 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "0.1.2" 388 | utf: 389 | dependency: transitive 390 | description: 391 | name: utf 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "0.9.0+5" 395 | vector_math: 396 | dependency: transitive 397 | description: 398 | name: vector_math 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "2.0.8" 402 | xdg_directories: 403 | dependency: transitive 404 | description: 405 | name: xdg_directories 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "0.1.0" 409 | xml: 410 | dependency: transitive 411 | description: 412 | name: xml 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "3.6.1" 416 | yaml: 417 | dependency: transitive 418 | description: 419 | name: yaml 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "2.2.1" 423 | sdks: 424 | dart: ">=2.6.0 <3.0.0" 425 | flutter: ">=1.12.13+hotfix.5 <2.0.0" 426 | -------------------------------------------------------------------------------- /lib/Pages/Attendance/Widgets/createList.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:percent_indicator/circular_percent_indicator.dart'; 3 | import 'package:mec_attendance/Widgets/fadeIn.dart'; 4 | import 'package:mec_attendance/Theme/theme.dart'; 5 | 6 | // This function uses created data and makes a list of widgets, each corresponding to a subject. 7 | // This data is shown as the attendane information 8 | returnListOfAttendanceInfo(studentattendance, subjectAndLastUpdated, length, 9 | noOfClassesList, context) { 10 | // print(noOfClassesList); 11 | var widgetList = []; 12 | 13 | for (int i = 0; i < length - 1; i++) { 14 | var attendance; 15 | var elective = 0; 16 | if (double.tryParse(studentattendance[i + 1]) != null) 17 | attendance = double.parse(studentattendance[i + 1]); 18 | else { 19 | attendance = 0.0; 20 | elective = 1; 21 | } 22 | var totalNoOfClasses = noOfClassesList[i]; 23 | var attented = (attendance * totalNoOfClasses) / 100; 24 | attented = attented.round() + 0.0; 25 | var canCut = 0.0; 26 | var canCutText = ''; 27 | 28 | if (attendance == 75.0) { 29 | canCutText = 'Perfectly Balanced As All Things Should Be !'; 30 | } else if (attendance > 75.0) { 31 | canCut = (4 * attented - 3 * totalNoOfClasses) / 3; 32 | canCutText = 'Can Cut ' + canCut.floor().toString() + ' Classes'; 33 | } else if ((attendance == 0.0 && totalNoOfClasses == 0) || 34 | (elective == 1)) { 35 | canCutText = '-------'; 36 | } else { 37 | canCut = 3 * totalNoOfClasses - 4 * attented; 38 | // print(canCut); 39 | canCutText = 'Have to Attend ' + canCut.round().toString() + ' Classes'; 40 | } 41 | var attn = ''; 42 | if (attendance == 0.0) 43 | attn = '- -'; 44 | else 45 | attn = attendance.toString() + '%'; 46 | // Getting Subject Name 47 | var subname = subjectAndLastUpdated[i][0].toString(); 48 | 49 | int lastNumIndex = 0; 50 | for (int j = 0; j < subname.length; j++) { 51 | if (int.tryParse(subname[j]) != null) lastNumIndex = j; 52 | } 53 | 54 | subname = subname.substring(lastNumIndex + 1); 55 | 56 | // var subarray = subname.split(' '); 57 | // // If first word of subject name contains numbers, its propably the course code so removes it. 58 | // if (subarray[0].contains('0') || 59 | // subarray[0].contains('1') || 60 | // subarray[0].contains('2') || 61 | // subarray[0].contains('3') || 62 | // subarray[0].contains('4')) subarray.removeAt(0); 63 | // subname = subarray.join(' '); 64 | 65 | // Tries to convert student name to Lowercase. 66 | try { 67 | subname = subname 68 | .trim() 69 | .toLowerCase() 70 | .split(' ') 71 | .map((s) => s[0].toUpperCase() + s.substring(1)) 72 | .join(' '); 73 | } catch (_) {} 74 | // print(subname); 75 | //Convert date to no of days 76 | var lastupdated = subjectAndLastUpdated[i][1]; 77 | 78 | // Takes last updated value, splits to day, month & year. 79 | // Takes device date & finds difference in number of days. 80 | int luday, lumonth, luyear, difference = -999; 81 | try { 82 | luday = int.parse(lastupdated.substring(0, 2)); 83 | lumonth = int.parse(lastupdated.substring(3, 5)); 84 | luyear = int.parse(lastupdated.substring(6, 10)); 85 | var now = new DateTime.now(); 86 | var dateupdated = new DateTime.utc(luyear, lumonth, luday); 87 | difference = now.difference(dateupdated).inDays; 88 | } catch (_) {} 89 | // Sets Last Updated 90 | var lastupdatedstring; 91 | if (difference == 0) 92 | lastupdatedstring = 'Today'; 93 | else if (difference == 1) 94 | lastupdatedstring = 'Yesterday'; 95 | else if (difference == -999) 96 | lastupdatedstring = subjectAndLastUpdated[i][1]; 97 | else 98 | lastupdatedstring = difference.toString() + ' Days Ago'; 99 | 100 | // Returns the small thing to display data in popup 101 | Widget _popupElement(t1, t2) { 102 | return Container( 103 | decoration: BoxDecoration( 104 | borderRadius: BorderRadius.circular(10), 105 | gradient: LinearGradient( 106 | begin: Alignment.centerLeft, 107 | end: Alignment.centerRight, 108 | stops: [ 109 | 0.1, 110 | 0.9 111 | ], 112 | colors: [ 113 | (attendance >= 75 || 114 | (attendance == 0 && totalNoOfClasses == 0) || 115 | elective == 1) 116 | ? attendaneGradientStart 117 | : gradientWhenUnderStart, 118 | (attendance >= 75 || 119 | (attendance == 0 && totalNoOfClasses == 0) || 120 | elective == 1) 121 | ? attendaneGradientEnd 122 | : gradientWhenUnderEnd, 123 | ]), 124 | ), 125 | margin: EdgeInsets.symmetric(vertical: 5), 126 | padding: EdgeInsets.symmetric(horizontal: 15, vertical: 5), 127 | child: Row( 128 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 129 | children: [ 130 | Text( 131 | t1, 132 | style: TextStyle( 133 | fontFamily: fontName, color: Colors.white, fontSize: 12), 134 | ), 135 | Text( 136 | t2, 137 | style: TextStyle( 138 | fontFamily: fontName, color: Colors.white, fontSize: 12), 139 | ), 140 | ], 141 | ), 142 | ); 143 | } // End of the popup element 144 | 145 | // Percentage Indicator 146 | Widget percentIndicator() { 147 | return Container( 148 | margin: EdgeInsets.fromLTRB(10, 5, 7, 5), 149 | child: CircularPercentIndicator( 150 | radius: 78.0, 151 | lineWidth: 1.3, 152 | percent: attendance / 100, 153 | center: Text( 154 | attn.toString(), 155 | style: TextStyle(fontFamily: fontName, fontSize: 16), 156 | ), 157 | circularStrokeCap: CircularStrokeCap.round, 158 | reverse: true, 159 | animation: true, 160 | animationDuration: 2000, 161 | backgroundColor: Color(0x11000000), 162 | maskFilter: MaskFilter.blur(BlurStyle.solid, 0), 163 | linearGradient: LinearGradient( 164 | begin: Alignment.centerLeft, 165 | end: Alignment.centerRight, 166 | colors: [ 167 | (attendance >= 75 || 168 | (attendance == 0 && totalNoOfClasses == 0) || 169 | elective == 1) 170 | ? attendaneGradientStart 171 | : gradientWhenUnderStart, 172 | (attendance >= 75 || 173 | (attendance == 0 && totalNoOfClasses == 0) || 174 | elective == 1) 175 | ? attendaneGradientEnd 176 | : gradientWhenUnderEnd, 177 | ], 178 | ), 179 | ), 180 | ); 181 | } // End of Percentage Indicator 182 | 183 | // Each list Item starts here............ 184 | // Change here to change how the details of subjects change. 185 | 186 | widgetList.add( 187 | InkWell( 188 | onTap: () { 189 | // When a card is presses, The following pop up comes up. 190 | showDialog( 191 | context: context, 192 | builder: (BuildContext context) { 193 | return AlertDialog( 194 | shape: RoundedRectangleBorder( 195 | borderRadius: BorderRadius.all(Radius.circular(15.0))), 196 | title: Text( 197 | subname, 198 | textAlign: TextAlign.center, 199 | style: TextStyle( 200 | color: Colors.black54, 201 | fontFamily: fontName, 202 | shadows: [ 203 | BoxShadow( 204 | color: Color(0x88000000), 205 | blurRadius: 0.0, 206 | spreadRadius: 0.0, 207 | ) 208 | ]), 209 | ), 210 | content: SingleChildScrollView( 211 | child: Column( 212 | mainAxisSize: MainAxisSize.min, 213 | crossAxisAlignment: CrossAxisAlignment.start, 214 | children: [ 215 | Center( 216 | child: percentIndicator(), 217 | ), 218 | FadeIn( 219 | delay: 0.2, 220 | child: _popupElement('Classes Attended', 221 | ': ' + attented.toStringAsFixed(0)), 222 | ), 223 | FadeIn( 224 | delay: 0.3, 225 | child: _popupElement('Total No. of Classes', 226 | ': ' + totalNoOfClasses.toString()), 227 | ), 228 | FadeIn( 229 | delay: 0.4, 230 | child: _popupElement('Last Updated', lastupdatedstring), 231 | ), 232 | FadeIn( 233 | delay: 0.5, 234 | child: _popupElement( 235 | 'Updated Date', subjectAndLastUpdated[i][1]), 236 | ), 237 | SizedBox(height: 10), 238 | FadeIn( 239 | delay: .7, 240 | child: Center( 241 | child: Text( 242 | canCutText, 243 | style: TextStyle( 244 | fontFamily: fontName, 245 | color: Colors.black54, 246 | fontSize: 12, 247 | shadows: [ 248 | BoxShadow( 249 | color: Color(0x88000000), 250 | blurRadius: 1.0, 251 | spreadRadius: 0.0, 252 | ) 253 | ]), 254 | )), 255 | ), 256 | ], 257 | ), 258 | ), 259 | actions: [ 260 | FadeIn( 261 | delay: .7, 262 | child: FlatButton( 263 | child: Text( 264 | "Close", 265 | style: TextStyle( 266 | fontFamily: fontName, 267 | color: attendaneGradientEnd, 268 | fontSize: 12, 269 | shadows: [ 270 | BoxShadow( 271 | color: Color(0x885555ff), 272 | blurRadius: 2.0, 273 | spreadRadius: 0.0, 274 | ) 275 | ]), 276 | ), 277 | onPressed: () { 278 | Navigator.of(context).pop(); 279 | }, 280 | ), 281 | ), 282 | ], 283 | ); 284 | }, 285 | ); 286 | }, 287 | child: FadeIn( 288 | delay: i / 2.0, 289 | child: Container( 290 | padding: EdgeInsets.fromLTRB(10, 10, 5, 5), 291 | margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 8.0), 292 | decoration: BoxDecoration( 293 | color: Colors.white, 294 | borderRadius: BorderRadius.circular(15.0), 295 | // gradient: LinearGradient( 296 | // begin: Alignment.topRight, 297 | // end: Alignment.bottomLeft, 298 | // stops: [0.1, 0.9], 299 | // colors: [Colors.indigo, Colors.cyan]), 300 | ), 301 | child: Row( 302 | children: [ 303 | Expanded( 304 | child: Column( 305 | crossAxisAlignment: CrossAxisAlignment.start, 306 | children: [ 307 | Container( 308 | margin: EdgeInsets.only(left: 10), 309 | child: Text( 310 | subname, 311 | style: TextStyle( 312 | fontFamily: fontName, 313 | color: Color(0xFF555555), 314 | fontSize: 16.0), 315 | ), 316 | ), 317 | 318 | // The line under subject title. 319 | SizedBox(height: 10), 320 | 321 | //Have to Attend / Cut 322 | Column( 323 | crossAxisAlignment: CrossAxisAlignment.stretch, 324 | children: [ 325 | Container( 326 | // margin: EdgeInsets.only(left: 10.0), 327 | alignment: Alignment.center, 328 | padding: EdgeInsets.symmetric( 329 | vertical: 5.0, horizontal: 10.0), 330 | decoration: BoxDecoration( 331 | // color: Color(0xFF2680C1), 332 | borderRadius: BorderRadius.circular(50.0), 333 | gradient: LinearGradient( 334 | begin: Alignment.centerLeft, 335 | end: Alignment.centerRight, 336 | stops: [ 337 | 0.1, 338 | 0.9 339 | ], 340 | colors: [ 341 | (attendance >= 75 || 342 | (attendance == 0 && 343 | totalNoOfClasses == 0) || 344 | elective == 1) 345 | ? attendaneGradientStart //Blue Left 346 | : gradientWhenUnderStart, // Red 347 | (attendance >= 75 || 348 | (attendance == 0 && 349 | totalNoOfClasses == 0) || 350 | elective == 1) 351 | ? attendaneGradientEnd // Blue Right 352 | : gradientWhenUnderEnd, 353 | ]), 354 | ), 355 | child: Text( 356 | canCutText, 357 | style: TextStyle( 358 | fontFamily: fontName, 359 | color: Colors.white, 360 | fontSize: 12), 361 | textAlign: TextAlign.center, 362 | ), 363 | ), 364 | ], 365 | ), 366 | 367 | SizedBox( 368 | height: 4, 369 | ), 370 | 371 | //Last Updated 372 | Container( 373 | padding: EdgeInsets.symmetric( 374 | vertical: 5.0, horizontal: 10.0), 375 | child: Text( 376 | 'Last Updated : ' + lastupdatedstring, 377 | // subjectAndLastUpdated[i][1], 378 | style: TextStyle( 379 | fontFamily: fontName, 380 | color: Color(0xFF777777), 381 | fontSize: 12, 382 | ), 383 | // textAlign: TextAlign.center, 384 | ), 385 | ), 386 | ]), 387 | ), 388 | percentIndicator(), 389 | ], 390 | )), 391 | ), 392 | ), 393 | ); 394 | } 395 | return widgetList; 396 | } 397 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 18 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 19 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 10; 28 | files = ( 29 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 30 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 31 | ); 32 | name = "Embed Frameworks"; 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXCopyFilesBuildPhase section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 39 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 40 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 41 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 42 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 43 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 44 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 45 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 46 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 47 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 48 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 52 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 61 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 9740EEB11CF90186004384FC /* Flutter */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 3B80C3931E831B6300D905FE /* App.framework */, 72 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 73 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 74 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 75 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 76 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 77 | ); 78 | name = Flutter; 79 | sourceTree = ""; 80 | }; 81 | 97C146E51CF9000F007C117D = { 82 | isa = PBXGroup; 83 | children = ( 84 | 9740EEB11CF90186004384FC /* Flutter */, 85 | 97C146F01CF9000F007C117D /* Runner */, 86 | 97C146EF1CF9000F007C117D /* Products */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 97C146EF1CF9000F007C117D /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 97C146EE1CF9000F007C117D /* Runner.app */, 94 | ); 95 | name = Products; 96 | sourceTree = ""; 97 | }; 98 | 97C146F01CF9000F007C117D /* Runner */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 102 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 103 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 104 | 97C147021CF9000F007C117D /* Info.plist */, 105 | 97C146F11CF9000F007C117D /* Supporting Files */, 106 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 107 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 108 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 109 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 110 | ); 111 | path = Runner; 112 | sourceTree = ""; 113 | }; 114 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | /* End PBXGroup section */ 122 | 123 | /* Begin PBXNativeTarget section */ 124 | 97C146ED1CF9000F007C117D /* Runner */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 127 | buildPhases = ( 128 | 9740EEB61CF901F6004384FC /* Run Script */, 129 | 97C146EA1CF9000F007C117D /* Sources */, 130 | 97C146EB1CF9000F007C117D /* Frameworks */, 131 | 97C146EC1CF9000F007C117D /* Resources */, 132 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 133 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = Runner; 140 | productName = Runner; 141 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 97C146E61CF9000F007C117D /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | LastUpgradeCheck = 1020; 151 | ORGANIZATIONNAME = "The Chromium Authors"; 152 | TargetAttributes = { 153 | 97C146ED1CF9000F007C117D = { 154 | CreatedOnToolsVersion = 7.3.1; 155 | LastSwiftMigration = 1100; 156 | }; 157 | }; 158 | }; 159 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 160 | compatibilityVersion = "Xcode 3.2"; 161 | developmentRegion = en; 162 | hasScannedForEncodings = 0; 163 | knownRegions = ( 164 | en, 165 | Base, 166 | ); 167 | mainGroup = 97C146E51CF9000F007C117D; 168 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 169 | projectDirPath = ""; 170 | projectRoot = ""; 171 | targets = ( 172 | 97C146ED1CF9000F007C117D /* Runner */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXResourcesBuildPhase section */ 178 | 97C146EC1CF9000F007C117D /* Resources */ = { 179 | isa = PBXResourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 183 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 184 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 185 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXShellScriptBuildPhase section */ 192 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 193 | isa = PBXShellScriptBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | ); 197 | inputPaths = ( 198 | ); 199 | name = "Thin Binary"; 200 | outputPaths = ( 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | shellPath = /bin/sh; 204 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 205 | }; 206 | 9740EEB61CF901F6004384FC /* Run Script */ = { 207 | isa = PBXShellScriptBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | ); 211 | inputPaths = ( 212 | ); 213 | name = "Run Script"; 214 | outputPaths = ( 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | shellPath = /bin/sh; 218 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 219 | }; 220 | /* End PBXShellScriptBuildPhase section */ 221 | 222 | /* Begin PBXSourcesBuildPhase section */ 223 | 97C146EA1CF9000F007C117D /* Sources */ = { 224 | isa = PBXSourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 228 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | }; 232 | /* End PBXSourcesBuildPhase section */ 233 | 234 | /* Begin PBXVariantGroup section */ 235 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 236 | isa = PBXVariantGroup; 237 | children = ( 238 | 97C146FB1CF9000F007C117D /* Base */, 239 | ); 240 | name = Main.storyboard; 241 | sourceTree = ""; 242 | }; 243 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 244 | isa = PBXVariantGroup; 245 | children = ( 246 | 97C147001CF9000F007C117D /* Base */, 247 | ); 248 | name = LaunchScreen.storyboard; 249 | sourceTree = ""; 250 | }; 251 | /* End PBXVariantGroup section */ 252 | 253 | /* Begin XCBuildConfiguration section */ 254 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 255 | isa = XCBuildConfiguration; 256 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | CLANG_ANALYZER_NONNULL = YES; 260 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 261 | CLANG_CXX_LIBRARY = "libc++"; 262 | CLANG_ENABLE_MODULES = YES; 263 | CLANG_ENABLE_OBJC_ARC = YES; 264 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 265 | CLANG_WARN_BOOL_CONVERSION = YES; 266 | CLANG_WARN_COMMA = YES; 267 | CLANG_WARN_CONSTANT_CONVERSION = YES; 268 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 270 | CLANG_WARN_EMPTY_BODY = YES; 271 | CLANG_WARN_ENUM_CONVERSION = YES; 272 | CLANG_WARN_INFINITE_RECURSION = YES; 273 | CLANG_WARN_INT_CONVERSION = YES; 274 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 275 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 276 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 279 | CLANG_WARN_STRICT_PROTOTYPES = YES; 280 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 281 | CLANG_WARN_UNREACHABLE_CODE = YES; 282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 283 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 284 | COPY_PHASE_STRIP = NO; 285 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 286 | ENABLE_NS_ASSERTIONS = NO; 287 | ENABLE_STRICT_OBJC_MSGSEND = YES; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_NO_COMMON_BLOCKS = YES; 290 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 291 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 292 | GCC_WARN_UNDECLARED_SELECTOR = YES; 293 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 294 | GCC_WARN_UNUSED_FUNCTION = YES; 295 | GCC_WARN_UNUSED_VARIABLE = YES; 296 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 297 | MTL_ENABLE_DEBUG_INFO = NO; 298 | SDKROOT = iphoneos; 299 | SUPPORTED_PLATFORMS = iphoneos; 300 | TARGETED_DEVICE_FAMILY = "1,2"; 301 | VALIDATE_PRODUCT = YES; 302 | }; 303 | name = Profile; 304 | }; 305 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 308 | buildSettings = { 309 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 310 | CLANG_ENABLE_MODULES = YES; 311 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 312 | ENABLE_BITCODE = NO; 313 | FRAMEWORK_SEARCH_PATHS = ( 314 | "$(inherited)", 315 | "$(PROJECT_DIR)/Flutter", 316 | ); 317 | INFOPLIST_FILE = Runner/Info.plist; 318 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 319 | LIBRARY_SEARCH_PATHS = ( 320 | "$(inherited)", 321 | "$(PROJECT_DIR)/Flutter", 322 | ); 323 | PRODUCT_BUNDLE_IDENTIFIER = com.mec.attendance; 324 | PRODUCT_NAME = "$(TARGET_NAME)"; 325 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 326 | SWIFT_VERSION = 5.0; 327 | VERSIONING_SYSTEM = "apple-generic"; 328 | }; 329 | name = Profile; 330 | }; 331 | 97C147031CF9000F007C117D /* Debug */ = { 332 | isa = XCBuildConfiguration; 333 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 334 | buildSettings = { 335 | ALWAYS_SEARCH_USER_PATHS = NO; 336 | CLANG_ANALYZER_NONNULL = YES; 337 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 338 | CLANG_CXX_LIBRARY = "libc++"; 339 | CLANG_ENABLE_MODULES = YES; 340 | CLANG_ENABLE_OBJC_ARC = YES; 341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_COMMA = YES; 344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 347 | CLANG_WARN_EMPTY_BODY = YES; 348 | CLANG_WARN_ENUM_CONVERSION = YES; 349 | CLANG_WARN_INFINITE_RECURSION = YES; 350 | CLANG_WARN_INT_CONVERSION = YES; 351 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 353 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 354 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 355 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 356 | CLANG_WARN_STRICT_PROTOTYPES = YES; 357 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 358 | CLANG_WARN_UNREACHABLE_CODE = YES; 359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 360 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 361 | COPY_PHASE_STRIP = NO; 362 | DEBUG_INFORMATION_FORMAT = dwarf; 363 | ENABLE_STRICT_OBJC_MSGSEND = YES; 364 | ENABLE_TESTABILITY = YES; 365 | GCC_C_LANGUAGE_STANDARD = gnu99; 366 | GCC_DYNAMIC_NO_PIC = NO; 367 | GCC_NO_COMMON_BLOCKS = YES; 368 | GCC_OPTIMIZATION_LEVEL = 0; 369 | GCC_PREPROCESSOR_DEFINITIONS = ( 370 | "DEBUG=1", 371 | "$(inherited)", 372 | ); 373 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 374 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 375 | GCC_WARN_UNDECLARED_SELECTOR = YES; 376 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 377 | GCC_WARN_UNUSED_FUNCTION = YES; 378 | GCC_WARN_UNUSED_VARIABLE = YES; 379 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 380 | MTL_ENABLE_DEBUG_INFO = YES; 381 | ONLY_ACTIVE_ARCH = YES; 382 | SDKROOT = iphoneos; 383 | TARGETED_DEVICE_FAMILY = "1,2"; 384 | }; 385 | name = Debug; 386 | }; 387 | 97C147041CF9000F007C117D /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 398 | CLANG_WARN_BOOL_CONVERSION = YES; 399 | CLANG_WARN_COMMA = YES; 400 | CLANG_WARN_CONSTANT_CONVERSION = YES; 401 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 402 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 403 | CLANG_WARN_EMPTY_BODY = YES; 404 | CLANG_WARN_ENUM_CONVERSION = YES; 405 | CLANG_WARN_INFINITE_RECURSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 408 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 409 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 410 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 411 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 412 | CLANG_WARN_STRICT_PROTOTYPES = YES; 413 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 414 | CLANG_WARN_UNREACHABLE_CODE = YES; 415 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 416 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 417 | COPY_PHASE_STRIP = NO; 418 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 419 | ENABLE_NS_ASSERTIONS = NO; 420 | ENABLE_STRICT_OBJC_MSGSEND = YES; 421 | GCC_C_LANGUAGE_STANDARD = gnu99; 422 | GCC_NO_COMMON_BLOCKS = YES; 423 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 424 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 425 | GCC_WARN_UNDECLARED_SELECTOR = YES; 426 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 427 | GCC_WARN_UNUSED_FUNCTION = YES; 428 | GCC_WARN_UNUSED_VARIABLE = YES; 429 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 430 | MTL_ENABLE_DEBUG_INFO = NO; 431 | SDKROOT = iphoneos; 432 | SUPPORTED_PLATFORMS = iphoneos; 433 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 434 | TARGETED_DEVICE_FAMILY = "1,2"; 435 | VALIDATE_PRODUCT = YES; 436 | }; 437 | name = Release; 438 | }; 439 | 97C147061CF9000F007C117D /* Debug */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 442 | buildSettings = { 443 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 444 | CLANG_ENABLE_MODULES = YES; 445 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 446 | ENABLE_BITCODE = NO; 447 | FRAMEWORK_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "$(PROJECT_DIR)/Flutter", 450 | ); 451 | INFOPLIST_FILE = Runner/Info.plist; 452 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 453 | LIBRARY_SEARCH_PATHS = ( 454 | "$(inherited)", 455 | "$(PROJECT_DIR)/Flutter", 456 | ); 457 | PRODUCT_BUNDLE_IDENTIFIER = com.mec.attendance; 458 | PRODUCT_NAME = "$(TARGET_NAME)"; 459 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 460 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 461 | SWIFT_VERSION = 5.0; 462 | VERSIONING_SYSTEM = "apple-generic"; 463 | }; 464 | name = Debug; 465 | }; 466 | 97C147071CF9000F007C117D /* Release */ = { 467 | isa = XCBuildConfiguration; 468 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | CLANG_ENABLE_MODULES = YES; 472 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 473 | ENABLE_BITCODE = NO; 474 | FRAMEWORK_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "$(PROJECT_DIR)/Flutter", 477 | ); 478 | INFOPLIST_FILE = Runner/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 480 | LIBRARY_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "$(PROJECT_DIR)/Flutter", 483 | ); 484 | PRODUCT_BUNDLE_IDENTIFIER = com.mec.attendance; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 487 | SWIFT_VERSION = 5.0; 488 | VERSIONING_SYSTEM = "apple-generic"; 489 | }; 490 | name = Release; 491 | }; 492 | /* End XCBuildConfiguration section */ 493 | 494 | /* Begin XCConfigurationList section */ 495 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 97C147031CF9000F007C117D /* Debug */, 499 | 97C147041CF9000F007C117D /* Release */, 500 | 249021D3217E4FDB00AE95B9 /* Profile */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 97C147061CF9000F007C117D /* Debug */, 509 | 97C147071CF9000F007C117D /* Release */, 510 | 249021D4217E4FDB00AE95B9 /* Profile */, 511 | ); 512 | defaultConfigurationIsVisible = 0; 513 | defaultConfigurationName = Release; 514 | }; 515 | /* End XCConfigurationList section */ 516 | }; 517 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 518 | } 519 | --------------------------------------------------------------------------------