Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

427 rader
20 KiB

  1. // ignore_for_file: public_member_api_docs, sort_constructors_first
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
  4. import 'package:go_router/go_router.dart';
  5. import 'package:intl/intl.dart';
  6. import 'package:provider/provider.dart';
  7. import 'package:qadirneyriz/setting/setting.dart';
  8. import 'package:qadirneyriz/utils/tools/tools.dart';
  9. import 'package:qadirneyriz/widgets/card_meeting.dart';
  10. import 'package:qadirneyriz/widgets/custom_appbar.dart';
  11. import 'package:qadirneyriz/widgets/custom_button.dart';
  12. import 'package:qadirneyriz/widgets/empty_widget.dart';
  13. import 'package:qadirneyriz/widgets/error_widget.dart';
  14. import 'package:qadirneyriz/widgets/today_widget.dart';
  15. import 'package:flutter_gen/gen_l10n/app_localizations.dart';
  16. import 'package:qadirneyriz/config/config.dart';
  17. import 'package:qadirneyriz/screens/home/state.dart';
  18. import 'package:qadirneyriz/utils/enums/status.dart';
  19. import 'package:qadirneyriz/widgets/loading_widget.dart';
  20. class HomeScreen extends StatefulWidget {
  21. const HomeScreen({super.key});
  22. @override
  23. State<HomeScreen> createState() => _HomeScreenState();
  24. }
  25. class _HomeScreenState extends State<HomeScreen> {
  26. @override
  27. void initState() {
  28. super.initState();
  29. HomeState homeState = Provider.of(context, listen: false);
  30. Future.delayed(Duration.zero, () async {
  31. await homeState.getTodayMeetings();
  32. });
  33. }
  34. @override
  35. Widget build(BuildContext context) {
  36. DateTime now = DateTime.now();
  37. String dateMiladi = DateFormat('yyyy-MM-dd').format(now);
  38. String dateJalali =
  39. '${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}'; // فرمت کردن تاریخ
  40. return Consumer<HomeState>(
  41. builder: (context, value, child) {
  42. switch (value.todayMettingsStatus) {
  43. case Status.ready:
  44. return RefreshIndicator(
  45. onRefresh: () async {
  46. await value.getTodayMeetings();
  47. },
  48. child: CustomScrollView(
  49. slivers: [
  50. const CustomAppbar(),
  51. SliverToBoxAdapter(
  52. child: Padding(
  53. padding: const EdgeInsets.symmetric(
  54. horizontal: 20, vertical: 10),
  55. child: Container(
  56. decoration: BoxDecoration(
  57. color: const Color(0xffF4F9F6),
  58. boxShadow: [
  59. BoxShadow(
  60. color: config.ui.mainGray.withOpacity(.1),
  61. spreadRadius: .1,
  62. offset: const Offset(0, 5),
  63. blurRadius: 6)
  64. ],
  65. borderRadius: BorderRadius.circular(25)),
  66. width: double.infinity,
  67. child: Padding(
  68. padding: const EdgeInsets.all(20),
  69. child: Row(
  70. crossAxisAlignment: CrossAxisAlignment.start,
  71. children: [
  72. Icon(
  73. Icons.edit_outlined,
  74. color: config.ui.mainGreen,
  75. ),
  76. const SizedBox(
  77. width: 10,
  78. ),
  79. Expanded(
  80. child: Text(
  81. style: const TextStyle(fontSize: 13),
  82. value.todayMeetingsModel!.note ?? ''),
  83. ),
  84. ],
  85. ),
  86. ),
  87. ),
  88. ),
  89. ),
  90. SliverToBoxAdapter(
  91. child: TodayWidget(
  92. formattedDate:
  93. setting.userLocalDb.getUser().language == 'en'
  94. ? dateMiladi
  95. : dateJalali),
  96. ),
  97. SliverToBoxAdapter(
  98. child: SizedBox(
  99. height: 170,
  100. child: value.todayMeetingsModel!.meetings!.isNotEmpty
  101. ? ListView.builder(
  102. scrollDirection: Axis.horizontal,
  103. itemCount:
  104. value.todayMeetingsModel!.meetings!.length,
  105. itemBuilder: (BuildContext context, int index) {
  106. final items =
  107. value.todayMeetingsModel!.meetings![index];
  108. return Padding(
  109. padding:
  110. const EdgeInsets.only(right: 5, left: 1),
  111. child: CustomCardMeeting(
  112. status: items.accepted ?? 0,
  113. titel: items.subject != null
  114. ? items.subject!.subject ?? ''
  115. : '',
  116. fromTime: items.azHour ?? '',
  117. toTime: items.taHour ?? "",
  118. location: items.location != null
  119. ? items.location!.address ?? ''
  120. : '',
  121. date: items.dateJalali ?? '',
  122. cardId: items.id ?? 0,
  123. ),
  124. );
  125. },
  126. )
  127. : Center(
  128. child: Column(
  129. mainAxisAlignment: MainAxisAlignment.center,
  130. children: [
  131. Icon(Icons.error_outline,
  132. size: 40,
  133. color:
  134. config.ui.mainGray.withOpacity(.5)),
  135. const SizedBox(
  136. height: 20,
  137. ),
  138. Text(
  139. AppLocalizations.of(context)!
  140. .nomeetingfortoday,
  141. style: TextStyle(
  142. color:
  143. config.ui.mainGray.withOpacity(.5)),
  144. ),
  145. ],
  146. ),
  147. ),
  148. ),
  149. ),
  150. SliverPadding(
  151. padding: const EdgeInsets.symmetric(
  152. vertical: 30, horizontal: 10),
  153. sliver: SliverToBoxAdapter(
  154. child: StaggeredGrid.count(
  155. crossAxisCount: 4,
  156. mainAxisSpacing: 4,
  157. crossAxisSpacing: 4,
  158. children: [
  159. StaggeredGridTile.count(
  160. crossAxisCellCount: 2,
  161. mainAxisCellCount: 1,
  162. child: ItemInGrid(
  163. icon: Icons.assessment,
  164. backColor: const Color(0xff03C85F),
  165. text: AppLocalizations.of(context)!.reports,
  166. onTap: () {
  167. context.pushNamed('navigate',
  168. pathParameters: {'tab': '3'});
  169. },
  170. ),
  171. ),
  172. StaggeredGridTile.count(
  173. crossAxisCellCount: 2,
  174. mainAxisCellCount: 2,
  175. child: ItemInGrid(
  176. icon: Icons.people,
  177. backColor: const Color(0xff04A54F),
  178. text: AppLocalizations.of(context)!.meetings,
  179. onTap: () {
  180. context.pushNamed('navigate',
  181. pathParameters: {'tab': '1'});
  182. },
  183. ),
  184. ),
  185. StaggeredGridTile.count(
  186. crossAxisCellCount: 2,
  187. mainAxisCellCount: 2,
  188. child: ItemInGrid(
  189. icon: Icons.calendar_today,
  190. backColor: const Color(0xff37A068),
  191. text: AppLocalizations.of(context)!.events,
  192. onTap: () {
  193. context.pushNamed('navigate',
  194. pathParameters: {'tab': '2'});
  195. },
  196. ),
  197. ),
  198. StaggeredGridTile.count(
  199. crossAxisCellCount: 2,
  200. mainAxisCellCount: 1,
  201. child: ItemInGrid(
  202. icon: Icons.exit_to_app,
  203. backColor: const Color(0xff00843D),
  204. text: AppLocalizations.of(context)!.exit,
  205. onTap: () {
  206. showModalBottomSheet(
  207. context: context,
  208. builder: (context) {
  209. return DraggableScrollableSheet(
  210. initialChildSize: .5,
  211. expand: false,
  212. snap: false,
  213. builder: (context, scrollController) {
  214. return Column(
  215. mainAxisSize: MainAxisSize.min,
  216. children: [
  217. Padding(
  218. padding: const EdgeInsets.only(
  219. top: 8, bottom: 30),
  220. child: Container(
  221. width: 60,
  222. height: 4,
  223. decoration: BoxDecoration(
  224. color: Colors.black
  225. .withOpacity(.4),
  226. borderRadius:
  227. BorderRadius.circular(
  228. 10)),
  229. ),
  230. ),
  231. Text(
  232. AppLocalizations.of(context)!
  233. .exit,
  234. style: TextStyle(
  235. color: config.ui.mainGreen,
  236. fontSize: 18,
  237. fontWeight: FontWeight.w500),
  238. ),
  239. const SizedBox(
  240. height: 15,
  241. ),
  242. Text(
  243. AppLocalizations.of(context)!
  244. .areusurelog,
  245. style: TextStyle(
  246. color: Colors.black,
  247. fontSize: 14,
  248. ),
  249. ),
  250. const SizedBox(
  251. height: 30,
  252. ),
  253. Consumer<HomeState>(
  254. builder: (context, value, child) {
  255. switch (value.statusLogOut) {
  256. case Status.loading:
  257. return const LoadingWidget();
  258. default:
  259. return Row(
  260. mainAxisAlignment:
  261. MainAxisAlignment
  262. .center,
  263. crossAxisAlignment:
  264. CrossAxisAlignment
  265. .center,
  266. children: [
  267. CustomButton(
  268. fontSize: 13,
  269. color: config
  270. .ui.mainGreen,
  271. onPressed: () {
  272. Navigator.pop(
  273. context);
  274. },
  275. hieght: 50,
  276. // width: 150,
  277. text: AppLocalizations
  278. .of(context)!
  279. .no,
  280. ),
  281. const SizedBox(
  282. width: 10,
  283. ),
  284. CustomButton(
  285. fontSize: 13,
  286. hieght: 50,
  287. // width: 150,
  288. text: AppLocalizations
  289. .of(context)!
  290. .logout,
  291. textColor:
  292. Colors.black,
  293. color: const Color(
  294. 0xffD0D5ED),
  295. onPressed: () async {
  296. final status =
  297. await value
  298. .logOut();
  299. if (status ==
  300. Status.error) {
  301. Tools.showCustomSnackBar(
  302. context,
  303. text: value
  304. .messageLogOut ??
  305. AppLocalizations.of(
  306. context)!
  307. .error,
  308. isError:
  309. true);
  310. } else if (status ==
  311. Status.ready) {
  312. context
  313. .pushReplacementNamed(
  314. 'login');
  315. Tools.showCustomSnackBar(
  316. context,
  317. text: value
  318. .messageLogOut ??
  319. 'Done successfully',
  320. isError:
  321. false);
  322. }
  323. },
  324. ),
  325. ],
  326. );
  327. }
  328. },
  329. ),
  330. const SizedBox(
  331. height: 40,
  332. )
  333. ],
  334. );
  335. },
  336. );
  337. },
  338. );
  339. },
  340. ),
  341. ),
  342. ],
  343. ),
  344. ),
  345. ),
  346. ],
  347. ),
  348. );
  349. case Status.loading:
  350. return const LoadingWidget();
  351. case Status.error:
  352. return CustomErrorWidget(
  353. onPressed: () async {
  354. await value.getTodayMeetings(refresh: true);
  355. },
  356. );
  357. case Status.empty:
  358. return EmptyStateWidget();
  359. default:
  360. return Container();
  361. }
  362. },
  363. );
  364. }
  365. }
  366. class ItemInGrid extends StatelessWidget {
  367. final IconData icon;
  368. final Color backColor;
  369. final String text;
  370. final void Function() onTap;
  371. const ItemInGrid(
  372. {super.key,
  373. required this.icon,
  374. required this.backColor,
  375. required this.text,
  376. required this.onTap});
  377. @override
  378. Widget build(BuildContext context) {
  379. return Padding(
  380. padding: const EdgeInsets.all(4.0),
  381. child: GestureDetector(
  382. onTap: onTap,
  383. child: Container(
  384. decoration: BoxDecoration(
  385. borderRadius: BorderRadius.circular(20),
  386. color: backColor,
  387. boxShadow: [
  388. BoxShadow(
  389. color: config.ui.mainGray.withOpacity(.5),
  390. spreadRadius: .1,
  391. offset: const Offset(0, 2),
  392. blurRadius: 6)
  393. ],
  394. ),
  395. child: Column(
  396. mainAxisAlignment: MainAxisAlignment.center,
  397. children: [
  398. Icon(
  399. icon,
  400. size: 40,
  401. color: Colors.white,
  402. ),
  403. const SizedBox(
  404. height: 8,
  405. ),
  406. Text(
  407. text,
  408. style: const TextStyle(color: Colors.white, fontSize: 16),
  409. ),
  410. ],
  411. ),
  412. ),
  413. ),
  414. );
  415. }
  416. }