feat: homepage init

This commit is contained in:
louis 2024-03-19 11:09:07 +08:00
parent 142c8b5f06
commit d1aaecd800
56 changed files with 2238 additions and 71 deletions

BIN
assets/images/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
assets/images/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
assets/images/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 KiB

BIN
assets/images/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/images/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
assets/images/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

BIN
assets/images/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

BIN
assets/images/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
assets/images/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
assets/images/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

BIN
assets/images/back.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 KiB

BIN
assets/images/color.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

BIN
assets/images/study.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

View File

@ -4,7 +4,7 @@ import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class AppTheme {
AppTheme._();
static const Color primaryColor = Color(0xFFC89607);
static Color primaryColorLight = primaryColor.withOpacity(0.7);
static const Color primaryColorLight = Color.fromARGB(255, 255, 206, 70);
static Color primaryColorDark = Color.fromRGBO(
primaryColor.red,
primaryColor.green,
@ -21,6 +21,8 @@ class AppTheme {
static const Color snackbarWarningBackgroudColor = Colors.orange;
static Color barrierColor = Colors.black.withOpacity(0.5);
static const String fontName = 'NotoSans';
static const Color activeNavigationBarColor = primaryColor;
static const Color notActiveNavigationBarColor = Colors.grey;
}
final theme = ThemeData(

View File

@ -0,0 +1,13 @@
import 'dart:ui';
import 'package:flutter/material.dart';
const lightAccentBlue = Color(0xFF92E2FF);
const darkAccentBlue = Color(0xFF1DBEF9);
const lightOrange = Color(0xFFFFD099);
const darkOrange = Color(0xFFFE9B48);
const lightBlue = Color(0xFF7395CF);
const darkBlue = Color(0xFF3C5073);
const neviBlue = Color(0xFF45597A);
const darkestBlue = Color(0xFF1E2843);
const defaultPadding = 20.0;

View File

@ -1,3 +1,8 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
class Data {
static const parkDetail = {
"elephant": {
@ -90,4 +95,45 @@ class Data {
'swan': 899,
'squirrel': 399
};
Map<String, dynamic> images = {
'0': 'assets/images/1.png',
'1': 'assets/images/2.png',
'2': 'assets/images/3.png',
'3': 'assets/images/4.png',
'4': 'assets/images/5.png',
'5': 'assets/images/6.png',
'6': 'assets/images/7.png',
'7': 'assets/images/8.png',
'8': 'assets/images/9.png',
'9': 'assets/images/10.png',
};
List<Color> colors = [
lightBlue,
lightAccentBlue,
darkAccentBlue,
darkOrange,
lightOrange,
Colors.pinkAccent,
Colors.purpleAccent,
Colors.greenAccent,
neviBlue,
Colors.tealAccent
];
List<String> tags = [
'Study',
'Productive',
'Work',
'Personal',
'Health',
'Home',
'Errands',
'Social',
'Finance',
'Hobby',
'Family',
'Self-care',
'Tech',
'Creative',
];
}

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/login/login.dart';
import '../screens/landing/zt_landing.dart';
import '../screens/landing/landing.dart';
import '../screens/mine/useinfo/userinfo.dart';
class RouteConfig {

View File

@ -0,0 +1,60 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/models/task_model.dart';
import 'package:sk_base_mobile/util/util.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
class DbHelper {
Database? _db;
Future<Database?> get db async {
if (_db != null) {
return _db;
}
final directory = Platform.isAndroid
? await getExternalStorageDirectory()
: await getApplicationSupportDirectory();
String path = join(directory!.path, 'db');
var db = await openDatabase(
path,
version: 1,
onCreate: (db, version) {
db.execute(
"CREATE TABLE Tasks(key TEXT PRIMARY KEY,title TEXT,category TEXT,description TEXT,image TEXT,date TEXT,startTime TEXT,periority TEXT,show TEXT,endTime TEXT,status,TEXT)");
},
);
return db;
}
Future<TaskModel> insert(TaskModel model) async {
var dbClient = await db;
dbClient!.insert('Tasks', model.toMap()).then((value) {});
return model;
}
Future<int> delete(String id, String table) async {
var dbClient = await db;
return await dbClient!
.delete(table, where: 'key = ?', whereArgs: [id]).then((value) {
SnackBarUtil().success(
'Deleted',
message: 'Task is removed successfully',
);
return value;
});
}
Future<int> update(String id, String key, String value) async {
var dbClient = await db;
return await dbClient!
.update('Tasks', {key: value}, where: 'key = ?', whereArgs: [id]);
}
Future<List<TaskModel>> getData() async {
var dbClient = await db;
final List<Map<String, Object?>> queryResult =
await dbClient!.query('Tasks');
return queryResult.map((e) => TaskModel.fromMap(e)).toList();
}
}

View File

@ -0,0 +1,58 @@
import 'dart:core';
class TaskModel {
String? key;
String? title;
String? category;
String? description;
String? image;
String? periority;
String? startTime;
String? endTime;
String? date;
String? show;
String? status;
TaskModel(
{ required this.key,
required this.startTime,
required this.endTime,
required this.date,
required this.periority,
required this.description,
required this.category,
required this.title,
required this.image,
required this.show,
required this.status});
TaskModel.fromMap(Map<String, dynamic> res) {
key = res['key'];
title = res['title'];
category = res['category'];
description = res['description'];
image = res['image'];
periority = res['periority'];
show = res['show'];
startTime = res['startTime'];
endTime = res['endTime'];
date = res['date'];
status=res['status'];
}
Map<String, Object?> toMap() {
return {
'key': key,
'title': title,
'category': category,
'description': description,
'image': image,
'periority': periority,
'startTime': startTime,
'endTime': endTime,
'date': date,
'show': show,
'status' : status,
};
}
}

View File

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/components/change_icon.dart';
import 'package:sk_base_mobile/screens/home/components/today_button.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class ChangeButtonRow extends StatelessWidget {
ChangeButtonRow({super.key});
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(
horizontal: MediaQuery.sizeOf(context).width * 0.06),
child: Row(
children: [
TodayButton(),
Spacer(),
InkWell(
onTap: () => controller.onMoveBack(),
child: ChangeIconButton(
icon: Icon(
Icons.arrow_back_ios_rounded,
color: Colors.white,
size: 15,
))),
SizedBox(
width: defaultPadding / 2,
),
InkWell(
onTap: () => controller.onMoveNextPage(),
child: ChangeIconButton(
icon: Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.white,
size: 15,
))),
],
),
);
}
}

View File

@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
class ChangeIconButton extends StatelessWidget {
const ChangeIconButton({super.key, required this.icon});
final Widget icon;
@override
Widget build(BuildContext context) {
return Container(
height: 40,
width: 40,
alignment: Alignment.center,
decoration:
BoxDecoration(shape: BoxShape.circle, color: neviBlue, boxShadow: [
BoxShadow(
color: neviBlue.withOpacity(.3),
offset: Offset(0, 10),
blurRadius: 10)
]),
child: icon,
);
}
}

View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class CustomAppBar extends StatelessWidget {
CustomAppBar({super.key});
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
children: [
if (ScreenAdaper.isLandspace()) Spacer(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hello,',
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Colors.black87,
fontWeight: FontWeight.w400,
height: 0,
letterSpacing: 2,
fontSize: 18),
),
Obx(
() => Text(
controller.name.value,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Colors.black,
fontWeight: FontWeight.bold,
letterSpacing: 2,
height: 0,
fontSize: 25),
),
)
],
),
const Spacer(
flex: 10,
),
Container(
height: 50,
width: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: darkAccentBlue,
boxShadow: const [
BoxShadow(
color: lightAccentBlue,
blurRadius: 20,
offset: Offset(0, 10))
]),
child: const Icon(
Icons.account_circle_outlined,
color: Colors.white,
),
),
if (ScreenAdaper.isLandspace()) const Spacer(),
],
),
);
}
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
import 'dates.dart';
class DateContainer extends StatelessWidget {
final int index;
DateContainer({super.key, required this.index});
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
var size = MediaQuery.sizeOf(context);
return Obx(() => AnimatedContainer(
duration: const Duration(milliseconds: 200),
height: 110,
width: 70,
margin: EdgeInsets.only(left: size.width * 0.05),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
gradient: controller.currentIndex.value == index
? const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [lightOrange, darkOrange])
: null,
boxShadow: [
controller.currentIndex.value == index
? const BoxShadow(
color: lightOrange, offset: Offset(0, 10), blurRadius: 20)
: const BoxShadow(
color: Colors.black12,
offset: Offset(0, 10),
blurRadius: 20)
]),
child: Dates(index: index)));
}
}

View File

@ -0,0 +1,55 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
import 'package:sk_base_mobile/util/util.dart';
class Dates extends StatelessWidget {
Dates({super.key, required this.index});
final int index;
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(
() => Text(
DateUtil.getMonth(DateTime.now().add(Duration(days: index))),
style: TextStyle(
color: controller.currentIndex.value == index
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 13,
height: 0),
),
),
Obx(
() => Text(
DateUtil.getDate(DateTime.now().add(Duration(days: index))),
style: TextStyle(
color: controller.currentIndex.value == index
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 26,
height: 0),
),
),
Obx(
() => Text(
DateUtil.getDay(DateTime.now().add(Duration(days: index))),
style: TextStyle(
color: controller.currentIndex.value == index
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 13),
),
)
],
);
}
}

View File

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
class Responsive extends StatelessWidget {
const Responsive({super.key, required this.tablet, required this.mobile, required this.largeTablet});
final Widget tablet;
final Widget mobile;
final Widget largeTablet;
static bool isTablet(BuildContext context){
return MediaQuery.sizeOf(context).width>500;
}
static bool isLargeTablet(BuildContext context){
return MediaQuery.sizeOf(context).width>1000;
}
@override
Widget build(BuildContext context) {
var size=MediaQuery.sizeOf(context);
if(size.width >1000){
return largeTablet;
}
else if(size.width >500){
return tablet;
}else{
return mobile;
}
}
}

View File

@ -0,0 +1,68 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/data.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class TaskTitle extends StatelessWidget {
TaskTitle({super.key, required this.index, required this.ind});
final int index;
final int ind;
final int randomColor1 = Random().nextInt(9);
final int randomColor2 = Random().nextInt(9);
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
controller.list[ind][index].title,
style: const TextStyle(
color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20),
),
Text(
'${controller.list[ind][index].startTime} - ${controller.list[ind][index].endTime}',
style: const TextStyle(
color: Colors.grey, fontWeight: FontWeight.w300, fontSize: 12),
),
const SizedBox(
height: defaultPadding / 2,
),
Row(
children: [
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 10),
decoration: BoxDecoration(
color: Data().colors[randomColor1].withOpacity(.5),
borderRadius: BorderRadius.circular(10),
),
child: Text(
Data().tags[Random().nextInt(13)],
style: TextStyle(color: Data().colors[randomColor1]),
),
),
const SizedBox(
width: defaultPadding / 2,
),
Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 10),
decoration: BoxDecoration(
color: Data().colors[randomColor2].withOpacity(.5),
borderRadius: BorderRadius.circular(10)),
child: Text(
Data().tags[Random().nextInt(13)],
style: TextStyle(color: Data().colors[randomColor2]),
),
)
],
),
],
);
}
}

View File

@ -0,0 +1,153 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/data.dart';
import 'package:sk_base_mobile/screens/home/components/task_detail_col.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
import 'package:sk_base_mobile/util/util.dart';
class TaskDetailContainer extends StatelessWidget {
TaskDetailContainer({super.key, required this.index, required this.ind});
final int index;
final int ind;
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Dismissible(
key: UniqueKey(),
confirmDismiss: (direction) async {
return await ModalUtil.showWarningDialog(
'Remove Task', 'Are you sure to remove this task', 'Confirm', () {
controller.db.delete(controller.list[ind][index].key, 'Tasks');
controller.list[ind].remove(controller.list[ind][index]);
});
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: lightAccentBlue.withOpacity(.5),
offset: Offset(0, 5),
blurRadius: 10),
], color: Colors.white, borderRadius: BorderRadius.circular(30)),
child: Row(
children: [
Image.asset(
Data().images[controller.list[ind][index].image],
height: 100,
width: 100,
),
const Spacer(
flex: 1,
),
TaskTitle(index: index, ind: ind),
const Spacer(
flex: 2,
),
controller.list[ind][index].status == 'complete'
? Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
lightOrange,
darkOrange,
]),
boxShadow: [
BoxShadow(
color: lightOrange,
offset: Offset(0, 10),
blurRadius: 10)
]),
child: const Icon(
Icons.done,
color: Colors.white,
),
)
: Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: PopupMenuButton(
onSelected: (value) => controller.onTaskComplete(
value,
index,
ind,
controller.list[ind][index].key,
context),
surfaceTintColor: Colors.white,
padding: EdgeInsets.zero,
icon: const Icon(
Icons.more_vert_rounded,
color: Colors.grey,
size: 24,
),
shape: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide.none,
),
itemBuilder: (context) {
return [
const PopupMenuItem(
height: 25,
value: 1,
child: Row(
children: [
Icon(
Icons.edit_note,
color: Colors.orange,
size: 14,
),
SizedBox(
width: defaultPadding / 2,
),
Text('Edit')
],
)),
const PopupMenuItem(
height: 25,
value: 2,
child: Row(
children: [
Icon(
Icons.delete_outline,
color: Colors.orange,
size: 14,
),
SizedBox(
width: defaultPadding / 2,
),
Text('Delete')
],
)),
const PopupMenuItem(
height: 25,
value: 3,
child: Row(
children: [
Icon(
Icons.done_all_outlined,
color: Colors.orange,
size: 14,
),
SizedBox(
width: defaultPadding / 2,
),
Text('Complete')
],
)),
];
},
)),
),
],
),
),
);
}
}

View File

@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/home/components/responsive.dart';
import 'package:sk_base_mobile/screens/home/components/task_detail_container.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class TaskList extends StatelessWidget {
const TaskList({super.key, required this.index});
final int index;
@override
Widget build(BuildContext context) {
return Responsive(
tablet: Grid(
crossAsis: 2,
ratio: 3,
ind: index,
),
largeTablet: Grid(
crossAsis: 3,
ratio: 3,
ind: index,
),
mobile: Grid(
ratio: 3,
crossAsis: 1,
ind: index,
));
}
}
class Grid extends StatelessWidget {
final int crossAsis;
final double ratio;
final int ind;
final controller = Get.put(HomeController());
Grid(
{super.key,
required this.crossAsis,
required this.ratio,
required this.ind});
@override
Widget build(BuildContext context) {
return Obx(() => controller.list[ind].isEmpty
? const Center(
child: Text(
'No Task Today',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
)
: GridView.builder(
padding: const EdgeInsets.only(top: 40),
itemCount: controller.list[ind].length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAsis, childAspectRatio: ratio),
itemBuilder: (context, index) {
return TaskDetailContainer(
index: index,
ind: ind,
);
},
));
}
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/home/components/task_list.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class TaskPageView extends StatelessWidget {
TaskPageView({super.key});
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return PageView(
physics: const NeverScrollableScrollPhysics(),
controller: controller.pageController,
children: const [
TaskList(
index: 0,
),
TaskList(
index: 1,
),
TaskList(
index: 2,
),
TaskList(
index: 3,
),
TaskList(
index: 4,
),
TaskList(
index: 5,
),
TaskList(
index: 6,
),
],
);
}
}

View File

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/screens/home/components/change_button_roe.dart';
import 'package:sk_base_mobile/screens/home/components/task_page_View.dart';
class TaskPageBody extends StatelessWidget {
const TaskPageBody({super.key});
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned.fill(
child: Container(
margin: const EdgeInsets.only(top: 25),
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(40), topLeft: Radius.circular(40)),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white.withOpacity(.6),
Colors.white.withOpacity(.5),
Colors.white.withOpacity(.4),
Colors.white.withOpacity(.3),
Colors.white.withOpacity(.2),
Colors.white.withOpacity(.0),
Colors.white.withOpacity(.0),
Colors.white.withOpacity(.0),
Colors.white.withOpacity(.0),
Colors.white.withOpacity(.0),
])),
child: TaskPageView(),
)),
ChangeButtonRow(),
],
);
}
}

View File

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class TodayButton extends StatelessWidget {
const TodayButton({super.key});
@override
Widget build(BuildContext context) {
final controller = Get.put(HomeController());
return InkWell(
borderRadius: BorderRadius.circular(30),
onTap: () => controller.pageController.animateToPage(0,
duration: Duration(milliseconds: 300), curve: Curves.easeIn),
child: Container(
height: 50,
width: 150,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
boxShadow: const [
BoxShadow(
color: lightAccentBlue, offset: Offset(0, 5), blurRadius: 20)
],
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [lightAccentBlue, darkAccentBlue])),
child: const Text(
'Today',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/components/custom_app_bar.dart';
import 'package:sk_base_mobile/screens/home/components/date_container.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
class UperBody extends StatelessWidget {
UperBody({super.key});
final controller = Get.put(HomeController());
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(
height: defaultPadding,
),
CustomAppBar(),
SizedBox(
height: 150,
child: ListView.builder(
controller: controller.scrollController,
itemCount: 7,
shrinkWrap: true,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(bottom: 30, top: defaultPadding),
itemBuilder: (context, index) {
return InkWell(
borderRadius: BorderRadius.circular(20),
onTap: () => controller.setIndex(index),
child: DateContainer(index: index),
);
},
),
),
],
);
}
}

View File

@ -1,13 +1,20 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/screens/home/components/task_page_holder.dart';
import 'package:sk_base_mobile/screens/home/components/upper_body.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('首页')),
body: SizedBox(child: Text('sss')),
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
UperBody(),
const Expanded(
child: TaskPageBody(),
),
],
);
}
}

View File

@ -0,0 +1,107 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
import 'package:sk_base_mobile/util/modal.util.dart';
class HomeController extends GetxController {
RxMap userData = {}.obs;
RxString name = ''.obs;
RxInt currentIndex = 0.obs;
final PageController pageController = PageController();
final DateTime dateTime = DateTime.now();
final DbHelper db = DbHelper();
List<RxList> list = [
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
].obs;
RxInt barIndex = 0.obs;
RxList model = [].obs;
final ScrollController scrollController = ScrollController();
HomeController() {
if (userData['NAME'] == null) {
getUserData();
}
}
getUserData() async {
getName();
}
getName() {}
getTasks() async {
db.getData().then((value) {
model.value = value;
getSepretLists();
});
}
setIndex(int value) {
pageController.animateToPage(value,
duration: const Duration(milliseconds: 300), curve: Curves.easeIn);
currentIndex.value = value;
}
getDateAccordingTabs(int value) {}
getSepretLists() {
// List<RxList<dynamic>> tempList = [];
// for (int i = 0; i < 7; i++) {
// RxList tempList1 = [].obs;
// tempList1.clear();
// for (int j = 0; j < model.length; j++) {
// if (model[j].date == getDateAccordingTabs(i)) {
// tempList1.add(model[j]);
// }
// }
// tempList.add(tempList1);
// }
// list = tempList;
}
onMoveNextPage() {
if (currentIndex.value < 7) {
setIndex(currentIndex.value + 1);
}
}
onMoveBack() {
if (currentIndex.value > 0) {
setIndex(currentIndex.value - 1);
}
}
onTaskComplete(
int value, int index, int ind, String key, BuildContext context) {
switch (value) {
case 3:
{
ModalUtil.showWarningDialog('Complete Task',
'This task will be marked as completed', 'Confirm', () {
list[ind][index].status = 'complete';
list[ind].add('');
list[ind].remove('');
db.update(key, 'status', 'complete');
});
}
case 2:
{
ModalUtil.showWarningDialog(
'Delete Task', 'Are you want to sure to remove', 'Confirm', () {
list[ind].remove(list[ind][index]);
db.delete(
key,
'Tasks',
);
});
}
}
}
}

View File

@ -0,0 +1,29 @@
// import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/landing/landing_controller.dart';
import 'package:sk_base_mobile/widgets/back_decoration.dart';
import 'package:sk_base_mobile/widgets/bottom_nav_bar.dart';
import 'package:sk_base_mobile/widgets/floating_action.dart';
class LandingPage extends StatelessWidget {
LandingPage({super.key});
final controller = Get.put<LandingController>(LandingController());
@override
Widget build(BuildContext context) {
return Material(
child: Stack(children: [
const BackColors(),
SafeArea(
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: const FloatingButton(),
bottomNavigationBar: BottomNavBar(),
backgroundColor: Colors.transparent,
body: Obx(() => controller.pages[controller.currentIndex.value]),
))
]));
}
}

View File

@ -0,0 +1,119 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
import 'package:sk_base_mobile/services/app_info.service.dart';
class LandingController extends GetxController {
RxMap userData = {}.obs;
RxString name = ''.obs;
RxInt currentIndex = 0.obs;
final PageController pageController = PageController();
final DateTime dateTime = DateTime.now();
List<IconData> iconList = [Icons.home_max, Icons.person_outline_rounded];
List<RxList> list = [
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
[].obs,
].obs;
RxList model = [].obs;
final ScrollController scrollController = ScrollController();
RxList bottomNavItems = RxList<BottomNavigationBarItem>([]);
List<Widget> pages = [];
@override
onInit() {
super.onInit();
List<AppBottomNavItem> roleWithBottomNavItems =
AppInfoService.to.bottomNavItems!;
bottomNavItems.assignAll(roleWithBottomNavItems
.map((e) => BottomNavigationBarItem(
icon: e.icon, activeIcon: e.activeIcon, label: e.label))
.toList());
pages = roleWithBottomNavItems.map((e) => e.page!).toList();
}
getUserData() async {
getName();
}
getName() {
// name.value = userData['NAME'];
}
getTasks() async {
// db.getData().then((value) {
// model.value = value;
// getSepretLists();
// });
}
setIndex(int value) {
pageController.animateToPage(value,
duration: const Duration(milliseconds: 300), curve: Curves.easeIn);
currentIndex.value = value;
}
// getDateAccordingTabs(int value) {
// return '${Utils.addPrefix(dateTime.add(Duration(days: value)).day.toString())}/${Utils.addPrefix(dateTime.add(Duration(days: value)).month.toString())}/${Utils.addPrefix(dateTime.add(Duration(days: value)).year.toString())}';
// }
getSepretLists() {
// List<RxList<dynamic>> tempList = [];
// for (int i = 0; i < 7; i++) {
// RxList tempList1 = [].obs;
// tempList1.clear();
// for (int j = 0; j < model.length; j++) {
// if (model[j].date == getDateAccordingTabs(i)) {
// tempList1.add(model[j]);
// }
// }
// tempList.add(tempList1);
// }
// list = tempList;
}
onMoveNextPage() {
if (currentIndex.value < 7) {
setIndex(currentIndex.value + 1);
}
}
onMoveBack() {
if (currentIndex.value > 0) {
setIndex(currentIndex.value - 1);
}
}
onTaskComplete(
int value, int index, int ind, String key, BuildContext context) {
// switch (value) {
// case 3:
// {
// Utils.showWarningDialog(context, 'Complete Task',
// 'This task will be marked as completed', 'Confirm', () {
// list[ind][index].status = 'complete';
// list[ind].add('');
// list[ind].remove('');
// db.update(key, 'status', 'complete');
// });
// }
// case 2:
// {
// Utils.showWarningDialog(context, 'Delete Task',
// 'Are you want to sure to remove', 'Confirm', () {
// list[ind].remove(list[ind][index]);
// db.delete(
// key,
// 'Tasks',
// );
// });
// }
// }
}
}

View File

@ -1,63 +0,0 @@
// import 'dart:io';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../models/app_bottom_nav_item.dart';
import '../../services/app_info.service.dart';
import '../../util/util.dart';
class LandingPage extends StatefulWidget {
LandingPage({Key? key}) : super(key: key);
@override
_LandingPageState createState() => _LandingPageState();
}
class _LandingPageState extends State<LandingPage> {
int _selectedLanding = 0;
List<BottomNavigationBarItem> bottomNavItems = [];
List<Widget> pages = [];
@override
Widget build(BuildContext context) {
// ScreenUtil.init(
// BoxConstraints(
// maxWidth: MediaQuery.of(context).size.width,
// maxHeight: MediaQuery.of(context).size.height),
// designSize: const Size(414, 896),
// orientation: Orientation.portrait,
// context: context,
// );
List<AppBottomNavItem> roleWithBottomNavItems =
AppInfoService.to.bottomNavItems!;
bottomNavItems = roleWithBottomNavItems
.map((e) => BottomNavigationBarItem(
icon: e.icon, activeIcon: e.activeIcon, label: e.label))
.toList();
pages = roleWithBottomNavItems.map((e) => e.page!).toList();
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
iconSize: ScreenAdaper.sp(40),
type: BottomNavigationBarType.fixed,
items: bottomNavItems,
showSelectedLabels: true,
showUnselectedLabels: true,
currentIndex: _selectedLanding,
onTap: (landing) {
_onItemTapped(landing);
},
),
body: pages[_selectedLanding],
);
}
void _onItemTapped(int landing) {
if (landing != _selectedLanding) {
setState(() {
_selectedLanding = landing;
});
}
}
}

View File

@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class CategoryInput extends StatelessWidget {
CategoryInput({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: defaultPadding / 2,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Text(
'Category',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
),
Obx(
() => TextInputField(
controller: controller.category.value,
hint: 'Select Category',
focus: controller.categoryFocus.value,
onTap: () => controller.setCategoryFocus(),
),
)
],
),
);
}
}

View File

@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class DateTimeInput extends StatelessWidget {
DateTimeInput({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Date',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
const SizedBox(
height: defaultPadding / 2,
),
InkWell(
onTap: () => controller.showDatePick(context),
child: Obx(() => DateTimeContainer(
text: controller.selectedDate.isEmpty
? 'dd/mm/yyyy'
: controller.selectedDate.value)))
],
),
const Spacer(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'S-Time',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
const SizedBox(
height: defaultPadding / 2,
),
InkWell(
onTap: () => controller.picStartTime(context),
child: Obx(() => DateTimeContainer(
text: controller.startTime.isEmpty
? "hh:mm:a"
: controller.startTime.value)))
],
),
const Spacer(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'E-Time',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
const SizedBox(
height: defaultPadding / 2,
),
InkWell(
onTap: () => controller.picEndTime(context),
child: Obx(() => DateTimeContainer(
text: controller.endTime.isEmpty
? "hh:mm:a"
: controller.endTime.value)))
],
),
],
),
);
}
}
class DateTimeContainer extends StatelessWidget {
const DateTimeContainer({super.key, required this.text});
final String text;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(.2),
borderRadius: BorderRadius.circular(20),
),
child: Row(
children: [
Icon(
Icons.date_range,
color: darkBlue,
size: 16,
),
SizedBox(
width: defaultPadding / 4,
),
Text(text),
],
),
);
}
}

View File

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class DescriptionInput extends StatelessWidget {
final controller = Get.put(NewTaskController());
DescriptionInput({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: defaultPadding / 2,
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Text(
'Description',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
),
Obx(() => TextInputField(
controller: controller.description.value,
hint: 'Description (Optional)',
focus: controller.descriptionFocus.value,
onTap: () => controller.setDescriptionFocus(),
))
],
),
);
}
}

View File

@ -0,0 +1,99 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/constants/constants.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class SelectImageList extends StatelessWidget {
SelectImageList({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: defaultPadding,
),
Align(
alignment: Alignment.topCenter,
child: Container(
height: 4,
width: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient:
const LinearGradient(colors: [lightOrange, darkOrange])),
),
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Text(
'Illustrations',
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.w600, fontSize: 20),
),
),
SizedBox(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
controller.changeImage(index);
},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
Obx(
() => AnimatedContainer(
duration: const Duration(milliseconds: 300),
padding: const EdgeInsets.all(2),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient:
controller.selectedImage.value == index
? const LinearGradient(colors: [
lightAccentBlue,
lightAccentBlue,
])
: null,
boxShadow:
controller.selectedImage.value == index
? const [
BoxShadow(
color: lightAccentBlue,
blurRadius: 10,
offset: Offset(0, 5),
),
]
: null),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20)),
child: Image.asset(
Data().images['$index'],
height: 80,
width: 80,
))),
),
Obx(
() => controller.selectedImage.value == index
? const Icon(Icons.keyboard_arrow_up,
color: Colors.orange)
: const SizedBox(),
)
],
)),
);
},
),
),
],
);
}
}

View File

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/components/periority_container.dart';
import 'package:sk_base_mobile/screens/new_task/components/text_input.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class LabelInput extends StatelessWidget {
LabelInput({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Lable',
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold),
),
const SizedBox(
height: defaultPadding / 2,
),
Obx(
() => TextInputField(
controller: controller.label.value,
hint: 'Enter Label',
onTap: () => controller.setLabelFocus(),
focus: controller.labelFocus.value),
),
],
),
),
const SizedBox(
width: defaultPadding,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Periority',
style:
TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
),
const SizedBox(
height: defaultPadding / 2,
),
Row(
children: [
Obx(
() => InkWell(
onTap: () => controller.lowPeriority.value = true,
child: PeriorityContainer(
text: 'Low',
selected: controller.lowPeriority.value)),
),
const SizedBox(
width: defaultPadding / 2,
),
Obx(
() => InkWell(
onTap: () => controller.lowPeriority.value = false,
child: PeriorityContainer(
text: 'High',
selected: !controller.lowPeriority.value)),
)
],
)
],
),
],
),
);
}
}

View File

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
class PeriorityContainer extends StatelessWidget {
final String text;
final bool selected;
const PeriorityContainer(
{super.key, required this.text, required this.selected});
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 300),
padding: EdgeInsets.all(selected ? 3 : 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: selected ? Colors.orange : Colors.black12),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: selected ? Colors.white : Colors.transparent,
borderRadius: BorderRadius.circular(30),
),
child: Text(
text,
style: TextStyle(color: darkAccentBlue, fontWeight: FontWeight.bold),
),
),
);
}
}

View File

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class CreateTaskButton extends StatelessWidget {
CreateTaskButton({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return Container(
height: 60,
alignment: Alignment.center,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(80), topLeft: Radius.circular(80)),
gradient: LinearGradient(colors: [
lightOrange,
darkOrange,
darkOrange,
])),
child: Obx(
() => controller.loading.value
? Container(
height: 15,
width: 15,
child: const CircularProgressIndicator(
color: Colors.white,
),
)
: const Text(
'Create Task',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16),
),
));
}
}

View File

@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
class TextInputField extends StatelessWidget {
final TextEditingController controller;
final String hint;
final bool focus;
final VoidCallback onTap;
TextInputField(
{super.key,
required this.controller,
required this.hint,
required this.focus,
required this.onTap});
final taskController = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: const Duration(milliseconds: 300),
height: 50,
width: double.infinity,
padding: EdgeInsets.all(focus ? 2 : 1),
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: focus ? darkOrange : Colors.grey),
child: TextFormField(
controller: controller,
onTapOutside: (event) {
FocusScope.of(context).unfocus();
taskController.onTapOutside();
},
onTap: onTap,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 20),
hintText: hint,
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide.none),
hintStyle: TextStyle(color: Colors.grey, fontSize: 12),
),
),
);
}
}

View File

@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/screens/new_task/components/category_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/date_time.dart';
import 'package:sk_base_mobile/screens/new_task/components/description_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/illustration_list.dart';
import 'package:sk_base_mobile/screens/new_task/components/lable_input.dart';
import 'package:sk_base_mobile/screens/new_task/components/task_button.dart';
import 'package:sk_base_mobile/screens/new_task/new_task_controller.dart';
import 'package:sk_base_mobile/screens/home/components/responsive.dart';
class NewTask extends StatelessWidget {
NewTask({super.key});
final controller = Get.put(NewTaskController());
@override
Widget build(BuildContext context) {
return ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(
30,
),
topRight: Radius.circular(30)),
child: Container(
height: 650,
width: Responsive.isLargeTablet(context)
? MediaQuery.sizeOf(context).width / 2.5
: Responsive.isTablet(context)
? MediaQuery.sizeOf(context).width / 1.6
: MediaQuery.sizeOf(context).width,
decoration: const BoxDecoration(
color: Colors.white,
),
child: Stack(
children: [
Positioned.fill(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SelectImageList(),
LabelInput(),
CategoryInput(),
DescriptionInput(),
DateTimeInput(),
],
),
),
),
GestureDetector(
onTap: () => controller.insertTask(context),
child: CreateTaskButton())
],
))
],
)),
);
}
}

View File

@ -0,0 +1,143 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/db_helper/dbHelper.dart';
import 'package:sk_base_mobile/models/task_model.dart';
import 'package:sk_base_mobile/screens/home/home_controller.dart';
import 'package:sk_base_mobile/util/util.dart';
class NewTaskController extends GetxController {
DateTime? pickedDate;
final DbHelper db = DbHelper();
RxInt selectedImage = 0.obs;
RxBool lowPeriority = false.obs;
RxBool labelFocus = false.obs;
RxBool categoryFocus = false.obs;
RxBool descriptionFocus = false.obs;
RxString selectedDate = ''.obs;
RxString startTime = ''.obs;
RxString endTime = ''.obs;
RxBool loading = false.obs;
final homeController = Get.put(HomeController());
final label = TextEditingController().obs;
final description = TextEditingController().obs;
final category = TextEditingController().obs;
picStartTime(BuildContext context) async {
var picker =
await showTimePicker(context: context, initialTime: TimeOfDay.now());
if (picker != null) {
startTime.value =
'${DateUtil.addPrefix(picker.hourOfPeriod.toString())}:${DateUtil.addPrefix(picker.minute.toString())}:${picker.period.name.toUpperCase()}';
}
}
picEndTime(BuildContext context) async {
var picker =
await showTimePicker(context: context, initialTime: TimeOfDay.now());
if (picker != null) {
endTime.value =
'${DateUtil.addPrefix(picker.hourOfPeriod.toString())}:${DateUtil.addPrefix(picker.minute.toString())}:${picker.period.name.toUpperCase()}';
}
}
showDatePick(BuildContext context) async {
var picker = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 7)));
if (picker != null) {
pickedDate = picker;
selectedDate.value =
'${DateUtil.addPrefix(picker.day.toString())}/${DateUtil.addPrefix(picker.month.toString())}/${picker.year}';
}
}
changeImage(int index) {
selectedImage.value = index;
}
setLabelFocus() {
labelFocus.value = true;
categoryFocus.value = false;
descriptionFocus.value = false;
}
setCategoryFocus() {
labelFocus.value = false;
categoryFocus.value = true;
descriptionFocus.value = false;
}
setDescriptionFocus() {
labelFocus.value = false;
categoryFocus.value = false;
descriptionFocus.value = true;
}
onTapOutside() {
labelFocus.value = false;
categoryFocus.value = false;
descriptionFocus.value = false;
}
insertTask(BuildContext context) {
if (label.value.text.toString().isEmpty) {
SnackBarUtil().warning(
'Warning',
message: 'Enter valid label',
);
return;
}
if (category.value.text.toString().isEmpty) {
SnackBarUtil().warning(
'Warning',
message: 'Enter Correct Category',
);
return;
}
if (selectedDate.isEmpty) {
// selectedDate.value =
// '${Utils.addPrefix(DateTime.now().day.toString())}/${Utils.addPrefix(DateTime.now().month.toString())}/${Utils.addPrefix(DateTime.now().year.toString())}';
showDatePick(context);
}
if (startTime.isEmpty) {
picStartTime(context);
return;
}
if (endTime.isEmpty) {
picEndTime(context);
return;
}
loading.value = true;
db
.insert(TaskModel(
key: DateTime.now().microsecondsSinceEpoch.toString(),
startTime: startTime.value,
endTime: endTime.value,
date: selectedDate.value,
periority: lowPeriority.value ? 'Low' : 'High',
description: description.value.text.toString(),
category: category.value.text.toString(),
title: label.value.text.toString(),
image: selectedImage.value.toString(),
show: 'yes',
status: 'unComplete'))
.then((value) {
Duration dif = pickedDate!.difference(DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day));
homeController.list[dif.inDays].add(value);
Timer(const Duration(seconds: 1), () {
loading.value = false;
Get.back();
SnackBarUtil().success(
'Successful',
message: 'Task is created',
);
});
});
}
}

28
lib/util/date.util.dart Normal file
View File

@ -0,0 +1,28 @@
import 'package:date_format/date_format.dart';
class DateUtil {
static String getMonth(DateTime date) {
String formattedDate = formatDate(date, ['MMM']);
return formattedDate;
}
static String getDate(DateTime date) {
String formattedDate = formatDate(date, ['d']);
if (formattedDate.length == 1) {
formattedDate = '0$formattedDate';
}
return formattedDate;
}
static String getDay(DateTime date) {
String formattedDate = formatDate(date, ['EEE']);
return formattedDate;
}
static String addPrefix(String string) {
if (string.length == 1) {
string = '0$string';
}
return string;
}
}

43
lib/util/modal.util.dart Normal file
View File

@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
class ModalUtil {
static Future<bool> showWarningDialog(
String title, String msg, String button, VoidCallback onConfirm) async {
bool confirmed = false;
await showDialog(
context: Get.overlayContext!,
builder: (context) {
return AlertDialog(
title: Text(title),
content: Text(msg),
actions: [
TextButton(
child: const Text(
'Cancel',
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(context).pop();
confirmed = false;
},
),
TextButton(
child: Text(
button,
style: TextStyle(color: Colors.orange),
),
onPressed: () {
onConfirm();
Navigator.pop(context);
confirmed = true;
},
),
],
);
},
);
return confirmed;
}
}

View File

@ -6,3 +6,5 @@ export 'media_util.dart';
export 'photo_picker_util.dart';
export 'screen_adaper_util.dart';
export 'validator_util.dart';
export 'date.util.dart';
export 'modal.util.dart';

View File

@ -0,0 +1,165 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class BackColors extends StatelessWidget {
const BackColors({super.key});
@override
Widget build(BuildContext context) {
var size = MediaQuery.sizeOf(context);
return Container(
color: Colors.white,
margin: EdgeInsets.only(top: 30),
child: Stack(
children: [
Positioned(
top: 100,
child: Container(
height: size.height * 0.5,
width: size.width * 0.5,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
lightOrange.withOpacity(.0),
lightOrange.withOpacity(.1),
lightOrange.withOpacity(.2),
lightOrange.withOpacity(.3),
lightOrange.withOpacity(.4),
lightOrange.withOpacity(.4),
lightOrange.withOpacity(.3),
lightOrange.withOpacity(.2),
lightOrange.withOpacity(.1),
lightOrange.withOpacity(0),
])),
)),
Positioned(
top: 100,
right: -50,
child: Container(
height: size.height * 0.5,
width: size.width * 0.3,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
lightOrange.withOpacity(.0),
lightOrange.withOpacity(.1),
lightOrange.withOpacity(.2),
lightOrange.withOpacity(.3),
lightOrange.withOpacity(.2),
lightOrange.withOpacity(.1),
lightOrange.withOpacity(0),
])),
)),
Positioned(
bottom: 100,
right: -50,
child: Container(
height: size.height * 0.5,
width: size.width * 0.6,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
lightAccentBlue.withOpacity(.0),
lightAccentBlue.withOpacity(.1),
lightAccentBlue.withOpacity(.2),
lightAccentBlue.withOpacity(.3),
lightAccentBlue.withOpacity(.4),
lightAccentBlue.withOpacity(.4),
lightAccentBlue.withOpacity(.3),
lightAccentBlue.withOpacity(.2),
lightAccentBlue.withOpacity(.1),
lightAccentBlue.withOpacity(0),
])),
)),
Positioned(
bottom: -30,
child: Container(
height: size.height * 0.3,
width: size.width * 0.6,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
lightAccentBlue.withOpacity(.0),
lightAccentBlue.withOpacity(.1),
lightAccentBlue.withOpacity(.2),
lightAccentBlue.withOpacity(.3),
lightAccentBlue.withOpacity(.4),
lightAccentBlue.withOpacity(.4),
lightAccentBlue.withOpacity(.3),
lightAccentBlue.withOpacity(.2),
lightAccentBlue.withOpacity(.1),
lightAccentBlue.withOpacity(0),
])),
)),
Positioned(
bottom: 1,
left: 1,
top: !ScreenAdaper.isLandspace() ? 100 : 200,
right: 1,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
Colors.pinkAccent.withOpacity(.0),
Colors.pinkAccent.withOpacity(.1),
Colors.pinkAccent.withOpacity(.2),
Colors.pinkAccent.withOpacity(.3),
Colors.pinkAccent.withOpacity(.4),
Colors.pinkAccent.withOpacity(.4),
Colors.pinkAccent.withOpacity(.3),
Colors.pinkAccent.withOpacity(.2),
Colors.pinkAccent.withOpacity(.1),
Colors.pinkAccent.withOpacity(0),
])),
)),
Positioned(
bottom: 1,
right: 1,
child: Container(
height: size.height * 0.3,
width: size.width * 0.6,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.centerRight,
colors: [
Colors.greenAccent.withOpacity(.0),
Colors.greenAccent.withOpacity(.1),
Colors.greenAccent.withOpacity(.2),
Colors.greenAccent.withOpacity(.3),
Colors.greenAccent.withOpacity(.4),
Colors.greenAccent.withOpacity(.4),
Colors.greenAccent.withOpacity(.3),
Colors.greenAccent.withOpacity(.2),
Colors.greenAccent.withOpacity(.1),
Colors.greenAccent.withOpacity(0),
])),
)),
Positioned.fill(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaY: 30, sigmaX: 30),
child: SizedBox(),
)),
],
),
);
}
}

View File

@ -0,0 +1,64 @@
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/screens/landing/landing_controller.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
import 'package:auto_size_text/auto_size_text.dart';
class BottomNavBar extends StatelessWidget {
BottomNavBar({super.key});
final controller = Get.put(LandingController());
final autoSizeGroup = AutoSizeGroup();
@override
Widget build(BuildContext context) {
return Obx(
() => AnimatedBottomNavigationBar.builder(
itemCount: controller.pages.length,
elevation: ScreenAdaper.height(30),
height: ScreenAdaper.height(80),
activeIndex: controller.currentIndex.value,
gapLocation: GapLocation.center,
notchSmoothness: NotchSmoothness.verySmoothEdge,
leftCornerRadius: ScreenAdaper.sp(25),
rightCornerRadius: ScreenAdaper.sp(25),
onTap: (index) {
controller.currentIndex.value = index;
},
tabBuilder: (int index, bool isActive) {
final color = isActive
? AppTheme.activeNavigationBarColor
: AppTheme.notActiveNavigationBarColor;
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
controller.iconList[index],
size: ScreenAdaper.sp(40),
color: color,
),
AutoSizeText(
controller.bottomNavItems[index].label,
maxLines: 1,
style: TextStyle(color: color, fontSize: ScreenAdaper.sp(20)),
group: autoSizeGroup,
),
],
);
},
),
);
}
}
// BottomNavigationBar(
// iconSize: ScreenAdaper.sp(40),
// type: BottomNavigationBarType.fixed,
// items: bottomNavItems,
// showSelectedLabels: true,
// showUnselectedLabels: true,
// currentIndex: _selectedLanding,
// onTap: (landing) {
// _onItemTapped(landing);
// },
// )

View File

@ -0,0 +1,73 @@
import 'package:flutter/material.dart';
import 'package:sk_base_mobile/app_theme.dart';
import 'package:sk_base_mobile/constants/bg_color.dart';
import 'package:sk_base_mobile/screens/home/components/responsive.dart';
import 'package:sk_base_mobile/screens/new_task/new_task.dart';
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
class FloatingButton extends StatelessWidget {
const FloatingButton({super.key});
@override
Widget build(BuildContext context) {
return InkWell(
borderRadius: BorderRadius.circular(ScreenAdaper.sp(50)),
onTap: () {
Responsive.isTablet(context)
? showGeneralDialog(
context: context,
barrierLabel: "Barrier",
barrierDismissible: true,
barrierColor: Colors.black.withOpacity(0.5),
transitionDuration: const Duration(milliseconds: 400),
pageBuilder: (_, __, ___) {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: Material(child: NewTask()),
),
);
},
transitionBuilder: (_, anim, __, child) {
Tween<Offset> tween;
tween = Tween(begin: const Offset(0, -1), end: Offset.zero);
return SlideTransition(
position: tween.animate(
CurvedAnimation(parent: anim, curve: Curves.easeInOut),
),
// child: FadeTransition(
// opacity: anim,
// child: child,
// ),
child: child,
);
},
)
: showModalBottomSheet(
elevation: 0,
isScrollControlled: true,
backgroundColor: Colors.white,
context: context,
builder: (context) {
return NewTask();
},
);
},
child: Container(
height: ScreenAdaper.height(100),
width: ScreenAdaper.height(100),
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [AppTheme.primaryColorLight, AppTheme.primaryColor])),
child: Icon(
Icons.add,
color: Colors.white,
size: ScreenAdaper.sp(40),
),
),
);
}
}

View File

@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
animated_bottom_navigation_bar:
dependency: "direct main"
description:
name: animated_bottom_navigation_bar
sha256: "2b04a2ae4b0742669e60ddf309467d6a354cefd2d0cd20f4737b1efaf9834cda"
url: "https://pub.dev"
source: hosted
version: "1.3.3"
ansicolor:
dependency: transitive
description:
@ -33,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_size_text:
dependency: "direct main"
description:
name: auto_size_text
sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
boolean_selector:
dependency: transitive
description:
@ -489,7 +505,7 @@ packages:
source: hosted
version: "2.0.2"
path:
dependency: transitive
dependency: "direct main"
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
@ -497,7 +513,7 @@ packages:
source: hosted
version: "1.8.3"
path_provider:
dependency: transitive
dependency: "direct main"
description:
name: path_provider
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
@ -718,7 +734,7 @@ packages:
source: hosted
version: "7.0.0"
sqflite:
dependency: transitive
dependency: "direct main"
description:
name: sqflite
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6

View File

@ -51,6 +51,11 @@ dependencies:
permission_handler: ^11.3.0
crypto: ^3.0.3
date_format: ^2.0.7
animated_bottom_navigation_bar: ^1.3.3
auto_size_text: ^3.0.0
sqflite: ^2.3.2
path: ^1.8.3
path_provider: ^2.1.2
dev_dependencies: