Remove Sales, Comment Task, and Report Task screens; update pubspec.yaml to clean up asset paths.

This commit is contained in:
Vaibhav Surve 2025-06-13 11:37:08 +05:30
parent d765b96df4
commit 5275ad940b
62 changed files with 0 additions and 201117 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,192 +0,0 @@
[
{
"id": 1,
"first_name": "James Carter",
"email": "james.carter@example.com",
"messages": [
{
"message": "How is your day going?",
"send_at": "2024-11-15T10:05:10Z",
"from_me": false
},
{
"message": "Reminder about the project meeting tomorrow",
"send_at": "2023-06-20T14:23:11Z",
"from_me": true
},
{
"message": "Can we meet today for a quick chat?",
"send_at": "2023-04-19T17:30:08Z",
"from_me": false
},
{
"message": "Yes, all is good. See you tomorrow at 2 PM for the meeting",
"send_at": "2023-03-22T11:09:45Z",
"from_me": false
}
]
},
{
"id": 2,
"first_name": "Sophia Lee",
"email": "sophia.lee@example.com",
"messages": [
{
"message": "Are we meeting today for the weekly catch-up?",
"send_at": "2023-09-10T08:45:36Z",
"from_me": false
},
{
"message": "Please review these updated documents",
"send_at": "2023-11-17T11:22:33Z",
"from_me": true
},
{
"message": "Good morning, How are you? When is our next meeting?",
"send_at": "2023-05-13T09:25:18Z",
"from_me": true
}
]
},
{
"id": 3,
"first_name": "Ethan Scott",
"email": "ethan.scott@example.com",
"messages": [
{
"message": "Are you available for a quick call? Need to discuss something",
"send_at": "2023-12-05T07:40:21Z",
"from_me": false
},
{
"message": "Let's meet today, shall we?",
"send_at": "2023-03-17T14:00:12Z",
"from_me": true
}
]
},
{
"id": 4,
"first_name": "Olivia Brown",
"email": "olivia.brown@example.com",
"messages": [
{
"message": "Let's meet today for a team discussion",
"send_at": "2023-05-30T11:55:10Z",
"from_me": false
},
{
"message": "Hope you're having a great day. Let's catch up soon",
"send_at": "2023-07-12T12:36:44Z",
"from_me": true
},
{
"message": "I need to go buy some groceries this afternoon, I'll be a bit late.",
"send_at": "2024-01-10T13:20:45Z",
"from_me": true
}
]
},
{
"id": 5,
"first_name": "Charlotte Miller",
"email": "charlotte.miller@example.com",
"messages": [
{
"message": "Are you available for a quick chat?",
"send_at": "2023-11-11T16:50:09Z",
"from_me": false
},
{
"message": "I just sent you the updated contract documents for review.",
"send_at": "2023-10-04T18:22:56Z",
"from_me": true
}
]
},
{
"id": 6,
"first_name": "Jackson Harris",
"email": "jackson.harris@example.com",
"messages": [
{
"message": "How's everything going? Any updates on the project?",
"send_at": "2023-08-25T11:10:30Z",
"from_me": false
},
{
"message": "Sending over the latest draft for your review",
"send_at": "2023-12-02T10:14:50Z",
"from_me": true
}
]
},
{
"id": 7,
"first_name": "Aiden Cooper",
"email": "aiden.cooper@example.com",
"messages": [
{
"message": "Do you have time today for a discussion?",
"send_at": "2023-10-05T09:18:22Z",
"from_me": false
},
{
"message": "The new update is ready for deployment, please check it.",
"send_at": "2024-01-25T11:29:13Z",
"from_me": true
}
]
},
{
"id": 8,
"first_name": "Lily King",
"email": "lily.king@example.com",
"messages": [
{
"message": "Would you be able to meet today for a catch-up?",
"send_at": "2023-06-18T13:12:09Z",
"from_me": false
},
{
"message": "I have finished reviewing the files, please take a look.",
"send_at": "2023-12-18T16:47:02Z",
"from_me": true
}
]
},
{
"id": 9,
"first_name": "Max Taylor",
"email": "max.taylor@example.com",
"messages": [
{
"message": "Please check the attached file and confirm if everything is okay.",
"send_at": "2023-09-29T14:10:33Z",
"from_me": false
},
{
"message": "Sending over the revised schedule for the next phase.",
"send_at": "2024-01-02T17:12:11Z",
"from_me": true
}
]
},
{
"id": 10,
"first_name": "Avery Clark",
"email": "avery.clark@example.com",
"messages": [
{
"message": "Are we ready for the meeting today?",
"send_at": "2023-08-22T12:43:50Z",
"from_me": false
},
{
"message": "I updated the timeline. Let me know if you have any questions.",
"send_at": "2023-12-15T10:55:29Z",
"from_me": true
}
]
}
]

View File

@ -1,82 +0,0 @@
[
{
"id": 1,
"asset": "Alaska Air Group, Inc.",
"date": "2024-06-17T12:59:41Z",
"ip_address": "113.9.18.110",
"status": "Unpaid",
"amount": 7061
},
{
"id": 2,
"asset": "T2 Biosystems, Inc.",
"date": "2024-09-09T00:20:08Z",
"ip_address": "45.51.68.143",
"status": "Unpaid",
"amount": 5677
},
{
"id": 3,
"asset": "North American Energy Partners, Inc.",
"date": "2024-07-17T10:46:42Z",
"ip_address": "221.131.122.193",
"status": "Unpaid",
"amount": 5420
},
{
"id": 4,
"asset": "Finjan Holdings, Inc.",
"date": "2024-01-20T20:10:26Z",
"ip_address": "50.242.43.22",
"status": "Success",
"amount": 6433
},
{
"id": 5,
"asset": "Omega Healthcare Investors, Inc.",
"date": "2024-11-14T23:08:09Z",
"ip_address": "109.125.5.131",
"status": "Success",
"amount": 6317
},
{
"id": 6,
"asset": "MediciNova, Inc.",
"date": "2024-01-12T18:20:33Z",
"ip_address": "54.103.156.190",
"status": "Unpaid",
"amount": 7952
},
{
"id": 7,
"asset": "PowerShares LadderRite 0-5 Year Corporate Bond Portfolio",
"date": "2024-04-26T00:44:42Z",
"ip_address": "169.190.183.205",
"status": "Success",
"amount": 6294
},
{
"id": 8,
"asset": "VelocityShares Daily 2x VIX Medium-Term ETN",
"date": "2024-02-01T12:47:59Z",
"ip_address": "144.189.211.137",
"status": "Success",
"amount": 4419
},
{
"id": 9,
"asset": "Liberty TripAdvisor Holdings, Inc.",
"date": "2023-12-29T14:49:59Z",
"ip_address": "166.41.221.149",
"status": "Unpaid",
"amount": 4195
},
{
"id": 10,
"asset": "Scorpio Tankers Inc.",
"date": "2023-12-02T11:36:44Z",
"ip_address": "27.151.0.226",
"status": "Success",
"amount": 8395
}
]

View File

@ -1,202 +0,0 @@
[
{
"id": 1,
"first_name": "Sabina",
"last_name": "Brothwood",
"project_name": "Wunsch, DuBuque and Green",
"phone_number": "541-568-8047",
"balance": "31907",
"order_count": 7,
"last_order": "2022-10-07T03:43:16Z"
},
{
"id": 2,
"first_name": "Felic",
"last_name": "Parlor",
"project_name": "Dare LLC",
"phone_number": "866-349-3385",
"balance": "02260",
"order_count": 26,
"last_order": "2023-07-12T07:52:19Z"
},
{
"id": 3,
"first_name": "Marnie",
"last_name": "Kofax",
"project_name": "Von LLC",
"phone_number": "821-779-3766",
"balance": "663",
"order_count": 21,
"last_order": "2022-10-14T21:19:33Z"
},
{
"id": 4,
"first_name": "Tine",
"last_name": "Meron",
"project_name": "Stracke Inc",
"phone_number": "901-149-2915",
"balance": "84",
"order_count": 8,
"last_order": "2023-04-06T12:36:09Z"
},
{
"id": 5,
"first_name": "Shanon",
"last_name": "Ivashchenko",
"project_name": "Satterfield, Schultz and Jones",
"phone_number": "452-728-1072",
"balance": "0878",
"order_count": 34,
"last_order": "2023-04-03T15:07:21Z"
},
{
"id": 6,
"first_name": "Guthrey",
"last_name": "Crossland",
"project_name": "Medhurst and Sons",
"phone_number": "212-991-7314",
"balance": "0291",
"order_count": 7,
"last_order": "2022-12-03T04:24:53Z"
},
{
"id": 7,
"first_name": "Florie",
"last_name": "Chestnutt",
"project_name": "Beer-Kunze",
"phone_number": "935-525-9749",
"balance": "07984",
"order_count": 69,
"last_order": "2023-01-14T10:42:28Z"
},
{
"id": 8,
"first_name": "Wittie",
"last_name": "Damsell",
"project_name": "Daniel, Legros and Roberts",
"phone_number": "632-787-4799",
"balance": "22844",
"order_count": 41,
"last_order": "2023-01-18T09:38:50Z"
},
{
"id": 9,
"first_name": "Aimee",
"last_name": "Dibdall",
"project_name": "Schuster LLC",
"phone_number": "404-339-9261",
"balance": "460",
"order_count": 41,
"last_order": "2023-04-15T03:08:51Z"
},
{
"id": 10,
"first_name": "Inna",
"last_name": "Juggins",
"project_name": "Johnson Group",
"phone_number": "769-573-9516",
"balance": "77",
"order_count": 18,
"last_order": "2022-09-13T05:14:51Z"
},
{
"id": 11,
"first_name": "Cathyleen",
"last_name": "Went",
"project_name": "DuBuque LLC",
"phone_number": "558-736-4450",
"balance": "24",
"order_count": 98,
"last_order": "2023-07-05T05:26:12Z"
},
{
"id": 12,
"first_name": "Kora",
"last_name": "Dowderswell",
"project_name": "Harber, Daugherty and West",
"phone_number": "721-147-2917",
"balance": "32",
"order_count": 5,
"last_order": "2022-10-22T07:47:42Z"
},
{
"id": 13,
"first_name": "Loni",
"last_name": "Armin",
"project_name": "Fadel-Kerluke",
"phone_number": "251-582-9867",
"balance": "2122",
"order_count": 4,
"last_order": "2023-01-26T19:56:37Z"
},
{
"id": 14,
"first_name": "Kalle",
"last_name": "Spybey",
"project_name": "Kshlerin, Torp and Koelpin",
"phone_number": "245-661-6328",
"balance": "61034",
"order_count": 70,
"last_order": "2022-12-29T15:38:20Z"
},
{
"id": 15,
"first_name": "Verena",
"last_name": "Skerme",
"project_name": "Dach, Abshire and Crooks",
"phone_number": "227-694-0272",
"balance": "68921",
"order_count": 3,
"last_order": "2022-11-29T23:02:11Z"
},
{
"id": 16,
"first_name": "Lisle",
"last_name": "McGowan",
"project_name": "White, Murphy and Sawayn",
"phone_number": "196-817-6277",
"balance": "7250",
"order_count": 34,
"last_order": "2023-06-14T11:10:56Z"
},
{
"id": 17,
"first_name": "Bryce",
"last_name": "Pires",
"project_name": "Crooks Group",
"phone_number": "424-217-0372",
"balance": "549",
"order_count": 50,
"last_order": "2023-01-08T17:58:09Z"
},
{
"id": 18,
"first_name": "Ibrahim",
"last_name": "Battram",
"project_name": "Schmidt, Feil and Schaden",
"phone_number": "836-473-5900",
"balance": "3",
"order_count": 86,
"last_order": "2023-08-05T01:46:22Z"
},
{
"id": 19,
"first_name": "Josepha",
"last_name": "Grishkov",
"project_name": "Welch-Wisozk",
"phone_number": "928-393-5306",
"balance": "528",
"order_count": 38,
"last_order": "2023-08-18T19:01:25Z"
},
{
"id": 20,
"first_name": "Ellis",
"last_name": "Barfoot",
"project_name": "Davis, Ondricka and Schaefer",
"phone_number": "169-236-9311",
"balance": "169",
"order_count": 11,
"last_order": "2023-02-21T16:29:59Z"
}
]

View File

@ -1,72 +0,0 @@
[
{
"id": 1,
"image": "assets/dummy/dummy_1.jpg",
"name": "Meir O'Leahy",
"user_name": "moleahy0",
"contact_number": "817-666-8080"
},
{
"id": 2,
"image": "assets/dummy/dummy_2.jpg",
"name": "Ernie Ayling",
"user_name": "eayling1",
"contact_number": "890-910-3243"
},
{
"id": 3,
"image": "assets/dummy/dummy_3.jpg",
"name": "Mead Ezzle",
"user_name": "mezzle2",
"contact_number": "293-162-4468"
},
{
"id": 4,
"image": "assets/dummy/dummy_4.jpg",
"name": "Esta Norewood",
"user_name": "enorewood3",
"contact_number": "532-164-0604"
},
{
"id": 5,
"image": "assets/dummy/dummy_5.jpg",
"name": "Bartram Cottell",
"user_name": "bcottell4",
"contact_number": "940-143-2842"
},
{
"id": 6,
"image": "assets/dummy/dummy_1.jpg",
"name": "Nicola Reolfo",
"user_name": "nreolfo5",
"contact_number": "356-558-8324"
},
{
"id": 7,
"image": "assets/dummy/dummy_2.jpg",
"name": "Normy Gilhoolie",
"user_name": "ngilhoolie6",
"contact_number": "256-770-5288"
},
{
"id": 8,
"image": "assets/dummy/dummy_3.jpg",
"name": "Octavia Margerrison",
"user_name": "omargerrison7",
"contact_number": "744-595-1968"
},
{
"id": 9,
"image": "assets/dummy/dummy_4.jpg",
"name": "Stella Barriball",
"user_name": "sbarriball8",
"contact_number": "906-522-1874"
},
{
"id": 10,
"image": "assets/dummy/dummy_5.jpg",
"name": "Panchito Chase",
"user_name": "pchase9",
"contact_number": "929-922-7735"
}
]

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
[
{
"id": 1,
"candidate": "Patrica",
"category": "Manufacture",
"designation": "Sr.UI Developer",
"mail": "pbeedie0@ustream.tv",
"location": "Pojan",
"date": "2024-08-09T06:03:25Z",
"type": "Freelancer"
},
{
"id": 2,
"candidate": "Angelique",
"category": "Marketing",
"designation": "Team Lead",
"mail": "asamwayes1@fotki.com",
"location": "Jiangluo",
"date": "2023-11-17T10:23:18Z",
"type": "Hybride"
},
{
"id": 3,
"candidate": "Garnet",
"category": "Marketing",
"designation": "Team Lead",
"mail": "gjarrelt2@dailymail.co.uk",
"location": "Wissembourg",
"date": "2024-03-18T15:31:21Z",
"type": "Freelancer"
},
{
"id": 4,
"candidate": "Guglielmo",
"category": "Manufacture",
"designation": "Sales Executive",
"mail": "gcarlone3@ted.com",
"location": "Aoqiao",
"date": "2024-04-08T22:04:13Z",
"type": "Part Time"
},
{
"id": 5,
"candidate": "Reggie",
"category": "Manufacture",
"designation": "Team Lead",
"mail": "rmacieiczyk4@booking.com",
"location": "Insrom",
"date": "2024-01-09T06:29:40Z",
"type": "Freelancer"
},
{
"id": 6,
"candidate": "Florri",
"category": "Manufacture",
"designation": "Sales Executive",
"mail": "fharesign5@yellowbook.com",
"location": "Itambacuri",
"date": "2024-09-05T11:09:36Z",
"type": "Part Time"
},
{
"id": 7,
"candidate": "Annabella",
"category": "Manufacture",
"designation": "Team Lead",
"mail": "aossipenko6@ucoz.com",
"location": "Watthana Nakhon",
"date": "2024-07-27T16:17:23Z",
"type": "Full Time"
},
{
"id": 8,
"candidate": "Arlene",
"category": "Manufacture",
"designation": "Team Lead",
"mail": "agook7@google.com.hk",
"location": "Hayama",
"date": "2024-09-14T13:32:31Z",
"type": "Freelancer"
},
{
"id": 9,
"candidate": "Shurlocke",
"category": "Manufacture",
"designation": "Sales Executive",
"mail": "sgallehawk8@squidoo.com",
"location": "Bel Air Rivière Sèche",
"date": "2024-06-18T00:23:24Z",
"type": "Freelancer"
},
{
"id": 10,
"candidate": "Ricoriki",
"category": "Service",
"designation": "Sales Executive",
"mail": "rgillio9@mapy.cz",
"location": "Tawangsari",
"date": "2024-06-14T19:59:41Z",
"type": "Freelancer"
}
]

View File

@ -1,112 +0,0 @@
[
{
"id": 1,
"first_name": "Bordy",
"email": "bjeffreys0@macromedia.com",
"phone_number": "217-779-9808",
"company_name": "Voonyx",
"status": "Won Lead",
"location": "Presidencia Roque Sáenz Peña",
"date": "2024-06-20T06:26:12Z",
"amount": 52397
},
{
"id": 2,
"first_name": "Collin",
"email": "cgething1@paginegialle.it",
"phone_number": "124-897-0512",
"company_name": "Rhyzio",
"status": "New Lead",
"location": "Nombre de Jesús",
"date": "2023-11-20T12:12:32Z",
"amount": 58203
},
{
"id": 3,
"first_name": "Bear",
"email": "bfowlds2@booking.com",
"phone_number": "391-249-1041",
"company_name": "Blogtag",
"status": "Lost Lead",
"location": "Shani",
"date": "2024-11-09T07:57:49Z",
"amount": 18717
},
{
"id": 4,
"first_name": "Robers",
"email": "raujouanet3@google.cn",
"phone_number": "128-604-5632",
"company_name": "Quire",
"status": "Lost Lead",
"location": "Benghazi",
"date": "2023-12-09T17:33:39Z",
"amount": 11267
},
{
"id": 5,
"first_name": "Shirlene",
"email": "sjoiris4@theglobeandmail.com",
"phone_number": "471-884-5686",
"company_name": "Voonder",
"status": "New Lead",
"location": "Krasnaye",
"date": "2024-01-15T03:06:07Z",
"amount": 66877
},
{
"id": 6,
"first_name": "Erik",
"email": "ebudden5@zdnet.com",
"phone_number": "957-550-9950",
"company_name": "Digitube",
"status": "Won Lead",
"location": "Taouloukoult",
"date": "2024-01-21T03:05:01Z",
"amount": 55766
},
{
"id": 7,
"first_name": "Sabina",
"email": "sdenman6@ning.com",
"phone_number": "612-207-4109",
"company_name": "Kwinu",
"status": "Lost Lead",
"location": "Minneapolis",
"date": "2024-05-19T15:59:28Z",
"amount": 24691
},
{
"id": 8,
"first_name": "Andi",
"email": "aschruyer7@imdb.com",
"phone_number": "410-936-5855",
"company_name": "Photojam",
"status": "Won Lead",
"location": "Masina",
"date": "2024-09-30T18:31:07Z",
"amount": 7228
},
{
"id": 9,
"first_name": "Kathy",
"email": "kstandall8@woothemes.com",
"phone_number": "840-267-7381",
"company_name": "Quinu",
"status": "Won Lead",
"location": "Shashi",
"date": "2024-04-21T18:00:25Z",
"amount": 85726
},
{
"id": 10,
"first_name": "Lenka",
"email": "llennon9@hexun.com",
"phone_number": "962-993-3146",
"company_name": "Skaboo",
"status": "Won Lead",
"location": "Shireet",
"date": "2024-06-19T12:27:05Z",
"amount": 10069
}
]

View File

@ -1,197 +0,0 @@
[
{
"id": 1,
"name": "Mints - Striped Red",
"description": "Laceration of ulnar artery at wrs/hnd lv of unsp arm",
"price": 54,
"stock": 72,
"category": "Scallops 60/80 Iqf",
"order_counts": 10,
"created_at": "2022-07-20T09:52:34Z",
"rating": 2.49,
"rating_count": 42,
"sku": "RCII"
},
{
"id": 2,
"name": "Pasta - Ravioli",
"description": "Oth disp fx of upper end l humer, subs for fx w delay heal",
"price": 35,
"stock": 64,
"category": "Chocolate - Mi - Amere Semi",
"order_counts": 45,
"created_at": "2023-03-25T22:32:10Z",
"rating": 4.66,
"rating_count": 82,
"sku": "RDS.A"
},
{
"id": 3,
"name": "Soup - Campbells Chili",
"description": "Nondisp fx of anterior wall of left acetab, init for opn fx",
"price": 27,
"stock": 21,
"category": "Tomatoes - Cherry, Yellow",
"order_counts": 53,
"created_at": "2022-05-18T15:56:06Z",
"rating": 3.05,
"rating_count": 66,
"sku": "STNG"
},
{
"id": 4,
"name": "Fennel - Seeds",
"description": "Displ spiral fx shaft of ulna, r arm, 7thD",
"price": 124,
"stock": 56,
"category": "Squid - U - 10 Thailand",
"order_counts": 13,
"created_at": "2022-04-21T11:32:39Z",
"rating": 0.59,
"rating_count": 55,
"sku": "FEUZ"
},
{
"id": 5,
"name": "Salt - Celery",
"description": "Interstitial myositis, lower leg",
"price": 25,
"stock": 78,
"category": "Gatorade - Lemon Lime",
"order_counts": 30,
"created_at": "2023-01-01T01:15:44Z",
"rating": 1.42,
"rating_count": 10,
"sku": "VER"
},
{
"id": 6,
"name": "Flour - Chickpea",
"description": "Oth fx upr end unsp rad, 7thJ",
"price": 131,
"stock": 50,
"category": "Sweet Pea Sprouts",
"order_counts": 11,
"created_at": "2023-04-09T04:41:43Z",
"rating": 4.05,
"rating_count": 24,
"sku": "HDS"
},
{
"id": 7,
"name": "Chips - Miss Vickies",
"description": "Contusion of right hip, initial encounter",
"price": 52,
"stock": 63,
"category": "Extract - Almond",
"order_counts": 62,
"created_at": "2022-06-24T05:25:56Z",
"rating": 3.35,
"rating_count": 6,
"sku": "MACQW"
},
{
"id": 8,
"name": "Ice Cream - Super Sandwich",
"description": "Acute post-traumatic headache",
"price": 87,
"stock": 44,
"category": "Bread - Wheat Baguette",
"order_counts": 63,
"created_at": "2022-07-06T05:37:09Z",
"rating": 0.96,
"rating_count": 38,
"sku": "AA"
},
{
"id": 9,
"name": "Alize Gold Passion",
"description": "War op involving explosion of marine weapons, civilian",
"price": 113,
"stock": 72,
"category": "Lid - Translucent, 3.5 And 6 Oz",
"order_counts": 23,
"created_at": "2022-07-09T18:19:37Z",
"rating": 3.25,
"rating_count": 64,
"sku": "EVOK"
},
{
"id": 10,
"name": "Mushrooms - Honey",
"description": "Sltr-haris Type IV physl fx low end l femr, 7thP",
"price": 98,
"stock": 64,
"category": "Lemon Balm - Fresh",
"order_counts": 5,
"created_at": "2022-08-05T22:14:06Z",
"rating": 3.51,
"rating_count": 0,
"sku": "TDG"
},
{
"id": 11,
"name": "Bread Base - Goodhearth",
"description": "Unspecified injury of axillary artery",
"price": 81,
"stock": 56,
"category": "Beef - Bones, Marrow",
"order_counts": 76,
"created_at": "2023-04-22T03:11:41Z",
"rating": 4.07,
"rating_count": 22,
"sku": "GPAC"
},
{
"id": 12,
"name": "Veal - Heart",
"description": "Laceration without foreign body of left buttock, subs encntr",
"price": 93,
"stock": 13,
"category": "Peach - Fresh",
"order_counts": 12,
"created_at": "2023-02-18T16:15:16Z",
"rating": 2.08,
"rating_count": 87,
"sku": "PAH"
},
{
"id": 13,
"name": "Tomatoes - Grape",
"description": "Nondisplaced bicondylar fracture of left tibia",
"price": 132,
"stock": 13,
"category": "Veal - Striploin",
"order_counts": 24,
"created_at": "2022-06-08T20:49:59Z",
"rating": 3.32,
"rating_count": 82,
"sku": "ENZL"
},
{
"id": 14,
"name": "Tomato Paste",
"description": "Abrasion of unspecified part of neck, initial encounter",
"price": 48,
"stock": 24,
"category": "Juice - Tomato, 48 Oz",
"order_counts": 4,
"created_at": "2022-12-03T04:03:52Z",
"rating": 4.11,
"rating_count": 66,
"sku": "LTEA"
},
{
"id": 15,
"name": "Cheese - Roquefort Pappillon",
"description": "Wedge comprsn fx first thor vertebra, init for opn fx",
"price": 15,
"stock": 68,
"category": "Veal - Insides, Grains",
"order_counts": 72,
"created_at": "2022-09-22T06:22:33Z",
"rating": 1.54,
"rating_count": 40,
"sku": "AIF"
}
]

View File

@ -1,102 +0,0 @@
[
{
"order_id": "TWT76911",
"customer_name": "Robinson",
"location": "Lyubokhna",
"order_date": "2023-09-17T00:35:06Z",
"quantity": 6,
"payments": "COD",
"price": 336,
"status": "New"
},
{
"order_id": "TWT23890",
"customer_name": "Claudina",
"location": "Maracha",
"order_date": "2023-09-11T15:01:04Z",
"quantity": 8,
"payments": "American Express",
"price": 428,
"status": "Shopping"
},
{
"order_id": "TWT84616",
"customer_name": "Dewain",
"location": "Fuji",
"order_date": "2023-12-26T02:42:54Z",
"quantity": 6,
"payments": "Credit Card",
"price": 410,
"status": "Shopping"
},
{
"order_id": "TWT66711",
"customer_name": "Margette",
"location": "Chicago",
"order_date": "2024-01-09T18:24:04Z",
"quantity": 10,
"payments": "Paypal",
"price": 268,
"status": "Pending"
},
{
"order_id": "TWT50711",
"customer_name": "Brittany",
"location": "Hakha",
"order_date": "2023-09-28T14:17:02Z",
"quantity": 2,
"payments": "Visa Card",
"price": 229,
"status": "New"
},
{
"order_id": "TWT37588",
"customer_name": "Venus",
"location": "Sioguí Arriba",
"order_date": "2023-10-16T18:22:32Z",
"quantity": 5,
"payments": "Visa Card",
"price": 211,
"status": "Delivered"
},
{
"order_id": "TWT36092",
"customer_name": "Norry",
"location": "Hongqi",
"order_date": "2024-01-28T16:50:34Z",
"quantity": 7,
"payments": "American Express",
"price": 111,
"status": "Shopping"
},
{
"order_id": "TWT99659",
"customer_name": "Rabbi",
"location": "Macari",
"order_date": "2023-03-27T17:42:51Z",
"quantity": 9,
"payments": "COD",
"price": 268,
"status": "Pending"
},
{
"order_id": "TWT21952",
"customer_name": "Hesther",
"location": "København",
"order_date": "2024-02-08T00:16:01Z",
"quantity": 9,
"payments": "Credit Card",
"price": 392,
"status": "Delivered"
},
{
"order_id": "TWT66885",
"customer_name": "Sioux",
"location": "Taohua",
"order_date": "2023-10-23T16:25:29Z",
"quantity": 1,
"payments": "Paypal",
"price": 337,
"status": "New"
}
]

View File

@ -1,82 +0,0 @@
[
{
"id": 1,
"title": "Marketing Manager",
"assign_to": "Hercules",
"date": "2024-03-10T00:14:27Z",
"priority": "High",
"status": "Pending"
},
{
"id": 2,
"title": "Community Outreach Specialist",
"assign_to": "Fayre",
"date": "2024-10-07T06:24:18Z",
"priority": "High",
"status": "Pending"
},
{
"id": 3,
"title": "Senior Quality Engineer",
"assign_to": "Nancy",
"date": "2024-01-11T18:22:29Z",
"priority": "Medium",
"status": "In Progress"
},
{
"id": 4,
"title": "VP Sales",
"assign_to": "Jemimah",
"date": "2024-06-17T17:57:40Z",
"priority": "Low",
"status": "Finished"
},
{
"id": 5,
"title": "Sales Associate",
"assign_to": "Raquel",
"date": "2024-05-06T11:11:43Z",
"priority": "Medium",
"status": "Finished"
},
{
"id": 6,
"title": "Dental Hygienist",
"assign_to": "Vasili",
"date": "2024-05-31T21:16:27Z",
"priority": "High",
"status": "Finished"
},
{
"id": 7,
"title": "Occupational Therapist",
"assign_to": "Lulu",
"date": "2024-03-28T21:07:00Z",
"priority": "Medium",
"status": "Pending"
},
{
"id": 8,
"title": "Analyst Programmer",
"assign_to": "Egor",
"date": "2023-12-11T08:16:01Z",
"priority": "High",
"status": "Finished"
},
{
"id": 9,
"title": "Research Assistant III",
"assign_to": "Max",
"date": "2024-02-15T21:59:34Z",
"priority": "High",
"status": "Pending"
},
{
"id": 10,
"title": "Developer II",
"assign_to": "Kaela",
"date": "2024-06-24T07:29:47Z",
"priority": "High",
"status": "Cancelled"
}
]

View File

@ -1,47 +0,0 @@
[
{
"id": 1,
"product_name": "Theobald",
"quantity": 2,
"customer": "Theobald Southcott",
"status": "Shipped",
"price": 361,
"order_date": "2023-12-11T23:48:54Z"
},
{
"id": 2,
"product_name": "Carla",
"quantity": 3,
"customer": "Carla Grgic",
"status": "Pending",
"price": 329,
"order_date": "2024-05-25T09:37:51Z"
},
{
"id": 3,
"product_name": "Liana",
"quantity": 3,
"customer": "Liana Swannell",
"status": "Delivery",
"price": 120,
"order_date": "2024-04-06T19:02:14Z"
},
{
"id": 4,
"product_name": "Radcliffe",
"quantity": 4,
"customer": "Radcliffe Venard",
"status": "Shipped",
"price": 750,
"order_date": "2024-10-27T10:44:12Z"
},
{
"id": 5,
"product_name": "Delmer",
"quantity": 3,
"customer": "Delmer Vamplew",
"status": "Delivery",
"price": 469,
"order_date": "2024-10-16T15:55:22Z"
}
]

View File

@ -1,91 +0,0 @@
[
{
"id": 1,
"title": "Finish report",
"description": "Complete the quarterly report for the team meeting.",
"due_date": "2024-07-14T00:37:09Z",
"priority": "High",
"status": "Pending"
},
{
"id": 2,
"title": "Team meeting",
"description": "Attend the weekly project meeting and provide updates.",
"due_date": "2024-04-18T01:25:27Z",
"priority": "Medium",
"status": "Completed"
},
{
"id": 3,
"title": "Buy groceries",
"description": "Purchase ingredients for dinner and weekly supplies.",
"due_date": "2024-02-17T16:32:03Z",
"priority": "Low",
"status": "Pending"
},
{
"id": 4,
"title": "Update website",
"description": "Update the homepage with new content and images.",
"due_date": "2024-07-16T15:49:59Z",
"priority": "Medium",
"status": "Pending"
},
{
"id": 5,
"title": "Send emails",
"description": "Send out follow-up emails to clients from last week's meeting.",
"due_date": "2024-09-24T11:08:14Z",
"priority": "High",
"status": "Completed"
},
{
"id": 6,
"title": "Organize workspace",
"description": "Declutter desk and organize office supplies.",
"due_date": "2024-10-06T11:49:14Z",
"priority": "Low",
"status": "Pending"
},
{
"id": 7,
"title": "Prepare presentation",
"description": "Create slides for next week's client pitch.",
"due_date": "2024-05-20T04:38:51Z",
"priority": "High",
"status": "In Progress"
},
{
"id": 8,
"title": "Write blog post",
"description": "Write a blog post about industry trends for the company website.",
"due_date": "2024-01-13T07:46:34Z",
"priority": "Medium",
"status": "Pending"
},
{
"id": 9,
"title": "Schedule doctor's appointment",
"description": "Call and book a check-up appointment with the doctor.",
"due_date": "2024-09-22T10:54:21Z",
"priority": "Low",
"status": "Pending"
},
{
"id": 10,
"title": "Review budget",
"description": "Review and adjust monthly budget for expenses.",
"due_date": "2024-08-20T03:57:48Z",
"priority": "Medium",
"status": "Pending"
}
]

View File

@ -1,62 +0,0 @@
[
{
"id": 1,
"first_name": "Roobbie",
"last_name": "Ivashintsov",
"email": "rivashintsov0@symantec.com"
},
{
"id": 2,
"first_name": "Cissy",
"last_name": "Salmons",
"email": "csalmons1@unicef.org"
},
{
"id": 3,
"first_name": "Jillene",
"last_name": "Besnardeau",
"email": "jbesnardeau2@china.com.cn"
},
{
"id": 4,
"first_name": "Catriona",
"last_name": "Wrennall",
"email": "cwrennall3@godaddy.com"
},
{
"id": 5,
"first_name": "Risa",
"last_name": "Rumens",
"email": "rrumens4@un.org"
},
{
"id": 6,
"first_name": "Gianina",
"last_name": "Pavlenkov",
"email": "gpavlenkov5@ted.com"
},
{
"id": 7,
"first_name": "Tripp",
"last_name": "Blowick",
"email": "tblowick6@reuters.com"
},
{
"id": 8,
"first_name": "Ephrem",
"last_name": "Pfertner",
"email": "epfertner7@godaddy.com"
},
{
"id": 9,
"first_name": "Jacinda",
"last_name": "Tomkies",
"email": "jtomkies8@si.edu"
},
{
"id": 10,
"first_name": "Traver",
"last_name": "Poile",
"email": "tpoile9@phoca.cz"
}
]

View File

@ -1,56 +0,0 @@
[
{
"id": 1,
"session_duration": "2023-08-18T14:47:41Z",
"channel": "Organic Search",
"session": 547,
"bounce_rate": 27.2,
"target_reached": 843,
"page_per_session": 4.4
},
{
"id": 2,
"session_duration": "2023-04-20T20:13:24Z",
"channel": "Direct",
"session": 855,
"bounce_rate": 25.8,
"target_reached": 998,
"page_per_session": 6.6
},
{
"id": 3,
"session_duration": "2023-09-05T02:15:03Z",
"channel": "Referral",
"session": 337,
"bounce_rate": 12.4,
"target_reached": 509,
"page_per_session": 8.0
},
{
"id": 4,
"session_duration": "2023-06-23T13:50:55Z",
"channel": "Social",
"session": 279,
"bounce_rate": 40.4,
"target_reached": 860,
"page_per_session": 7.3
},
{
"id": 5,
"session_duration": "2023-09-14T09:01:34Z",
"channel": "Email",
"session": 118,
"bounce_rate": 46.2,
"target_reached": 168,
"page_per_session": 3.0
},
{
"id": 6,
"session_duration": "2023-07-14T01:46:51Z",
"channel": "Paid Search",
"session": 205,
"bounce_rate": 32.8,
"target_reached": 583,
"page_per_session": 2.5
}
]

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 KiB

View File

@ -1,52 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/visitor_by_channels_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class AnalyticsController extends MyController {
String selectActivity = "Year";
List<VisitorByChannelsModel> visitorByChannel = [];
final TooltipBehavior columnChartToolTip = TooltipBehavior(enable: true, format: 'point.x : point.y', tooltipPosition: TooltipPosition.pointer);
final TooltipBehavior audienceOverview = TooltipBehavior(enable: true, format: 'point.x : point.y', tooltipPosition: TooltipPosition.pointer);
@override
void onInit() {
VisitorByChannelsModel.dummyList.then((value) {
visitorByChannel = value;
update();
});
super.onInit();
}
void onSelectedActivity(String time) {
selectActivity = time;
update();
}
void removeData(index) {
visitorByChannel.removeAt(index);
update();
}
final List<ChartSampleData> columnChart = <ChartSampleData>[
ChartSampleData(x: 2010, y: 32, yValue: 50),
ChartSampleData(x: 2011, y: 44, yValue: 40),
ChartSampleData(x: 2012, y: 40, yValue: 60),
ChartSampleData(x: 2013, y: 50, yValue: 38),
ChartSampleData(x: 2014, y: 10, yValue: 28),
ChartSampleData(x: 2015, y: 20, yValue: 16),
ChartSampleData(x: 2016, y: 30, yValue: 50),
];
final List<ChartSampleData> audienceOverviewChart = [
ChartSampleData(x: 2018, y: 50, yValue: 38),
ChartSampleData(x: 2019, y: 10, yValue: 28),
ChartSampleData(x: 2020, y: 32, yValue: 50),
ChartSampleData(x: 2020, y: 44, yValue: 40),
ChartSampleData(x: 2020, y: 40, yValue: 60),
ChartSampleData(x: 2020, y: 50, yValue: 38),
ChartSampleData(x: 2021, y: 10, yValue: 28),
ChartSampleData(x: 2022, y: 20, yValue: 16),
ChartSampleData(x: 2023, y: 30, yValue: 50)
];
}

View File

@ -1,35 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/lead_report_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class CrmController extends MyController {
List<ChartSampleData>? chartData;
List<LeadReportModel> leadReport = [];
TooltipBehavior? tooltipBehavior;
@override
void onInit() {
tooltipBehavior = TooltipBehavior(enable: true);
chartData = <ChartSampleData>[
ChartSampleData(x: 'Jan', y: 10, secondSeriesYValue: 5),
ChartSampleData(x: 'Feb', y: 12, secondSeriesYValue: 8),
ChartSampleData(x: 'Mar', y: 14, secondSeriesYValue: 9),
ChartSampleData(x: 'Apr', y: 11, secondSeriesYValue: 7),
ChartSampleData(x: 'May', y: 15, secondSeriesYValue: 10),
ChartSampleData(x: 'Jun', y: 9, secondSeriesYValue: 6),
ChartSampleData(x: 'Jul', y: 13, secondSeriesYValue: 7),
ChartSampleData(x: 'Aug', y: 12, secondSeriesYValue: 8),
ChartSampleData(x: 'Sep', y: 14, secondSeriesYValue: 10),
ChartSampleData(x: 'Oct', y: 15, secondSeriesYValue: 12),
ChartSampleData(x: 'Nov', y: 13, secondSeriesYValue: 9),
ChartSampleData(x: 'Dec', y: 11, secondSeriesYValue: 6),
];
LeadReportModel.dummyList.then((value) {
leadReport = value.sublist(0, 5);
update();
});
super.onInit();
}
}

View File

@ -1,43 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/coin_growth_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class CryptoController extends MyController {
List<ChartSampleData>? chartData;
DateTimeIntervalType intervalType = DateTimeIntervalType.months;
List<CoinGrowthModel> coinGrowth = [];
bool enableSolidCandle = false;
TrackballBehavior? trackballBehavior;
@override
void onInit() {
CoinGrowthModel.dummyList.then((value) {
coinGrowth = value.sublist(0, 5);
update();
});
chartData = <ChartSampleData>[
ChartSampleData(x: 'Jan', y: 50, secondSeriesYValue: 40, thirdSeriesYValue: 45),
ChartSampleData(x: 'Feb', y: 47, secondSeriesYValue: 39, thirdSeriesYValue: 48),
ChartSampleData(x: 'Mar', y: 55, secondSeriesYValue: 42, thirdSeriesYValue: 50),
ChartSampleData(x: 'Apr', y: 60, secondSeriesYValue: 45, thirdSeriesYValue: 53),
ChartSampleData(x: 'May', y: 70, secondSeriesYValue: 50, thirdSeriesYValue: 58),
ChartSampleData(x: 'Jun', y: 75, secondSeriesYValue: 55, thirdSeriesYValue: 62),
ChartSampleData(x: 'Jul', y: 80, secondSeriesYValue: 58, thirdSeriesYValue: 65),
ChartSampleData(x: 'Aug', y: 78, secondSeriesYValue: 60, thirdSeriesYValue: 66),
ChartSampleData(x: 'Sep', y: 72, secondSeriesYValue: 55, thirdSeriesYValue: 64),
ChartSampleData(x: 'Oct', y: 65, secondSeriesYValue: 50, thirdSeriesYValue: 57),
ChartSampleData(x: 'Nov', y: 58, secondSeriesYValue: 45, thirdSeriesYValue: 53),
ChartSampleData(x: 'Dec', y: 50, secondSeriesYValue: 40, thirdSeriesYValue: 48)
];
super.onInit();
}
void onSelectIntervalType(DateTimeIntervalType interval) {
intervalType = interval;
update();
}
}

View File

@ -1,69 +0,0 @@
import 'package:flutter/material.dart';
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/product_order_modal.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class EcommerceController extends MyController {
List<ChartSampleData>? salesAnalyticsData;
List<ProductOrderModal> order = [];
String selectedTimeByLocation = "Year";
@override
void onInit() {
ProductOrderModal.dummyList.then((value) {
order = value.sublist(0, 5);
update();
});
salesAnalyticsData = <ChartSampleData>[
ChartSampleData(x: 'Jan', y: 43, secondSeriesYValue: 37, thirdSeriesYValue: 41),
ChartSampleData(x: 'Feb', y: 45, secondSeriesYValue: 37, thirdSeriesYValue: 45),
ChartSampleData(x: 'Mar', y: 50, secondSeriesYValue: 39, thirdSeriesYValue: 48),
ChartSampleData(x: 'Apr', y: 55, secondSeriesYValue: 43, thirdSeriesYValue: 52),
ChartSampleData(x: 'May', y: 63, secondSeriesYValue: 48, thirdSeriesYValue: 57),
ChartSampleData(x: 'Jun', y: 68, secondSeriesYValue: 54, thirdSeriesYValue: 61),
ChartSampleData(x: 'Jul', y: 72, secondSeriesYValue: 57, thirdSeriesYValue: 66),
ChartSampleData(x: 'Aug', y: 70, secondSeriesYValue: 57, thirdSeriesYValue: 66),
ChartSampleData(x: 'Sep', y: 66, secondSeriesYValue: 54, thirdSeriesYValue: 63),
ChartSampleData(x: 'Oct', y: 57, secondSeriesYValue: 48, thirdSeriesYValue: 55),
ChartSampleData(x: 'Nov', y: 50, secondSeriesYValue: 43, thirdSeriesYValue: 50),
ChartSampleData(x: 'Dec', y: 45, secondSeriesYValue: 37, thirdSeriesYValue: 45)
];
super.onInit();
}
final List<ChartSampleData> chartData = [
ChartSampleData(x: 'Jan', y: 10, yValue: 1000),
ChartSampleData(x: 'Fab', y: 20, yValue: 2000),
ChartSampleData(x: 'Mar', y: 15, yValue: 1500),
ChartSampleData(x: 'Jun', y: 5, yValue: 500),
ChartSampleData(x: 'Jul', y: 30, yValue: 3000),
ChartSampleData(x: 'Aug', y: 20, yValue: 2000),
ChartSampleData(x: 'Sep', y: 40, yValue: 4000),
ChartSampleData(x: 'Oct', y: 60, yValue: 6000),
ChartSampleData(x: 'Nov', y: 55, yValue: 5500),
ChartSampleData(x: 'Dec', y: 38, yValue: 3000),
];
final TooltipBehavior chart = TooltipBehavior(
enable: true,
format: 'point.x : point.yValue1 : point.yValue2',
);
final List<ChartSampleData> circleChart = [
ChartSampleData(x: 'David', y: 25, pointColor: const Color.fromRGBO(9, 0, 136, 1)),
ChartSampleData(x: 'Steve', y: 38, pointColor: const Color.fromRGBO(147, 0, 119, 1)),
ChartSampleData(x: 'Jack', y: 34, pointColor: const Color.fromRGBO(228, 0, 124, 1)),
ChartSampleData(x: 'Others', y: 52, pointColor: const Color.fromRGBO(255, 189, 57, 1))
];
void onSelectedTimeByLocation(String time) {
selectedTimeByLocation = time;
update();
}
@override
void dispose() {
salesAnalyticsData!.clear();
super.dispose();
}
}

View File

@ -1,42 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/helpers/widgets/my_text_utils.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/job_recent_application_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class JobController extends MyController {
int isSelectedListingPerformanceTime = 0;
List<ChartSampleData>? chartData;
TooltipBehavior? columnToolTip;
List<JobRecentApplicationModel> recentApplication = [];
List<String> dummyTexts = List.generate(12, (index) => MyTextUtils.getDummyText(60));
@override
void onInit() {
chartData = <ChartSampleData>[
ChartSampleData(x: 'Jan', y: 4, secondSeriesYValue: 8),
ChartSampleData(x: 'Feb', y: 9, secondSeriesYValue: 7),
ChartSampleData(x: 'Mar', y: 6, secondSeriesYValue: 5),
ChartSampleData(x: 'Apr', y: 8, secondSeriesYValue: 3),
ChartSampleData(x: 'May', y: 7, secondSeriesYValue: 9),
ChartSampleData(x: 'Jun', y: 10, secondSeriesYValue: 6),
ChartSampleData(x: 'Jul', y: 5, secondSeriesYValue: 4),
ChartSampleData(x: 'Aug', y: 3, secondSeriesYValue: 2),
ChartSampleData(x: 'Sep', y: 6, secondSeriesYValue: 10),
ChartSampleData(x: 'Oct', y: 4, secondSeriesYValue: 8),
ChartSampleData(x: 'Nov', y: 9, secondSeriesYValue: 6),
ChartSampleData(x: 'Dec', y: 7, secondSeriesYValue: 5),
];
columnToolTip = TooltipBehavior(enable: true);
JobRecentApplicationModel.dummyList.then((value) {
recentApplication = value.sublist(0, 5);
update();
});
super.onInit();
}
void onSelectListingPerformanceTimeToggle(index) {
isSelectedListingPerformanceTime = index;
update();
}
}

View File

@ -1,46 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/project_summary_model.dart';
import 'package:marco/model/task_list_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class ProjectController extends MyController {
TooltipBehavior? tooltipBehavior;
List<TaskListModel> task = [];
List<ProjectSummaryModel> projectSummary = [];
List<ChartSampleData>? chartData;
@override
void onInit() {
TaskListModel.dummyList.then((value) {
task = value;
update();
});
ProjectSummaryModel.dummyList.then((value) {
projectSummary = value.sublist(0, 5);
update();
});
chartData = <ChartSampleData>[
ChartSampleData(x: 'Jan', y: 10, secondSeriesYValue: 8, thirdSeriesYValue: 12),
ChartSampleData(x: 'Feb', y: 5, secondSeriesYValue: 6, thirdSeriesYValue: 7),
ChartSampleData(x: 'Mar', y: 11, secondSeriesYValue: 9, thirdSeriesYValue: 6),
ChartSampleData(x: 'Apr', y: 14, secondSeriesYValue: 10, thirdSeriesYValue: 13),
ChartSampleData(x: 'May', y: 9, secondSeriesYValue: 7, thirdSeriesYValue: 5),
ChartSampleData(x: 'Jun', y: 8, secondSeriesYValue: 12, thirdSeriesYValue: 11),
ChartSampleData(x: 'Jul', y: 12, secondSeriesYValue: 11, thirdSeriesYValue: 9),
ChartSampleData(x: 'Aug', y: 7, secondSeriesYValue: 13, thirdSeriesYValue: 10),
ChartSampleData(x: 'Sep', y: 6, secondSeriesYValue: 5, thirdSeriesYValue: 8),
ChartSampleData(x: 'Oct', y: 4, secondSeriesYValue: 14, thirdSeriesYValue: 15),
ChartSampleData(x: 'Nov', y: 13, secondSeriesYValue: 4, thirdSeriesYValue: 11),
ChartSampleData(x: 'Dec', y: 15, secondSeriesYValue: 3, thirdSeriesYValue: 4)
];
tooltipBehavior = TooltipBehavior(enable: true, format: 'point.x : point.ym');
super.onInit();
}
void onSelectTask(TaskListModel task) {
task.isSelectTask = !task.isSelectTask;
update();
}
}

View File

@ -1,56 +0,0 @@
import 'package:marco/controller/my_controller.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/recent_order_model.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class SalesController extends MyController {
List<ChartData>? statisticsData;
List<RecentOrderModel> recentOrder = [];
@override
void onInit() {
RecentOrderModel.dummyList.then((value) {
recentOrder = value;
update();
});
statisticsData = <ChartData>[
ChartData(2005, 15, 25),
ChartData(2006, 40, 55),
ChartData(2007, 50, 70),
ChartData(2008, 55, 80),
ChartData(2009, 65, 85),
ChartData(2010, 70, 95),
ChartData(2011, 90, 110)
];
super.onInit();
}
final List<ChartSampleData> visitorChartData = [
ChartSampleData(x: 'Jan', y: 12, yValue: 1200),
ChartSampleData(x: 'Feb', y: 18, yValue: 1800),
ChartSampleData(x: 'Mar', y: 22, yValue: 2200),
ChartSampleData(x: 'Apr', y: 10, yValue: 1000),
ChartSampleData(x: 'May', y: 25, yValue: 2500),
ChartSampleData(x: 'Jun', y: 35, yValue: 3500),
ChartSampleData(x: 'Jul', y: 28, yValue: 2800),
ChartSampleData(x: 'Aug', y: 45, yValue: 4500),
ChartSampleData(x: 'Sep', y: 50, yValue: 5000),
ChartSampleData(x: 'Oct', y: 60, yValue: 6000),
ChartSampleData(x: 'Nov', y: 42, yValue: 4200),
ChartSampleData(x: 'Dec', y: 55, yValue: 5500),
];
final TooltipBehavior visitorChart = TooltipBehavior(
enable: true,
format: 'point.x : point.yValue1 : point.yValue2',
);
}
class ChartData {
ChartData(this.x, this.y, this.y2);
final double x;
final double y;
final double y2;
}

View File

@ -1,34 +0,0 @@
import 'package:flutter/material.dart';
class ChartSampleData {
ChartSampleData(
{this.x,
this.y,
this.xValue,
this.yValue,
this.secondSeriesYValue,
this.thirdSeriesYValue,
this.pointColor,
this.size,
this.text,
this.open,
this.close,
this.low,
this.high,
this.volume});
final dynamic x;
final num? y;
final dynamic xValue;
final num? yValue;
final num? secondSeriesYValue;
final num? thirdSeriesYValue;
final Color? pointColor;
final num? size;
final String? text;
final num? open;
final num? close;
final num? low;
final num? high;
final num? volume;
}

View File

@ -1,72 +0,0 @@
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:marco/helpers/services/json_decoder.dart';
import 'package:marco/images.dart';
import 'package:marco/model/identifier_model.dart';
class ChatModel extends IdentifierModel {
final String firstName, avatar, email;
final List<ChatMessageModel> messages;
ChatModel(super.id, this.firstName, this.avatar, this.messages, this.email);
static ChatModel fromJSON(Map<String, dynamic> json) {
JSONDecoder decoder = JSONDecoder(json);
String firstName = decoder.getString('first_name');
String email = decoder.getString('email');
String avatar = Images.randomImage(Images.avatars);
List<dynamic>? messagesList = decoder.getObjectListOrNull('messages');
List<ChatMessageModel> messages = [];
if (messagesList != null) {
messages = ChatMessageModel.listFromJSON(messagesList);
}
return ChatModel(decoder.getId, firstName, avatar, messages, email);
}
static List<ChatModel> listFromJSON(List<dynamic> list) {
return list.map((e) => ChatModel.fromJSON(e)).toList();
}
static List<ChatModel>? _dummyList;
static Future<List<ChatModel>> get dummyList async {
if (_dummyList == null) {
dynamic data = json.decode(await getData());
_dummyList = listFromJSON(data);
}
return _dummyList!;
}
static Future<String> getData() async {
return await rootBundle.loadString('assets/data/chat.json');
}
}
class ChatMessageModel extends IdentifierModel {
final String message, imageSent;
final DateTime sendAt;
final bool fromMe;
ChatMessageModel(super.id, this.message, this.sendAt, this.fromMe, this.imageSent);
static ChatMessageModel fromJSON(Map<String, dynamic> json) {
JSONDecoder decoder = JSONDecoder(json);
String message = decoder.getString('message');
String imageSent = Images.randomImage(Images.avatars);
DateTime sendAt = decoder.getDateTime('send_at');
bool fromMe = decoder.getBool('from_me');
return ChatMessageModel(decoder.getId, message, sendAt, fromMe, imageSent);
}
static List<ChatMessageModel> listFromJSON(List<dynamic> list) {
return list.map((e) => ChatMessageModel.fromJSON(e)).toList();
}
}

View File

@ -1,51 +0,0 @@
import 'dart:convert';
import 'package:marco/helpers/services/json_decoder.dart';
import 'package:marco/model/identifier_model.dart';
import 'package:flutter/services.dart';
class CoinGrowthModel extends IdentifierModel {
final String asset, ipAddress, status;
final int amount;
final DateTime date;
CoinGrowthModel(
super.id,
this.asset,
this.ipAddress,
this.status,
this.amount,
this.date,
);
static CoinGrowthModel fromJSON(Map<String, dynamic> json) {
JSONDecoder decoder = JSONDecoder(json);
String asset = decoder.getString('asset');
String ipAddress = decoder.getString('ip_address');
String status = decoder.getString('status');
int amount = decoder.getInt('amount');
DateTime date = decoder.getDateTime('date');
return CoinGrowthModel(decoder.getId, asset, ipAddress, status, amount, date);
}
static List<CoinGrowthModel> listFromJSON(List<dynamic> list) {
return list.map((e) => CoinGrowthModel.fromJSON(e)).toList();
}
static List<CoinGrowthModel>? _dummyList;
static Future<List<CoinGrowthModel>> get dummyList async {
if (_dummyList == null) {
dynamic data = json.decode(await getData());
_dummyList = listFromJSON(data);
}
return _dummyList!;
}
static Future<String> getData() async {
return await rootBundle.loadString('assets/data/coin_growth.json');
}
}

View File

@ -1,66 +0,0 @@
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:marco/helpers/services/json_decoder.dart';
import 'package:marco/model/identifier_model.dart';
class Customer extends IdentifierModel {
final String firstName, lastName, phoneNumber, projectName, balance;
final double ordersCount;
final DateTime lastOrder;
String get fullName => '$firstName $lastName $projectName';
Customer(
super.id,
this.firstName,
this.lastName,
this.phoneNumber,
this.balance,
this.ordersCount,
this.lastOrder,
this.projectName,
);
static Customer fromJSON(Map<String, dynamic> json) {
JSONDecoder decoder = JSONDecoder(json);
String firstName = decoder.getString('first_name');
String lastName = decoder.getString('last_name');
String phoneNumber = decoder.getString('phone_number');
String balance = decoder.getString('balance');
double ordersCount = decoder.getDouble('order_count');
DateTime lastOrder = decoder.getDateTime('last_order');
String projectName = decoder.getString('project_name');
return Customer(
decoder.getId,
firstName,
lastName,
phoneNumber,
balance,
ordersCount,
lastOrder,
projectName,
);
}
static List<Customer> listFromJSON(List<dynamic> list) {
return list.map((e) => Customer.fromJSON(e)).toList();
}
static List<Customer>? _dummyList;
static Future<List<Customer>> get dummyList async {
if (_dummyList == null) {
dynamic data = json.decode(await getData());
_dummyList = listFromJSON(data);
}
return _dummyList!.sublist(0, 10);
}
static Future<String> getData() async {
return await rootBundle.loadString('assets/data/customer.json');
}
}

View File

@ -9,10 +9,6 @@ import 'package:marco/view/error_pages/coming_soon_screen.dart';
import 'package:marco/view/error_pages/error_404_screen.dart'; import 'package:marco/view/error_pages/error_404_screen.dart';
import 'package:marco/view/error_pages/error_500_screen.dart'; import 'package:marco/view/error_pages/error_500_screen.dart';
import 'package:marco/view/dashboard/dashboard_screen.dart'; import 'package:marco/view/dashboard/dashboard_screen.dart';
import 'package:marco/view/dashboard/add_employee_screen.dart';
import 'package:marco/view/dashboard/daily_task_screen.dart';
import 'package:marco/view/taskPlaning/report_task_screen.dart';
import 'package:marco/view/taskPlaning/comment_task_screen.dart';
import 'package:marco/view/dashboard/Attendence/attendance_screen.dart'; import 'package:marco/view/dashboard/Attendence/attendance_screen.dart';
import 'package:marco/view/taskPlaning/daily_task_planing.dart'; import 'package:marco/view/taskPlaning/daily_task_planing.dart';
import 'package:marco/view/taskPlaning/daily_progress.dart'; import 'package:marco/view/taskPlaning/daily_progress.dart';
@ -55,16 +51,7 @@ getPageRoute() {
name: '/dashboard/employees', name: '/dashboard/employees',
page: () => EmployeesScreen(), page: () => EmployeesScreen(),
middlewares: [AuthMiddleware()]), middlewares: [AuthMiddleware()]),
// Employees Creation
GetPage(
name: '/employees/addEmployee',
page: () => AddEmployeeScreen(),
middlewares: [AuthMiddleware()]),
// Daily Task Planning // Daily Task Planning
GetPage(
name: '/dashboard/daily-task',
page: () => DailyTaskScreen(),
middlewares: [AuthMiddleware()]),
GetPage( GetPage(
name: '/dashboard/daily-task-planing', name: '/dashboard/daily-task-planing',
page: () => DailyTaskPlaningScreen(), page: () => DailyTaskPlaningScreen(),
@ -73,14 +60,6 @@ getPageRoute() {
name: '/dashboard/daily-task-progress', name: '/dashboard/daily-task-progress',
page: () => DailyProgressReportScreen(), page: () => DailyProgressReportScreen(),
middlewares: [AuthMiddleware()]), middlewares: [AuthMiddleware()]),
GetPage(
name: '/daily-task/report-task',
page: () => ReportTaskScreen(),
middlewares: [AuthMiddleware()]),
GetPage(
name: '/daily-task/comment-task',
page: () => CommentTaskScreen(),
middlewares: [AuthMiddleware()]),
// Authentication // Authentication
GetPage(name: '/auth/login', page: () => LoginScreen()), GetPage(name: '/auth/login', page: () => LoginScreen()),
GetPage(name: '/auth/login-option', page: () => LoginOptionScreen()), GetPage(name: '/auth/login-option', page: () => LoginOptionScreen()),

View File

@ -1,261 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/dashboard/add_employee_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_button.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/my_text_style.dart';
import 'package:marco/view/layouts/layout.dart';
class AddEmployeeScreen extends StatefulWidget {
const AddEmployeeScreen({super.key});
@override
State<AddEmployeeScreen> createState() => _AddEmployeeScreenState();
}
class _AddEmployeeScreenState extends State<AddEmployeeScreen> with UIMixin {
final AddEmployeeController controller = Get.put(AddEmployeeController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder<AddEmployeeController>(
init: controller,
tag: 'add_employee_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium(
"Add Employee",
fontSize: 18,
fontWeight: 600,
),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Employee'),
MyBreadcrumbItem(name: 'Add Employee'),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: "lg-8 md-12", child: detail()),
],
),
),
],
);
},
),
);
}
Widget detail() {
return Form(
key: controller.basicValidator.formKey,
child: MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withOpacity(0.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(LucideIcons.server, size: 16),
MySpacing.width(12),
MyText.titleMedium("General", fontWeight: 600),
],
),
MySpacing.height(24),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("First Name"),
MySpacing.height(8),
TextFormField(
validator: controller.basicValidator.getValidation('first_name'),
controller: controller.basicValidator.getController('first_name'),
keyboardType: TextInputType.name,
decoration: InputDecoration(
hintText: "eg: Jhon",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
MyText.labelMedium("Last Name"),
MySpacing.height(8),
TextFormField(
validator: controller.basicValidator.getValidation('last_name'),
controller: controller.basicValidator.getController('last_name'),
keyboardType: TextInputType.name,
decoration: InputDecoration(
hintText: "eg: Doe",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
MyText.labelMedium("Phone Number"),
MySpacing.height(8),
TextFormField(
validator: controller.basicValidator.getValidation('phone_number'),
controller: controller.basicValidator.getController('phone_number'),
keyboardType: TextInputType.phone,
decoration: InputDecoration(
hintText: "eg: +91 9876543210",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
MyFlex(contentPadding: false, children: [
MyFlexItem(
sizes: 'lg-6 md-12',
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("Select Gender"),
MySpacing.height(8),
DropdownButtonFormField<Gender>(
value: controller.selectedGender,
dropdownColor: contentTheme.background,
menuMaxHeight: 200,
isDense: true,
items: Gender.values.map((gender) {
return DropdownMenuItem<Gender>(
value: gender,
child: MyText.labelMedium(
gender.name[0].toUpperCase() + gender.name.substring(1),
),
);
}).toList(),
icon: const Icon(Icons.expand_more, size: 20),
decoration: InputDecoration(
hintText: "Select Gender",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(14),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
onChanged: controller.onGenderSelected,
),
],
),
),
]),
MySpacing.height(24),
MyFlex(contentPadding: false, children: [
MyFlexItem(
sizes: 'lg-6 md-12',
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("Select Role"),
MySpacing.height(8),
DropdownButtonFormField<String>(
value: controller.selectedRoleId,
dropdownColor: contentTheme.background,
decoration: InputDecoration(
hintText: "Select Role",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(14),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
icon: const Icon(Icons.expand_more, size: 20),
isDense: true,
items: controller.roles.map((role) {
return DropdownMenuItem<String>(
value: role['id'],
child: Text(role['name']),
);
}).toList(),
onChanged: controller.onRoleSelected,
),
],
),
),
]),
MySpacing.height(24),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
MyButton.text(
onPressed: () {
Get.back();
},
padding: MySpacing.xy(20, 16),
splashColor: contentTheme.secondary.withValues(alpha: 0.1),
child: MyText.bodySmall('Cancel'),
),
MySpacing.width(12),
MyButton(
onPressed: () async {
if (controller.basicValidator.validateForm()) {
await controller.createEmployees();
}
},
elevation: 0,
padding: MySpacing.xy(20, 16),
backgroundColor: contentTheme.primary,
borderRadiusAll: AppStyle.buttonRadius.medium,
child: MyText.bodySmall(
'Save',
color: contentTheme.onPrimary,
),
),
],
),
],
),
],
),
),
);
}
}

View File

@ -1,546 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/dashboard/analytics_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_progress_bar.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class AnalyticsScreen extends StatefulWidget {
const AnalyticsScreen({super.key});
@override
State<AnalyticsScreen> createState() => _AnalyticsScreenState();
}
class _AnalyticsScreenState extends State<AnalyticsScreen> with UIMixin {
AnalyticsController controller = Get.put(AnalyticsController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
tag: 'analytics_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Analytics", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Analytics', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(children: [
MyFlexItem(sizes: 'lg-2.4 md-6 sm-6', child: stats("Pending", "1.245", "5.12%", LucideIcons.clock)),
MyFlexItem(sizes: 'lg-2.4 md-6 sm-6', child: stats("Paid", "92.342", "67.89%", LucideIcons.circle_check)),
MyFlexItem(sizes: 'lg-2.4 md-4 sm-4', child: stats("Rejected", "12.367", "3.56%", LucideIcons.circle_x)),
MyFlexItem(sizes: 'lg-2.4 md-4 sm-4', child: stats("In Progress", "5.125", "10.78%", LucideIcons.hourglass)),
MyFlexItem(sizes: 'lg-2.4 md-4 sm-4', child: stats("Canceled", "7.489", "4.45%", LucideIcons.trash)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: activityOnThePage()),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: audienceOverview()),
MyFlexItem(sizes: 'lg-4 md-12', child: buildTrafficSources()),
MyFlexItem(sizes: 'lg-4 md-6 sm-6', child: buildMostActiveUser()),
MyFlexItem(sizes: 'lg-4 md-6 sm-6', child: buildVisitorsByCountry()),
MyFlexItem(child: buildVisitorByChannel()),
]),
)
],
);
},
),
);
}
Widget stats(String title, String subTitle, String percentage, IconData icon) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Column(
children: [
Padding(
padding: MySpacing.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodySmall(title, maxLines: 1),
MySpacing.height(4),
MyText.titleLarge(subTitle, maxLines: 1),
],
),
),
MyContainer(
color: contentTheme.secondary.withValues(alpha:0.2),
paddingAll: 12,
child: Icon(icon, size: 16, color: contentTheme.onBackground),
)
],
),
),
MyContainer(
color: contentTheme.background,
borderRadiusAll: 0,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Row(
children: [
Icon(LucideIcons.arrow_up_right, size: 16),
MySpacing.width(8),
MyText.labelMedium(percentage),
MySpacing.width(8),
Expanded(child: MyText.labelMedium("Last Month", muted: true, maxLines: 1)),
Expanded(child: InkWell(onTap: () {}, child: MyText.labelMedium("View More", fontWeight: 600, maxLines: 1))),
],
),
)
],
),
);
}
Widget activityOnThePage() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: MyText.bodyMedium("Activity on the pages", fontWeight: 600, overflow: TextOverflow.ellipsis),
),
PopupMenuButton(
onSelected: controller.onSelectedActivity,
clipBehavior: Clip.antiAliasWithSaveLayer,
itemBuilder: (BuildContext context) {
return ["Year", "Month", "Week", "Day", "Hours"].map((behavior) {
return PopupMenuItem(
value: behavior,
height: 32,
child: MyText.bodySmall(
behavior.toString(),
color: theme.colorScheme.onSurface,
fontWeight: 600,
),
);
}).toList();
},
color: theme.cardTheme.color,
child: MyContainer.bordered(
padding: MySpacing.xy(8, 4),
borderRadiusAll: 8,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
MyText.bodySmall(
controller.selectActivity.toString(),
fontWeight: 600,
color: theme.colorScheme.onSurface,
),
MySpacing.width(4),
Icon(
LucideIcons.chevron_down,
size: 20,
color: theme.colorScheme.onSurface,
)
],
),
),
),
],
),
MySpacing.height(24),
SizedBox(
height: 305,
child: SfCartesianChart(
plotAreaBorderWidth: 0,
primaryXAxis: CategoryAxis(majorGridLines: MajorGridLines(width: 0)),
tooltipBehavior: controller.columnChartToolTip,
legend: Legend(isVisible: true, position: LegendPosition.bottom),
series: [
ColumnSeries<ChartSampleData, int>(
opacity: 0.9,
width: 0.6,
color: contentTheme.title,
dataSource: controller.columnChart,
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.y,
dataLabelSettings: DataLabelSettings(isVisible: true)),
ColumnSeries<ChartSampleData, int>(
color: contentTheme.success,
dataSource: controller.columnChart,
borderRadius: BorderRadius.vertical(top: Radius.circular(8)),
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.yValue,
dataLabelSettings: DataLabelSettings(isVisible: true),
),
],
),
),
],
),
);
}
Widget audienceOverview() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Audience Overview", fontWeight: 600),
MySpacing.height(24),
SizedBox(
height: 318,
child: SfCartesianChart(tooltipBehavior: controller.audienceOverview, series: <CartesianSeries>[
BarSeries<ChartSampleData, dynamic>(
color: Colors.blue,
borderRadius: BorderRadius.horizontal(right: Radius.circular(8)),
dataSource: controller.audienceOverviewChart,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.y,
width: 0.6,
spacing: 0.3),
BarSeries<ChartSampleData, dynamic>(
borderRadius: BorderRadius.horizontal(right: Radius.circular(8)),
dataSource: controller.audienceOverviewChart,
color: Colors.teal,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.yValue,
width: 0.6,
spacing: 0.3)
]))
],
),
);
}
Widget buildTrafficSources() {
Widget buildData(String browser, session, double process) {
return Row(
children: [
Expanded(child: MyText.bodyMedium(browser, fontWeight: 600, overflow: TextOverflow.ellipsis)),
Expanded(
child: Row(
children: [
if (session >= 5000) Icon(LucideIcons.trending_up, size: 20, color: contentTheme.success),
if (session < 5000) Icon(LucideIcons.trending_down, size: 20, color: contentTheme.danger),
MySpacing.width(8),
Expanded(
child: MyText.bodyMedium("$session", fontWeight: 600, overflow: TextOverflow.ellipsis),
),
],
),
),
Expanded(
child: MyProgressBar(
progress: process,
height: 4,
radius: 4,
inactiveColor: theme.dividerColor,
activeColor: contentTheme.primary,
),
),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.only(left: 23, top: 19),
child: MyText.titleMedium("Traffic Sources", fontWeight: 600),
),
MySpacing.height(24),
Divider(height: 0),
MySpacing.height(24),
Padding(
padding: MySpacing.only(left: 23),
child: Row(children: [
Expanded(child: MyText.bodyMedium("Browser", fontWeight: 600)),
Expanded(child: MyText.bodyMedium("Sessions", fontWeight: 600)),
Expanded(child: MyText.bodyMedium("Traffic", fontWeight: 600)),
]),
),
MySpacing.height(24),
Divider(height: 0),
Padding(
padding: MySpacing.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildData("Google Chrome", 12000, .30),
MySpacing.height(24),
buildData("Apple Safari", 7000, .25),
MySpacing.height(24),
buildData("Microsoft Edge", 4500, .15),
MySpacing.height(24),
buildData("Mozilla Firefox", 8000, .22),
MySpacing.height(24),
buildData("Opera Browser", 3000, .18),
MySpacing.height(24),
buildData("Brave Browser", 2000, .12),
MySpacing.height(24),
buildData("Vivaldi Browser", 1500, .08),
],
),
)
],
),
);
}
Widget buildMostActiveUser() {
Widget buildData(String image, name, emailID) {
return MyContainer.bordered(
child: Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 44,
width: 44,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(name, fontWeight: 600),
MySpacing.height(4),
MyText.labelMedium(
emailID,
fontWeight: 600,
xMuted: true,
overflow: TextOverflow.ellipsis,
),
],
),
)
],
),
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.titleMedium("Most Active user", fontWeight: 600),
MySpacing.height(20),
SizedBox(
height: 372,
child: SingleChildScrollView(
child: Column(
children: [
buildData(Images.avatars[0], "John Doe", "john.doe@example.com"),
MySpacing.height(24),
buildData(Images.avatars[1], "Emily Smith", "emily.smith@example.com"),
MySpacing.height(24),
buildData(Images.avatars[2], "Michael Johnson", "michael.johnson@example.com"),
MySpacing.height(24),
buildData(Images.avatars[3], "Olivia Williams", "olivia.williams@example.com"),
],
),
),
),
],
));
}
Widget buildVisitorsByCountry() {
Widget buildData(String image, name, count) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 41,
width: 41,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(
image,
fit: BoxFit.cover,
),
),
MySpacing.width(12),
Expanded(
child: MyText.bodyMedium(name, fontWeight: 600, overflow: TextOverflow.ellipsis),
),
MyContainer(
borderRadiusAll: 8,
padding: MySpacing.xy(8, 8),
color: Colors.brown.withAlpha(36),
child: MyText.bodySmall(
numberFormatter(count),
fontWeight: 600,
color: Colors.brown,
),
)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.titleMedium("Visitor by country's", fontWeight: 600),
MySpacing.height(24),
buildData('assets/country/united_states.png', "United State", "41560"),
MySpacing.height(24),
buildData('assets/country/argentina.png', "Argentina", "18400"),
MySpacing.height(24),
buildData('assets/country/germany.png', "Germany", "9000"),
MySpacing.height(24),
buildData('assets/country/mexico.png', "Mexico", "15325"),
MySpacing.height(24),
buildData('assets/country/russia.png', "Russia", "12222"),
MySpacing.height(24),
buildData('assets/country/canada.png', "Canada", "2040"),
],
),
);
}
Widget buildVisitorByChannel() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Visitors By Channel", fontWeight: 600),
MySpacing.height(24),
if (controller.visitorByChannel.isNotEmpty)
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 105,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Channel', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Session', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Bounce Rate', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Session Duration', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Target Reached', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Page Per Session', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Action', color: contentTheme.primary)),
],
rows: controller.visitorByChannel
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.bodyMedium('${data.id}')),
DataCell(MyText.labelLarge(data.channel, overflow: TextOverflow.ellipsis, maxLines: 1)),
DataCell(MyText.bodySmall('${data.session}', fontWeight: 600)),
DataCell(MyText.bodySmall('${data.bounceRate}%', fontWeight: 600)),
DataCell(MyText.bodySmall('${Utils.getDateTimeStringFromDateTime(data.sessionDuration)}', fontWeight: 600)),
DataCell(
MyContainer(
borderRadiusAll: 4,
clipBehavior: Clip.antiAliasWithSaveLayer,
padding: MySpacing.xy(8, 8),
color: contentTheme.primary.withAlpha(32),
child: MyText.bodySmall('${data.targetReached}', fontWeight: 600, color: contentTheme.primary),
),
),
DataCell(MyText.bodyMedium('${data.pagePerSession}')),
DataCell(SizedBox(
width: 130,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyContainer(
onTap: () => {},
padding: MySpacing.xy(8, 8),
color: contentTheme.primary.withAlpha(36),
child: Icon(LucideIcons.pencil, size: 14, color: contentTheme.primary),
),
MyContainer(
onTap: () => {},
padding: MySpacing.xy(8, 8),
color: contentTheme.success.withAlpha(36),
child: Icon(LucideIcons.pencil, size: 14, color: contentTheme.success),
),
MyContainer(
onTap: () => controller.removeData(index),
padding: MySpacing.xy(8, 8),
color: contentTheme.danger.withAlpha(36),
child: Icon(LucideIcons.trash_2, size: 14, color: contentTheme.danger),
),
],
),
)),
]))
.toList()),
),
],
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,523 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/dashboard/crm_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_progress_bar.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class CrmScreen extends StatefulWidget {
const CrmScreen({super.key});
@override
State<CrmScreen> createState() => _CrmScreenState();
}
class _CrmScreenState extends State<CrmScreen> with UIMixin {
CrmController controller = Get.put(CrmController());
@override
Widget build(BuildContext context) {
return GetBuilder(
init: controller,
tag: 'crm_dashboard_controller',
builder: (controller) {
return Layout(
child: Column(
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Crm", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Crm', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(
sizes: "lg-3 md-6 sm-6",
child:
stats(LucideIcons.circle_dollar_sign, "Nominal Balance", "\$5,780", "Nominal Balance last month", "\$6,290", contentTheme.primary)),
MyFlexItem(
sizes: "lg-3 md-6 sm-6",
child: stats(LucideIcons.package, "Total Stock Product", "5.264", "Total Stock product last month", "2.546", contentTheme.secondary)),
MyFlexItem(
sizes: "lg-3 md-6 sm-6",
child: stats(LucideIcons.file_down, "Nominal Revenue", "5.264", "Total revenue last month", "2.546", contentTheme.success)),
MyFlexItem(
sizes: "lg-3 md-6 sm-6",
child: stats(LucideIcons.file_up, "Nominal Expenses", "\$19,644", "Total expenses last month", "\$18,946", contentTheme.warning)),
MyFlexItem(sizes: 'lg-9', child: revenueForecast()),
MyFlexItem(sizes: 'lg-3', child: topDeals()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: dealSource()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: leadResponse()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: openDeals()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: leadSource()),
MyFlexItem(child: leadReport()),
],
),
),
],
),
);
},
);
}
Widget stats(IconData icon, String title, String subTitle, String statsMonthName, String statsMonthRevenue, Color color) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: SizedBox(
height: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
MyContainer.bordered(paddingAll: 8, borderColor: color, child: Icon(icon, size: 16, color: color)),
MySpacing.width(12),
MyText.bodyMedium(title, fontWeight: 600),
],
),
MyText.titleMedium(subTitle, fontWeight: 600),
Row(
children: [
MyText.labelMedium(statsMonthName, fontWeight: 600, xMuted: true),
MySpacing.width(8),
Expanded(child: MyText.labelMedium(statsMonthRevenue, fontWeight: 600, maxLines: 1)),
],
),
],
),
),
);
}
Widget revenueForecast() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium("Revenue Forecast", fontWeight: 600),
PopupMenuButton(
offset: Offset(0, 20),
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none),
itemBuilder: (BuildContext context) => [
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Download", fontWeight: 600)),
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Import", fontWeight: 600)),
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Export", fontWeight: 600)),
],
child: Icon(LucideIcons.ellipsis_vertical, size: 20),
)
],
),
MySpacing.height(24),
SfCartesianChart(
plotAreaBorderWidth: 0,
primaryXAxis: const CategoryAxis(
majorGridLines: MajorGridLines(width: 0),
),
margin: MySpacing.zero,
primaryYAxis: const NumericAxis(maximum: 20, minimum: 0, interval: 4, axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(size: 0)),
series: [
ColumnSeries<ChartSampleData, String>(
width: 0.8,
spacing: 0.2,
dataSource: controller.chartData,
color: contentTheme.primary,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.y,
name: 'Sales Revenue'),
ColumnSeries<ChartSampleData, String>(
dataSource: controller.chartData,
width: 0.8,
spacing: 0.2,
color: contentTheme.secondary,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue,
name: 'Product Cost'),
],
legend: Legend(isVisible: true, position: LegendPosition.bottom),
tooltipBehavior: controller.tooltipBehavior,
)
],
),
);
}
Widget topDeals() {
Widget topDealsWidget(String image, String name, String email, String price) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 40,
width: 40,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(name, fontWeight: 600),
MyText.labelMedium(email, fontWeight: 600, muted: true, maxLines: 1),
],
),
),
MyText.labelMedium(price, fontWeight: 600),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium("Top Deals", fontWeight: 600),
PopupMenuButton(
offset: Offset(0, 20),
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: OutlineInputBorder(borderRadius: BorderRadius.circular(8), borderSide: BorderSide.none),
itemBuilder: (BuildContext context) => [
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Week", fontWeight: 600)),
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Month", fontWeight: 600)),
PopupMenuItem(padding: MySpacing.xy(16, 8), height: 10, child: MyText.bodySmall("Year", fontWeight: 600)),
],
child: Icon(LucideIcons.ellipsis_vertical, size: 20),
)
],
),
MySpacing.height(24),
topDealsWidget(Images.avatars[0], "Christopher", "christopher123@gmail.com", "\$14,541"),
MySpacing.height(24),
topDealsWidget(Images.avatars[1], "Edward", "edward15@gmail.com", "\$21,548"),
MySpacing.height(24),
topDealsWidget(Images.avatars[2], "Michael", "michael@gmail.com", "\$13,645"),
MySpacing.height(24),
topDealsWidget(Images.avatars[3], "Sebastian", "sebastian@gmail.com", "\$51,254"),
MySpacing.height(24),
topDealsWidget(Images.avatars[4], "Nicholas", "nicholas@gmail.com", "\$15,487"),
],
),
);
}
Widget dealSource() {
Widget dealSourceWidget(String image, String title, String subtitle, String totalLeads) {
return Row(
children: [
MyContainer.rounded(
height: 32,
width: 32,
paddingAll: 0,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title, fontWeight: 600),
MyText.bodySmall(subtitle),
],
),
),
MyText.labelSmall('$totalLeads Leads', fontWeight: 600),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Deal Source", fontWeight: 600),
MySpacing.height(24),
dealSourceWidget("assets/social/uxerflow_logo.png", "Website", "userflow.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/dribbble-logo.png", "Dribbble", "dribbble.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/facebook-logo.png", "Facebook", "facebook.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/instagram-logo.png", "Instagram", "instagram.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/LinkedIn-logo.png", "Linkedin", "linkedin.com", "50"),
],
),
);
}
Widget leadResponse() {
Widget leadData(String image, name, processRate, double progress) {
return Row(
children: [
MyContainer(
paddingAll: 0,
height: 32,
width: 32,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: MyText.labelLarge(name, fontWeight: 600, overflow: TextOverflow.ellipsis),
),
MyText.labelSmall(processRate, fontWeight: 600, overflow: TextOverflow.ellipsis),
],
),
MySpacing.height(8),
MyProgressBar(
width: 300,
height: 7,
progress: progress,
radius: 8,
activeColor: contentTheme.primary,
inactiveColor: contentTheme.primary.withAlpha(32),
)
],
),
)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Lead Response", fontWeight: 600),
MySpacing.height(24),
leadData(Images.avatars[0], "Amelia Thomson", "1.3", .3),
MySpacing.height(24),
leadData(Images.avatars[1], "Ian Ferguson", "1.4", .4),
MySpacing.height(24),
leadData(Images.avatars[2], "Simon Ross", "2", .8),
MySpacing.height(24),
leadData(Images.avatars[3], "Heather", "1.5", .5),
MySpacing.height(24),
leadData(Images.avatars[4], "Madeleine Simpson", "1.9", .7),
],
),
);
}
Widget openDeals() {
Widget dealsData(String image, dealsType, dealsDate, price) {
return Row(
children: [
MyContainer(
paddingAll: 0,
height: 46,
width: 46,
borderRadiusAll: 8,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(24),
Expanded(
child: SizedBox(
height: 32,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium(dealsType, fontWeight: 600, overflow: TextOverflow.ellipsis),
MyText.labelSmall("Closing deal date ${dealsDate}", fontWeight: 600, overflow: TextOverflow.ellipsis)
],
),
),
),
MyText.labelMedium("\$${numberFormatter(price)}", fontWeight: 600, color: contentTheme.primary),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Open Deals", fontWeight: 600),
MySpacing.height(24),
dealsData(Images.avatars[1], "SASS app workflow", "26 Jan", "15478"),
MySpacing.height(24),
dealsData(Images.avatars[0], "Create new component", "8 Fab", "54791"),
MySpacing.height(24),
dealsData(Images.avatars[3], "New Email Design Template", "16 March", "54876"),
MySpacing.height(24),
dealsData(Images.avatars[4], "React Developer", "12 Fab", "1564"),
],
),
);
}
Widget leadSource() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Lead Source", fontWeight: 600),
SizedBox(
height: 280,
child: SfCircularChart(
series: [
PieSeries<ChartSampleData, String>(
explode: true,
explodeIndex: 0,
dataSource: <ChartSampleData>[
ChartSampleData(x: 'Prospecting', y: 13, text: 'Prospecting \n 13%'),
ChartSampleData(x: 'Negotiation', y: 24, text: 'Negotiation \n 24%'),
ChartSampleData(x: 'Proposal', y: 25, text: 'Proposal \n 25%'),
ChartSampleData(x: 'Qualification', y: 38, text: 'Qualification \n 38%'),
],
xValueMapper: (ChartSampleData data, _) => data.x as String,
yValueMapper: (ChartSampleData data, _) => data.y,
dataLabelMapper: (ChartSampleData data, _) => data.text,
dataLabelSettings: DataLabelSettings(isVisible: true)),
],
),
)
],
),
);
}
Widget leadReport() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Lead Report", fontWeight: 600),
MySpacing.height(24),
if (controller.leadReport.isNotEmpty)
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 80,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Lead', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Company Name', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Phone Number', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Location', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Amount', color: contentTheme.primary)),
],
rows: controller.leadReport
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.bodyMedium("#${data.id}", fontWeight: 600)),
DataCell(Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyContainer(
height: 44,
width: 44,
paddingAll: 0,
child: Image.asset(Images.avatars[index % Images.avatars.length], fit: BoxFit.cover),
),
MySpacing.width(24),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(data.firstName, fontWeight: 600),
MyText.labelMedium(data.email),
],
)
],
)),
DataCell(MyText.bodyMedium(data.companyName, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.phoneNumber, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.status, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.location, fontWeight: 600)),
DataCell(MyText.bodyMedium("${Utils.getDateStringFromDateTime(data.date)}", fontWeight: 600)),
DataCell(MyText.bodyMedium("\$${data.amount}", fontWeight: 600)),
]))
.toList()),
),
],
));
}
}

View File

@ -1,533 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:marco/controller/dashboard/crypto_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class CryptoScreen extends StatefulWidget {
const CryptoScreen({super.key});
@override
State<CryptoScreen> createState() => _CryptoScreenState();
}
class _CryptoScreenState extends State<CryptoScreen> with UIMixin {
CryptoController controller = Get.put(CryptoController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
builder: (controller) {
return Column(
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Crypto", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Crypto', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats('assets/coin/ethereum.png', 'ETH', 'Ethereum', '3.754120', '4.2')),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats('assets/coin/bitcoin.png', 'BTC', 'Bitcoin', '12.125620', '-1.3')),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats('assets/coin/chainlink.png', 'LINK', 'Chainlink', '15.874562', '0.8')),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats('assets/coin/dogecoin.png', 'DOGE', 'Dogecoin', '8.674930', '5.0')),
MyFlexItem(sizes: 'lg-6 md-6', child: marketOverview()),
MyFlexItem(sizes: 'lg-6 md-6', child: cryptoStatistics()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: accountStats("Total Balance", "\$12000.50", LucideIcons.credit_card, contentTheme.success)),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: accountStats("Total Investment", "\$8000.75", LucideIcons.trending_up, contentTheme.info)),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: accountStats("Total Change", "\$500.25", LucideIcons.refresh_cw, contentTheme.warning)),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: accountStats("Day Change", "\$20.30", LucideIcons.circle_arrow_up, contentTheme.danger)),
MyFlexItem(sizes: 'lg-4', child: recentActivity()),
MyFlexItem(sizes: 'lg-4', child: topPerformers()),
MyFlexItem(sizes: 'lg-4', child: transactionHistory()),
MyFlexItem(child: activeOverallGrowth()),
],
)),
],
);
},
),
);
}
Widget stats(String coinImage, String coinShortName, String coinName, String count, String change) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 170,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
MyContainer.rounded(
height: 44,
width: 44,
paddingAll: 0,
child: Image.asset(coinImage, fit: BoxFit.cover),
),
MySpacing.width(20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodySmall(coinShortName, xMuted: true),
MyText.bodySmall(coinName),
],
)
],
),
MyText.titleLarge('$count $coinShortName'),
Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(change.startsWith("-") ? LucideIcons.trending_down : LucideIcons.trending_up,
size: 16, color: change.startsWith("-") ? theme.colorScheme.error : theme.colorScheme.primary),
MySpacing.width(8),
MyText.bodySmall("${change.startsWith("-") ? '' : '+'}${change}%",
color: change.startsWith("-") ? theme.colorScheme.error : theme.colorScheme.primary),
],
),
],
),
);
}
Widget marketOverview() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium("Market Overview", fontWeight: 600),
PopupMenuButton(
onSelected: controller.onSelectIntervalType,
itemBuilder: (BuildContext context) {
return DateTimeIntervalType.values.map((behavior) {
return PopupMenuItem(
value: behavior,
height: 32,
child: MyText.bodySmall(
behavior.toString().split('.').last.capitalize.toString(),
color: theme.colorScheme.onSurface,
fontWeight: 600,
),
);
}).toList();
},
color: theme.cardTheme.color,
child: MyContainer.bordered(
padding: MySpacing.xy(8, 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
MyText.labelSmall(controller.intervalType.toString().split('.').last.capitalize.toString(), color: theme.colorScheme.onSurface),
Icon(LucideIcons.chevron_down, size: 16, color: theme.colorScheme.onSurface)
],
),
),
),
],
),
MySpacing.height(24),
SfCartesianChart(
plotAreaBorderWidth: 0,
primaryXAxis: DateTimeAxis(
autoScrollingMode: AutoScrollingMode.start,
dateFormat: DateFormat.MMM(),
intervalType: controller.intervalType,
minimum: DateTime(2016),
maximum: DateTime(2016, 10),
majorGridLines: const MajorGridLines(width: 0)),
primaryYAxis: const NumericAxis(minimum: 80, maximum: 120, labelFormat: r'${value}', axisLine: AxisLine(width: 0)),
series: _getCandleSeries(),
trackballBehavior: controller.trackballBehavior,
tooltipBehavior: TooltipBehavior(),
zoomPanBehavior: ZoomPanBehavior(enableMouseWheelZooming: true, enablePinching: true, enablePanning: true, enableDoubleTapZooming: true)),
],
),
);
}
List<CandleSeries<ChartSampleData, DateTime>> _getCandleSeries() {
return <CandleSeries<ChartSampleData, DateTime>>[
CandleSeries<ChartSampleData, DateTime>(
enableSolidCandles: controller.enableSolidCandle,
dataSource: <ChartSampleData>[
ChartSampleData(x: DateTime(2016, 01, 11), open: 98.97, high: 101.19, low: 95.36, close: 97.13),
ChartSampleData(x: DateTime(2016, 01, 18), open: 98.41, high: 101.46, low: 93.42, close: 101.42),
ChartSampleData(x: DateTime(2016, 01, 25), open: 101.52, high: 101.53, low: 92.39, close: 97.34),
ChartSampleData(x: DateTime(2016, 02), open: 96.47, high: 97.33, low: 93.69, close: 94.02),
ChartSampleData(x: DateTime(2016, 02, 08), open: 93.13, high: 96.35, low: 92.59, close: 93.99),
ChartSampleData(x: DateTime(2016, 02, 15), open: 95.02, high: 98.89, low: 94.61, close: 96.04),
ChartSampleData(x: DateTime(2016, 02, 22), open: 96.31, high: 98.0237, low: 93.32, close: 96.91),
ChartSampleData(x: DateTime(2016, 02, 29), open: 96.86, high: 103.75, low: 96.65, close: 103.01),
ChartSampleData(x: DateTime(2016, 03, 07), open: 102.39, high: 102.83, low: 100.15, close: 102.26),
ChartSampleData(x: DateTime(2016, 03, 14), open: 106.5, high: 106.5, low: 106.5, close: 106.5),
ChartSampleData(x: DateTime(2016, 03, 21), open: 105.93, high: 107.65, low: 104.89, close: 105.67),
ChartSampleData(x: DateTime(2016, 03, 28), open: 106, high: 110.42, low: 104.88, close: 109.99),
ChartSampleData(x: DateTime(2016, 04, 04), open: 110.42, high: 112.19, low: 108.121, close: 108.66),
ChartSampleData(x: DateTime(2016, 04, 11), open: 108.97, high: 112.39, low: 108.66, close: 109.85),
ChartSampleData(x: DateTime(2016, 04, 18), open: 108.89, high: 108.95, low: 104.62, close: 105.68),
ChartSampleData(x: DateTime(2016, 04, 25), open: 105, high: 105.65, low: 92.51, close: 93.74),
ChartSampleData(x: DateTime(2016, 05, 02), open: 93.965, high: 95.9, low: 91.85, close: 92.72),
ChartSampleData(x: DateTime(2016, 05, 09), open: 93, high: 93.77, low: 89.47, close: 90.52),
ChartSampleData(x: DateTime(2016, 05, 16), open: 92.39, high: 95.43, low: 91.65, close: 95.22),
ChartSampleData(x: DateTime(2016, 05, 23), open: 95.87, high: 100.73, low: 95.67, close: 100.35),
ChartSampleData(x: DateTime(2016, 05, 30), open: 99.6, high: 100.4, low: 96.63, close: 97.92),
ChartSampleData(x: DateTime(2016, 06, 06), open: 97.99, high: 101.89, low: 97.55, close: 98.83),
ChartSampleData(x: DateTime(2016, 06, 13), open: 98.69, high: 99.12, low: 95.3, close: 95.33),
ChartSampleData(x: DateTime(2016, 06, 20), open: 96, high: 96.89, low: 92.65, close: 93.4),
ChartSampleData(x: DateTime(2016, 06, 27), open: 93, high: 96.465, low: 91.5, close: 95.89),
ChartSampleData(x: DateTime(2016, 07, 04), open: 95.39, high: 96.89, low: 94.37, close: 96.68),
ChartSampleData(x: DateTime(2016, 07, 11), open: 96.75, high: 99.3, low: 96.73, close: 98.78),
ChartSampleData(x: DateTime(2016, 07, 18), open: 98.7, high: 101, low: 98.31, close: 98.66),
ChartSampleData(x: DateTime(2016, 07, 25), open: 98.25, high: 104.55, low: 96.42, close: 104.21),
ChartSampleData(x: DateTime(2016, 08), open: 104.41, high: 107.65, low: 104, close: 107.48),
ChartSampleData(x: DateTime(2016, 08, 08), open: 107.52, high: 108.94, low: 107.16, close: 108.18),
ChartSampleData(x: DateTime(2016, 08, 15), open: 108.14, high: 110.23, low: 108.08, close: 109.36),
ChartSampleData(x: DateTime(2016, 08, 22), open: 108.86, high: 109.32, low: 106.31, close: 106.94),
ChartSampleData(x: DateTime(2016, 08, 29), open: 109.74, high: 109.74, low: 109.74, close: 109.74),
ChartSampleData(x: DateTime(2016, 09, 05), open: 107.9, high: 108.76, low: 103.13, close: 103.13),
ChartSampleData(x: DateTime(2016, 09, 12), open: 102.65, high: 116.13, low: 102.53, close: 114.92),
ChartSampleData(x: DateTime(2016, 09, 19), open: 115.19, high: 116.18, low: 111.55, close: 112.71),
ChartSampleData(x: DateTime(2016, 09, 26), open: 111.64, high: 114.64, low: 111.55, close: 113.05),
],
showIndicationForSameValues: true,
xValueMapper: (ChartSampleData sales, _) => sales.x as DateTime,
lowValueMapper: (ChartSampleData sales, _) => sales.low,
highValueMapper: (ChartSampleData sales, _) => sales.high,
openValueMapper: (ChartSampleData sales, _) => sales.open,
closeValueMapper: (ChartSampleData sales, _) => sales.close,
spacing: 0.2,
width: 0.8,
borderRadius: BorderRadius.all(Radius.circular(4)),
)
];
}
Widget cryptoStatistics() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Crypto Statistics", fontWeight: 600),
MySpacing.height(24),
SizedBox(
height: 329,
child: SfCartesianChart(
margin: MySpacing.zero,
plotAreaBorderWidth: 0,
legend: Legend(isVisible: false, position: LegendPosition.bottom),
primaryXAxis: const CategoryAxis(majorGridLines: MajorGridLines(width: 0), labelPlacement: LabelPlacement.onTicks),
primaryYAxis: const NumericAxis(
axisLine: AxisLine(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift, labelFormat: '{value}', majorTickLines: MajorTickLines(size: 0)),
series: [
SplineSeries<ChartSampleData, String>(
dataSource: controller.chartData,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.y,
markerSettings: const MarkerSettings(isVisible: true),
color: contentTheme.success,
name: 'High'),
SplineSeries<ChartSampleData, String>(
dataSource: controller.chartData,
name: 'Low',
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue,
)
],
tooltipBehavior: TooltipBehavior(enable: true),
),
)
],
),
);
}
Widget accountStats(String title, String data, IconData icon, Color color) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
MyContainer(
color: color,
child: Icon(icon, color: contentTheme.light),
),
MySpacing.width(20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title, fontWeight: 600, maxLines: 1, overflow: TextOverflow.ellipsis),
MySpacing.height(4),
MyText.titleLarge(data, fontWeight: 600, maxLines: 1, overflow: TextOverflow.ellipsis),
],
),
)
],
)
],
),
);
}
Widget recentActivity() {
Widget recentActivityWidget(String coinName, String transactionType, String price, String transactionUpDown, IconData icon) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyContainer.roundBordered(
height: 44,
width: 44,
paddingAll: 0,
child: Icon(icon, size: 20),
),
MySpacing.width(20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(coinName, fontWeight: 600),
MySpacing.height(4),
MyText.bodySmall(transactionType, fontWeight: 600, muted: true),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
MyText.bodyMedium(price, fontWeight: 600),
MySpacing.height(4),
MyText.bodySmall("${transactionUpDown.startsWith('-') ? '' : '+'}${transactionUpDown}",
fontWeight: 600, muted: true, color: transactionUpDown.startsWith('-') ? contentTheme.danger : contentTheme.success),
],
),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Recent Activity", fontWeight: 600),
MySpacing.height(24),
recentActivityWidget("Bought Ethereum", "MasterCard ***8", "+0.215 BTC", "4320.22 USD", LucideIcons.circle_plus),
MySpacing.height(24),
recentActivityWidget("Sold Bitcoin", "PayPal Account", "-0.012 BTC", "-231.56 USD", LucideIcons.circle_minus),
MySpacing.height(24),
recentActivityWidget("Transferred Litecoin", "Visa Debit Card ***5", "-2.23 LTC", "-150.99 USD", LucideIcons.arrow_right),
MySpacing.height(24),
recentActivityWidget("Bought Cardano", "Bitcoin Wallet", "+500 ADA", "2,650.32 USD", LucideIcons.circle_plus),
MySpacing.height(24),
recentActivityWidget("Sold Dogecoin", "Bank Transfer", "-10,000 DOGE", "-756.11 USD", LucideIcons.circle_minus),
],
),
);
}
Widget topPerformers() {
Widget topPerformersWidget(String coinName, String shortName, String price, String image) {
return Row(
children: [
MyContainer(
height: 44,
width: 44,
paddingAll: 0,
child: Image.asset(image),
),
MySpacing.width(24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(coinName, fontWeight: 600),
MySpacing.height(4),
MyText.bodySmall(shortName, fontWeight: 600, muted: true),
],
),
),
MyText.bodyMedium(price, fontWeight: 600),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Top Performance", fontWeight: 600),
MySpacing.height(24),
topPerformersWidget("Bitcoin", "BTC", "\$45,000", "assets/coin/bitcoin.png"),
MySpacing.height(24),
topPerformersWidget("Chainlink", "LINK", "\$25.50", "assets/coin/chainlink.png"),
MySpacing.height(24),
topPerformersWidget("Dogecoin", "DOGE", "\$0.25", "assets/coin/dogecoin.png"),
MySpacing.height(24),
topPerformersWidget("Ethereum", "ETH", "\$3,200", "assets/coin/ethereum.png"),
MySpacing.height(24),
topPerformersWidget("Polkadot", "DOT", "\$12.75", "assets/coin/polkadot.png"),
],
),
);
}
Widget transactionHistory() {
Widget transactionHistoryWidget(String coinName, String date, String buyPrice, IconData icon) {
return Row(
children: [
MyContainer(
height: 44,
width: 44,
paddingAll: 0,
color: contentTheme.primary.withValues(alpha: 0.2),
child: Icon(icon, color: contentTheme.primary),
),
MySpacing.width(24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(coinName, fontWeight: 600),
MySpacing.height(4),
MyText.bodySmall(date, fontWeight: 600, muted: true),
],
),
),
MyText.bodyMedium(buyPrice, fontWeight: 600),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Transaction History", fontWeight: 600),
MySpacing.height(24),
transactionHistoryWidget("Sent BTC", "12 November 2024 2:15 PM", "0.045 BTC", LucideIcons.arrow_up),
MySpacing.height(24),
transactionHistoryWidget("Received ETH", "11 November 2024 9:30 AM", "2.5 ETH", LucideIcons.arrow_down),
MySpacing.height(24),
transactionHistoryWidget("Sent LTC", "10 November 2024 5:20 PM", "1.2 LTC", LucideIcons.arrow_up),
MySpacing.height(24),
transactionHistoryWidget("Received ADA", "9 November 2024 11:50 PM", "500 ADA", LucideIcons.arrow_down),
MySpacing.height(24),
transactionHistoryWidget("Sent DOGE", "8 November 2024 1:10 PM", "10,000 DOGE", LucideIcons.arrow_up),
],
),
);
}
Widget activeOverallGrowth() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha: .2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Active Overall Growth", fontWeight: 600),
MySpacing.height(24),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 170,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('Type', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Assets', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('IP Address', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Amount', color: contentTheme.primary)),
],
rows: controller.coinGrowth
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.labelMedium('Exchange')),
DataCell(MyText.labelMedium('${data.asset}')),
DataCell(MyText.labelMedium('${Utils.getDateTimeStringFromDateTime(data.date)}')),
DataCell(MyText.labelMedium('${data.ipAddress}')),
DataCell(MyContainer(
paddingAll: 4,
color: data.status == 'Success' ? contentTheme.success : contentTheme.danger,
child: MyText.labelMedium('${data.status}', color: data.status == 'Success' ? contentTheme.onSuccess : contentTheme.onDanger))),
DataCell(MyText.labelMedium('\$${data.amount}')),
]))
.toList()),
),
],
),
);
}
}

View File

@ -1,437 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:marco/controller/permission_controller.dart';
import 'package:marco/helpers/widgets/my_loading_component.dart';
import 'package:marco/helpers/widgets/my_refresh_wrapper.dart';
import 'package:marco/model/my_paginated_table.dart';
import 'package:marco/controller/dashboard/daily_task_controller.dart';
import 'package:marco/helpers/widgets/avatar.dart';
import 'package:intl/intl.dart';
import 'package:marco/helpers/widgets/my_team_model_sheet.dart';
class DailyTaskScreen extends StatefulWidget {
const DailyTaskScreen({super.key});
@override
State<DailyTaskScreen> createState() => _DailyTaskScreenState();
}
class _DailyTaskScreenState extends State<DailyTaskScreen> with UIMixin {
final DailyTaskController dailyTaskController =
Get.put(DailyTaskController());
final PermissionController permissionController =
Get.put(PermissionController());
@override
Widget build(BuildContext context) {
return Layout(
child: Obx(() {
return LoadingComponent(
isLoading: dailyTaskController.isLoading.value,
loadingText: 'Loading Tasks...',
child: GetBuilder<DailyTaskController>(
init: dailyTaskController,
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(),
MySpacing.height(flexSpacing),
_buildBreadcrumb(),
MySpacing.height(flexSpacing),
_buildFilterSection(),
MySpacing.height(flexSpacing),
_buildTaskList(),
],
);
},
),
);
}),
);
}
Widget _buildHeader() {
return Padding(
padding: MySpacing.x(flexSpacing),
child: MyText.titleMedium(
"Daily Progress Report",
fontSize: 18,
fontWeight: 600,
),
);
}
Widget _buildBreadcrumb() {
return Padding(
padding: MySpacing.x(flexSpacing),
child: MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Daily Progress Report', active: true),
],
),
);
}
Widget _buildFilterSection() {
return Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildProjectFilter(),
const SizedBox(width: 10),
_buildDateRangeButton(),
],
),
);
}
Widget _buildProjectFilter() {
return Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 1.5),
borderRadius: BorderRadius.circular(4),
),
child: PopupMenuButton<String>(
onSelected: (String value) async {
if (value.isNotEmpty) {
dailyTaskController.selectedProjectId = value;
await dailyTaskController.fetchTaskData(value);
}
dailyTaskController.update();
},
itemBuilder: (BuildContext context) {
return dailyTaskController.projects
.map<PopupMenuItem<String>>((project) {
return PopupMenuItem<String>(
value: project.id,
child: MyText.bodySmall(project.name),
);
}).toList();
},
offset: const Offset(0, 40),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
dailyTaskController.selectedProjectId == null
? dailyTaskController.projects.isNotEmpty
? dailyTaskController.projects.first.name
: 'No Tasks'
: dailyTaskController.projects
.firstWhere((project) =>
project.id ==
dailyTaskController.selectedProjectId)
.name,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontWeight: FontWeight.w600),
),
),
const Icon(Icons.arrow_drop_down),
],
),
),
),
),
);
}
Widget _buildDateRangeButton() {
String dateRangeText;
if (dailyTaskController.startDateTask != null &&
dailyTaskController.endDateTask != null) {
dateRangeText =
'${DateFormat('dd-MM-yyyy').format(dailyTaskController.startDateTask!)}'
' to '
'${DateFormat('dd-MM-yyyy').format(dailyTaskController.endDateTask!)}';
} else {
dateRangeText = "Select Date Range";
}
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton.icon(
icon: const Icon(Icons.date_range),
label: Text(dateRangeText),
onPressed: () => dailyTaskController.selectDateRangeForTaskData(
context,
dailyTaskController,
),
),
);
}
Widget _buildTaskList() {
return Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: 'lg-6', child: employeeListTab()),
],
),
);
}
Widget employeeListTab() {
if (dailyTaskController.dailyTasks.isEmpty) {
return Center(
child: MyText.bodySmall("No Tasks Assigned to This Project",
fontWeight: 600),
);
}
Map<String, List<dynamic>> groupedTasks = {};
for (var task in dailyTaskController.dailyTasks) {
String dateKey =
DateFormat('dd-MM-yyyy').format(task.assignmentDate);
groupedTasks.putIfAbsent(dateKey, () => []).add(task);
}
// Sort dates descending (latest first)
final sortedEntries = groupedTasks.entries.toList()
..sort((a, b) => DateFormat('dd-MM-yyyy')
.parse(b.key)
.compareTo(DateFormat('dd-MM-yyyy').parse(a.key)));
// Flatten grouped data into one list with optional visual separators
List<DataRow> allRows = [];
for (var entry in sortedEntries) {
allRows.add(
DataRow(
color: WidgetStateProperty.all(Colors.grey.shade200),
cells: [
DataCell(MyText.titleSmall('Date: ${entry.key}')),
DataCell(MyText.titleSmall('')),
DataCell(MyText.titleSmall('')),
DataCell(MyText.titleSmall('')),
DataCell(MyText.titleSmall('')),
DataCell(MyText.titleSmall('')),
],
),
);
allRows.addAll(entry.value.map((task) => _buildRow(task)));
}
return MyRefreshableContent(
onRefresh: () async {
if (dailyTaskController.selectedProjectId != null) {
await dailyTaskController
.fetchTaskData(dailyTaskController.selectedProjectId!);
}
},
child: MyPaginatedTable(
columns: _buildColumns(),
rows: allRows,
),
);
}
List<DataColumn> _buildColumns() {
return [
DataColumn(
label: MyText.labelLarge('Activity', color: contentTheme.primary)),
DataColumn(
label: MyText.labelLarge('Assigned', color: contentTheme.primary)),
DataColumn(
label: MyText.labelLarge('Completed', color: contentTheme.primary)),
DataColumn(
label: MyText.labelLarge('Assigned On', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Team', color: contentTheme.primary)),
DataColumn(
label: MyText.labelLarge('Actions', color: contentTheme.primary)),
];
}
DataRow _buildRow(dynamic task) {
final workItem = task.workItem;
final location = [
workItem?.workArea?.floor?.building?.name,
workItem?.workArea?.floor?.floorName,
workItem?.workArea?.areaName
].where((e) => e != null && e.isNotEmpty).join(' > ');
return DataRow(cells: [
DataCell(
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyText.bodyMedium(workItem?.activityMaster?.activityName ?? 'N/A',
fontWeight: 600),
SizedBox(height: 2),
MyText.bodySmall(location, color: Colors.grey),
],
),
),
DataCell(
MyText.bodyMedium(
'${task.plannedTask ?? "NA"} / '
'${(workItem?.plannedWork != null && workItem?.completedWork != null) ? (workItem!.plannedWork! - workItem.completedWork!) : "NA"}',
),
),
DataCell(MyText.bodyMedium(task.completedTask.toString())),
DataCell(MyText.bodyMedium(DateFormat('dd-MM-yyyy')
.format(DateTime.parse(task.assignmentDate)))),
DataCell(_buildTeamCell(task)),
DataCell(Row(
children: [
ElevatedButton(
onPressed: () {
final activityName =
task.workItem?.activityMaster?.activityName ?? 'N/A';
final assigned = '${task.plannedTask ?? "NA"} / '
'${(task.workItem?.plannedWork != null && task.workItem?.completedWork != null) ? (task.workItem!.plannedWork! - task.workItem.completedWork!) : "NA"}';
final assignedBy =
"${task.assignedBy.firstName} ${task.assignedBy.lastName ?? ''}";
final completed = task.completedTask.toString();
final assignedOn = DateFormat('dd-MM-yyyy')
.format(DateTime.parse(task.assignmentDate));
final taskId = task.id;
final location = [
task.workItem?.workArea?.floor?.building?.name,
task.workItem?.workArea?.floor?.floorName,
task.workItem?.workArea?.areaName
].where((e) => e != null && e.isNotEmpty).join(' > ');
final teamMembers =
task.teamMembers.map((member) => member.firstName).toList();
// Navigate with detailed values
Get.toNamed(
'/daily-task/report-task',
arguments: {
'activity': activityName,
'assigned': assigned,
'taskId': taskId,
'assignedBy': assignedBy,
'completed': completed,
'assignedOn': assignedOn,
'location': location,
'teamSize': task.teamMembers.length,
'teamMembers': teamMembers,
},
);
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
minimumSize: const Size(60, 20),
textStyle: const TextStyle(fontSize: 12),
),
child: const Text("Report"),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: () {
final activityName =
task.workItem?.activityMaster?.activityName ?? 'N/A';
final assigned = '${task.plannedTask ?? "NA"} / '
'${(task.workItem?.plannedWork != null && task.workItem?.completedWork != null) ? (task.workItem!.plannedWork! - task.workItem.completedWork!) : "NA"}';
final plannedWork = '${(task.plannedTask.toString())}';
final assignedBy =
"${task.assignedBy.firstName} ${task.assignedBy.lastName ?? ''}";
final completedWork = '${(task.completedTask.toString())}';
final assignedOn = DateFormat('dd-MM-yyyy')
.format(DateTime.parse(task.assignmentDate));
final taskId = task.id;
final location = [
task.workItem?.workArea?.floor?.building?.name,
task.workItem?.workArea?.floor?.floorName,
task.workItem?.workArea?.areaName
].where((e) => e != null && e.isNotEmpty).join(' > ');
final teamMembers =
task.teamMembers.map((member) => member.firstName).toList();
final taskComments = task.comments
.map((comment) => comment.comment ?? 'No Content')
.toList();
Get.toNamed(
'/daily-task/comment-task',
arguments: {
'activity': activityName,
'assigned': assigned,
'taskId': taskId,
'assignedBy': assignedBy,
'completedWork': completedWork,
'plannedWork': plannedWork,
'assignedOn': assignedOn,
'location': location,
'teamSize': task.teamMembers.length,
'teamMembers': teamMembers,
'taskComments': taskComments
},
);
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
minimumSize: const Size(60, 20),
textStyle: const TextStyle(fontSize: 12),
),
child: const Text("Comment"),
),
],
)),
]);
}
Widget _buildTeamCell(dynamic task) {
return GestureDetector(
onTap: () => TeamBottomSheet.show(
context: context,
teamMembers: task.teamMembers,
),
child: SizedBox(
height: 32,
width: 100,
child: Stack(
children: [
for (int i = 0; i < task.teamMembers.length.clamp(0, 3); i++)
_buildAvatar(task.teamMembers[i], i * 24.0),
if (task.teamMembers.length > 3)
_buildExtraMembersIndicator(task.teamMembers.length - 3, 48.0),
],
),
),
);
}
Widget _buildAvatar(dynamic member, double leftPosition) {
return Positioned(
left: leftPosition,
child: Tooltip(
message: member.firstName,
child: Avatar(firstName: member.firstName, lastName: '', size: 32),
),
);
}
Widget _buildExtraMembersIndicator(int extraMembers, double leftPosition) {
return Positioned(
left: leftPosition,
child: CircleAvatar(
radius: 16,
backgroundColor: Colors.grey.shade300,
child: MyText.bodyMedium('+$extraMembers',
style: const TextStyle(fontSize: 12, color: Colors.black87)),
),
);
}
}

View File

@ -1,528 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:marco/controller/dashboard/ecommerce_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class EcommerceScreen extends StatefulWidget {
const EcommerceScreen({super.key});
@override
State<EcommerceScreen> createState() => _EcommerceScreenState();
}
class _EcommerceScreenState extends State<EcommerceScreen> with UIMixin {
EcommerceController controller = Get.put(EcommerceController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
tag: 'ecommerce_dashboard_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Ecommerce", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Ecommerce', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: 'lg-6 ', child: stats()),
MyFlexItem(sizes: "lg-6", child: responseTimeByLocation()),
MyFlexItem(sizes: 'lg-3 md-6', child: topCustomer()),
MyFlexItem(sizes: "lg-4 md-6", child: costBreakDown()),
MyFlexItem(sizes: 'lg-5', child: salesAnalytics()),
MyFlexItem(child: productOrder()),
],
),
),
],
);
},
),
);
}
Widget stats() {
Widget statsWidget(IconData icon, String title, String count, String change, Color color) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 140,
child: Row(
children: [
MyContainer(
paddingAll: 24,
color: color.withValues(alpha:0.2),
child: MyContainer(paddingAll: 8, color: color, child: Icon(icon, size: 16, color: contentTheme.light)),
),
MySpacing.width(24),
Expanded(
child: SizedBox(
height: 80,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelSmall(title, maxLines: 1),
MyText.bodyMedium(count, fontWeight: 600, maxLines: 1),
Row(
children: [
MyContainer(
padding: MySpacing.xy(6, 4),
color: change[0] == '+' ? Colors.green.withValues(alpha:.2) : theme.colorScheme.error.withValues(alpha:.2),
child: MyText.labelSmall(change, color: change[0] == '+' ? Colors.green : theme.colorScheme.error),
),
MySpacing.width(8),
Expanded(child: MyText.labelSmall("This Month", overflow: TextOverflow.ellipsis))
],
)
],
),
),
)
],
),
);
}
return MyFlex(contentPadding: false, children: [
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.shopping_bag, "Total Sales", "12,254", "+4.2%", contentTheme.primary)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.receipt_text, "Total Expenses", "\$28,346.00", "-4.2%", contentTheme.secondary)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.user, "Total Visitors", "1,29,368", "-3.54%", contentTheme.success)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.shopping_basket, "Total Orders", "35,367", "+5.18%", contentTheme.info)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.chart_column, "Average Order Value", "\$120", "+4.48%", contentTheme.dark)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget(LucideIcons.users, "Total Customer", "36,835", "-1.15%", contentTheme.warning)),
]);
}
Widget salesAnalytics() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Sales Analytics", fontWeight: 600),
MySpacing.height(24),
SizedBox(height: 384, child: salesAnalyticsChart()),
],
),
);
}
SfCartesianChart salesAnalyticsChart() {
return SfCartesianChart(
plotAreaBorderWidth: 0,
margin: MySpacing.zero,
primaryXAxis: const CategoryAxis(majorGridLines: MajorGridLines(width: 0), labelPlacement: LabelPlacement.onTicks),
primaryYAxis: const NumericAxis(
minimum: 30,
maximum: 80,
axisLine: AxisLine(width: 0),
edgeLabelPlacement: EdgeLabelPlacement.shift,
labelFormat: '{value}',
majorTickLines: MajorTickLines(size: 0)),
series: [
SplineSeries<ChartSampleData, String>(
dataSource: controller.salesAnalyticsData,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.y,
markerSettings: const MarkerSettings(isVisible: true),
name: 'Pending',
),
SplineSeries<ChartSampleData, String>(
dataSource: controller.salesAnalyticsData,
name: 'Complete',
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue,
)
],
tooltipBehavior: TooltipBehavior(enable: true),
);
}
Widget topCustomer() {
Widget topCustomerData(String name, String cardNumber, int orders, String image) {
return Row(
children: [
MyContainer(
height: 44,
width: 44,
paddingAll: 0,
borderRadiusAll: 4,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image),
),
MySpacing.width(20),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(name, fontWeight: 600, maxLines: 1),
MyText.labelSmall(cardNumber, maxLines: 1),
],
),
),
MyText.labelSmall("Orders : $orders"),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Top Customer", fontWeight: 600),
MySpacing.height(24),
topCustomerData("John Doe", "1234 5678 9012 3456", 21, Images.avatars[0]),
MySpacing.height(24),
topCustomerData("Jane Smith", "2345 6789 0123 4567", 22, Images.avatars[1]),
MySpacing.height(24),
topCustomerData("Michael Johnson", "3456 7890 1234 5678", 23, Images.avatars[2]),
MySpacing.height(24),
topCustomerData("Emily Davis", "4567 8901 2345 6789", 24, Images.avatars[3]),
MySpacing.height(24),
topCustomerData("Chris Brown", "5678 9012 3456 7890", 25, Images.avatars[4]),
MySpacing.height(24),
topCustomerData("Olivia Wilson", "6789 0123 4567 8901", 26, Images.avatars[5]),
],
));
}
Widget costBreakDown() {
Widget buildCircleChartData(Color color, String name, String price) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
MyContainer.rounded(
paddingAll: 4,
color: color,
),
MySpacing.width(8),
MyText.labelMedium(name)
],
),
MyText.labelSmall(price),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium("Cost BreakDown", overflow: TextOverflow.ellipsis, fontWeight: 600),
InkWell(onTap: () {}, child: Icon(LucideIcons.move_right, size: 16)),
],
),
SizedBox(
height: 293,
child: SfCircularChart(
margin: MySpacing.zero,
tooltipBehavior: TooltipBehavior(enable: true),
series: <CircularSeries>[
DoughnutSeries<ChartSampleData, String>(
radius: '80%',
explode: true,
explodeOffset: '10%',
dataSource: controller.circleChart,
pointColorMapper: (ChartSampleData data, _) => data.pointColor,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.y,
dataLabelSettings: const DataLabelSettings(isVisible: true)),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [MyText.titleMedium("Top Channel"), MyText.titleMedium("Value")],
),
MySpacing.height(12),
buildCircleChartData(const Color.fromRGBO(9, 0, 136, 1), "Salary", "\$54,847"),
MySpacing.height(8),
buildCircleChartData(const Color.fromRGBO(147, 0, 119, 1), "Bill", "\$58,188"),
MySpacing.height(8),
buildCircleChartData(const Color.fromRGBO(228, 0, 124, 1), "Marketing", "\$24,618"),
MySpacing.height(8),
buildCircleChartData(const Color.fromRGBO(255, 189, 57, 1), "Other", "\$15,651")
],
),
);
}
Widget responseTimeByLocation() {
Widget buildResponseTimeByLocationData(String currentTime, String price, IconData icon, Color iconColor) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(LucideIcons.circle_dot_dashed, size: 16),
MySpacing.width(8),
MyText.bodyMedium(currentTime),
],
),
MySpacing.height(12),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyText.bodyLarge(price, fontSize: 20, fontWeight: 600, muted: true),
MySpacing.width(8),
Icon(icon, size: 16, color: iconColor),
],
),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 0,
child: Column(
children: [
Padding(
padding: MySpacing.all(16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: MyText.titleMedium(
"Response time by location",
overflow: TextOverflow.ellipsis,
fontWeight: 600,
),
),
PopupMenuButton(
onSelected: controller.onSelectedTimeByLocation,
itemBuilder: (BuildContext context) {
return ["Year", "Month", "Week", "Day", "Hours"].map((behavior) {
return PopupMenuItem(
value: behavior,
height: 32,
child: MyText.bodySmall(
behavior.toString(),
color: theme.colorScheme.onSurface,
fontWeight: 600,
),
);
}).toList();
},
color: theme.cardTheme.color,
child: MyContainer.bordered(
padding: MySpacing.xy(8, 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
MyText.labelSmall(controller.selectedTimeByLocation.toString(), color: theme.colorScheme.onSurface),
Icon(LucideIcons.chevron_down, size: 16, color: theme.colorScheme.onSurface)
],
),
),
),
],
),
),
const Divider(),
MySpacing.height(12),
MyFlex(
wrapCrossAlignment: WrapCrossAlignment.center,
runAlignment: WrapAlignment.center,
wrapAlignment: WrapAlignment.center,
children: [
MyFlexItem(
sizes: "lg-4 md-4 sm-6",
child: buildResponseTimeByLocationData("Current Week", "\$1886.52", LucideIcons.corner_right_up, contentTheme.success),
),
MyFlexItem(
sizes: "lg-4 md-4 sm-6",
child: buildResponseTimeByLocationData("Conversation", "5.68%", LucideIcons.corner_right_up, contentTheme.success),
),
MyFlexItem(
sizes: "lg-4 md-4 sm-6",
child: buildResponseTimeByLocationData("Customers", "59K", LucideIcons.corner_right_up, contentTheme.red),
),
],
),
MySpacing.height(12),
const Divider(),
Padding(
padding: MySpacing.all(16),
child: SizedBox(
height: 267,
child: SfCartesianChart(
primaryXAxis: CategoryAxis(),
tooltipBehavior: controller.chart,
axes: <ChartAxis>[
NumericAxis(
numberFormat: NumberFormat.compact(),
majorGridLines: const MajorGridLines(width: 0),
opposedPosition: true,
name: 'yAxis1',
interval: 1000,
minimum: 0,
maximum: 7000)
],
series: [
ColumnSeries<ChartSampleData, String>(
animationDuration: 2000,
width: 0.5,
borderRadius: const BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4)),
color: contentTheme.primary,
dataSource: controller.chartData,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.y,
name: 'Unit Sold'),
LineSeries<ChartSampleData, String>(
animationDuration: 4500,
animationDelay: 2000,
dataSource: controller.chartData,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.yValue,
yAxisName: 'yAxis1',
markerSettings: const MarkerSettings(isVisible: true),
name: 'Total Transaction')
],
),
),
),
],
),
);
}
Widget productOrder() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.titleMedium("Product Order", fontWeight: 600),
MySpacing.height(20),
if (controller.order.isNotEmpty)
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 98,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('Order Id', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Customer Name', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Location', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Order Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Payments', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Quantity', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Price', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Total Amount', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
],
rows: controller.order
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.bodyMedium("#${data.orderId}", fontWeight: 600)),
DataCell(MyText.bodyMedium(data.customerName, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.location, fontWeight: 600)),
DataCell(MyText.bodyMedium("${Utils.getDateStringFromDateTime(data.orderDate)}", fontWeight: 600)),
DataCell(MyText.bodyMedium(data.payment, fontWeight: 600)),
DataCell(MyText.bodyMedium("${data.quantity}", fontWeight: 600)),
DataCell(MyText.bodyMedium("\$${data.price}", fontWeight: 600)),
DataCell(MyText.bodyMedium("\$${data.quantity * data.price}", fontWeight: 600)),
DataCell(MyContainer(
padding: MySpacing.xy(8, 4),
color: getStatusColor(data.status)?.withAlpha(32),
child: MyText.bodySmall(
data.status,
fontWeight: 600,
color: getStatusColor(data.status),
),
)),
]))
.toList()),
),
],
),
);
}
Color? getStatusColor(String? status) {
switch (status) {
case "Delivered":
return contentTheme.primary;
case "Shopping":
return contentTheme.success;
case "New":
return contentTheme.warning;
case "Pending":
return contentTheme.danger;
default:
return null;
}
}
}

View File

@ -1,436 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/dashboard/job_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class JobScreen extends StatefulWidget {
const JobScreen({super.key});
@override
State<JobScreen> createState() => _JobScreenState();
}
class _JobScreenState extends State<JobScreen> with UIMixin {
JobController controller = Get.put(JobController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
tag: 'job_dashboard_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Job", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Job', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.briefcase, '245', 'EMPLOYEES IN SYSTEM', contentTheme.primary)),
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.file_text, '3201', 'CANDIDATES IN DATA', contentTheme.secondary)),
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.map_pin, '56', 'LOCATIONS SERVED', contentTheme.success)),
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.user_plus, '312', 'RECRUITER NETWORK', contentTheme.info)),
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.credit_card, '689', 'ACTIVE SUBSCRIPTIONS', contentTheme.purple)),
MyFlexItem(sizes: 'xxl-2 xl-4 lg-4 md-4 sm-6', child: stats(LucideIcons.cloud_upload, '82%', 'RESUME UPLOAD RATE', contentTheme.pink)),
MyFlexItem(sizes: 'lg-4', child: workingFormat()),
MyFlexItem(sizes: 'lg-8 md-6', child: listingPerformance()),
MyFlexItem(sizes: 'lg-4 md-6', child: recentCandidate()),
MyFlexItem(sizes: 'lg-4 md-6', child: mostViewedCVs()),
MyFlexItem(sizes: 'lg-4 md-6', child: recentChat()),
MyFlexItem(child: recentApplication()),
],
)),
],
);
},
),
);
}
Widget stats(IconData? icon, String title, String subTitle, Color color) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Row(
children: [
MyContainer(
paddingAll: 12,
color: color,
child: Icon(icon, color: contentTheme.light, size: 16),
),
MySpacing.width(16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.titleMedium(title, fontWeight: 600),
MySpacing.height(4),
MyText.labelSmall(subTitle, xMuted: true, maxLines: 1, overflow: TextOverflow.ellipsis),
],
),
)
],
),
);
}
Widget workingFormat() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 408,
child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [
MyText.bodyMedium("Working Format", height: .8, fontWeight: 600),
SfCircularChart(legend: Legend(isVisible: true, position: LegendPosition.bottom, overflowMode: LegendItemOverflowMode.wrap), series: [
DoughnutSeries<ChartSampleData, String>(
explode: true,
dataSource: <ChartSampleData>[
ChartSampleData(x: 'OnSite', y: 55, text: '55%'),
ChartSampleData(x: 'Remote', y: 31, text: '31%'),
ChartSampleData(x: 'Hybrid', y: 7.7, text: '7.7%'),
],
xValueMapper: (ChartSampleData data, _) => data.x as String,
yValueMapper: (ChartSampleData data, _) => data.y,
dataLabelMapper: (ChartSampleData data, _) => data.text,
dataLabelSettings: DataLabelSettings(isVisible: true))
])
]),
);
}
Widget listingPerformance() {
Widget isSelectTime(String title, int index) {
bool isSelect = controller.isSelectedListingPerformanceTime == index;
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 0, position: MyShadowPosition.bottom),
paddingAll: 4,
color: isSelect ? contentTheme.secondary.withValues(alpha:0.15) : null,
onTap: () => controller.onSelectListingPerformanceTimeToggle(index),
child: MyText.labelSmall(title, fontWeight: 600, color: isSelect ? contentTheme.secondary : null),
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: MyText.bodyMedium("Listing Performance", fontWeight: 600, overflow: TextOverflow.ellipsis),
),
isSelectTime("Day", 0),
MySpacing.width(12),
isSelectTime("Week", 1),
MySpacing.width(12),
isSelectTime("Month", 2),
],
),
MySpacing.height(24),
SizedBox(
height: 310,
child: SfCartesianChart(
margin: MySpacing.zero,
plotAreaBorderWidth: 0,
primaryXAxis: CategoryAxis(majorGridLines: MajorGridLines(width: 0)),
primaryYAxis: NumericAxis(
maximum: 20,
minimum: 0,
interval: 4,
axisLine: AxisLine(width: 0),
majorTickLines: MajorTickLines(size: 0),
),
series: [
ColumnSeries<ChartSampleData, String>(
width: .7,
spacing: .2,
dataSource: controller.chartData,
color: theme.colorScheme.primary,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.y,
name: 'Views'),
ColumnSeries<ChartSampleData, String>(
dataSource: controller.chartData,
width: .7,
spacing: .2,
color: theme.colorScheme.secondary,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue,
name: 'Application')
],
legend: Legend(isVisible: true, position: LegendPosition.bottom),
tooltipBehavior: controller.columnToolTip),
)
],
),
);
}
Widget recentCandidate() {
Widget candidatesData(String image, title, subtitle) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 44,
width: 44,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title, fontWeight: 600),
MyText.bodySmall(subtitle, fontWeight: 600, xMuted: true, maxLines: 1, overflow: TextOverflow.visible)
],
),
)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Recent Candidate", fontWeight: 600),
MySpacing.height(24),
candidatesData(Images.avatars[3], "Sophia Williams", controller.dummyTexts[0]),
MySpacing.height(24),
candidatesData(Images.avatars[4], "Ethan Johnson", controller.dummyTexts[1]),
MySpacing.height(24),
candidatesData(Images.avatars[5], "Olivia Martinez", controller.dummyTexts[2]),
MySpacing.height(24),
candidatesData(Images.avatars[6], "Liam Brown", controller.dummyTexts[3]),
MySpacing.height(24),
candidatesData(Images.avatars[7], "Ava Davis", controller.dummyTexts[4]),
MySpacing.height(24),
candidatesData(Images.avatars[8], "Mason Lee", controller.dummyTexts[5]),
],
));
}
Widget mostViewedCVs() {
Widget cv(String title) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 44,
width: 44,
clipBehavior: Clip.antiAliasWithSaveLayer,
color: contentTheme.primary.withAlpha(40),
child: Icon(LucideIcons.file_text, color: contentTheme.primary),
),
MySpacing.width(12),
Expanded(child: MyText.bodyMedium(title, fontWeight: 600, overflow: TextOverflow.ellipsis)),
InkWell(onTap: () {}, child: Icon(LucideIcons.download))
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Most Viewed CV's", fontWeight: 600),
MySpacing.height(24),
cv("Isabella Green"),
MySpacing.height(24),
cv("James Turner"),
MySpacing.height(24),
cv("Charlotte Scott"),
MySpacing.height(24),
cv("Oliver King"),
MySpacing.height(24),
cv("Lucas Carter"),
MySpacing.height(24),
cv("Mia Brooks"),
],
),
);
}
Widget recentChat() {
Widget chat(String image, name, message) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 44,
width: 44,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(name, fontWeight: 600),
MyText.labelSmall(message, fontWeight: 600, maxLines: 1, muted: true, overflow: TextOverflow.ellipsis),
],
)),
MySpacing.width(28),
Icon(LucideIcons.message_square, size: 20)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
MyText.bodyMedium("Recent Chat", fontWeight: 600),
MySpacing.height(24),
chat(Images.avatars[0], "Sophia", controller.dummyTexts[6]),
MySpacing.height(24),
chat(Images.avatars[1], "Liam", controller.dummyTexts[5]),
MySpacing.height(24),
chat(Images.avatars[2], "Charlotte", controller.dummyTexts[4]),
MySpacing.height(24),
chat(Images.avatars[3], "Oliver", controller.dummyTexts[3]),
MySpacing.height(24),
chat(Images.avatars[4], "Amelia", controller.dummyTexts[2]),
MySpacing.height(24),
chat(Images.avatars[5], "James", controller.dummyTexts[1])
]));
}
Widget recentApplication() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Recent Application", fontWeight: 600),
MySpacing.height(24),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 88,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Candidate', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Category', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Designation', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Mail', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Location', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Type', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Action', color: contentTheme.primary)),
],
rows: controller.recentApplication
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.bodyMedium("#${data.id}", fontWeight: 600)),
DataCell(Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyContainer(
height: 40,
width: 40,
paddingAll: 0,
child: Image.asset(Images.avatars[index % Images.avatars.length], fit: BoxFit.cover),
),
MySpacing.width(24),
MyText.labelMedium(data.candidate, fontWeight: 600)
],
)),
DataCell(MyText.labelMedium(data.category, fontWeight: 600)),
DataCell(MyText.labelMedium(data.designation, fontWeight: 600)),
DataCell(MyText.labelMedium(data.mail, fontWeight: 600)),
DataCell(MyText.labelMedium(data.location, fontWeight: 600)),
DataCell(MyText.labelMedium("${Utils.getDateStringFromDateTime(data.date)}", fontWeight: 600)),
DataCell(MyText.labelMedium(data.type, fontWeight: 600)),
DataCell(Row(
children: [
MyContainer(
onTap: () {},
color: contentTheme.primary,
paddingAll: 8,
child: Icon(LucideIcons.download, size: 16, color: contentTheme.onPrimary),
),
MySpacing.width(12),
MyContainer(
onTap: () {},
color: contentTheme.secondary,
paddingAll: 8,
child: Icon(LucideIcons.pencil, size: 16, color: contentTheme.onPrimary),
),
],
))
]))
.toList()),
)
],
),
);
}
}

View File

@ -1,435 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/dashboard/project_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/model/task_list_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class ProjectScreen extends StatefulWidget {
const ProjectScreen({super.key});
@override
State<ProjectScreen> createState() => _ProjectScreenState();
}
class _ProjectScreenState extends State<ProjectScreen> with UIMixin {
ProjectController controller = Get.put(ProjectController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Project", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Project', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(children: [
MyFlexItem(sizes: 'lg-6', child: stats()),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: taskPerformance()),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: incomeAnalytics()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: taskList()),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: recentTransaction()),
MyFlexItem(sizes: 'lg-3 md-6', child: taskSummary()),
MyFlexItem(sizes: 'lg-9 md-6', child: projectSummary()),
]),
),
],
);
},
),
);
}
Widget stats() {
Widget statsWidget(String title, String subTitle, IconData icon, Color color) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Row(
children: [
Expanded(
child: SizedBox(
height: 40,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.bodyMedium(title, maxLines: 1),
MyText.titleMedium(subTitle, fontWeight: 600),
],
),
),
),
MyContainer(
color: color,
child: Icon(icon, color: contentTheme.light),
)
],
));
}
return MyFlex(
contentPadding: false,
children: [
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Projects Completed", "120", LucideIcons.briefcase, contentTheme.primary)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Tasks In Progress", "75", LucideIcons.circle_check, contentTheme.secondary)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Total Hours Worked", "540", LucideIcons.clock, contentTheme.info)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Current Budgets", "\$12,500", LucideIcons.dollar_sign, contentTheme.success)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Completed Tasks", "58", LucideIcons.check, contentTheme.warning)),
MyFlexItem(sizes: 'lg-6 md-6 sm-6', child: statsWidget("Team Members", "15", LucideIcons.user, contentTheme.danger)),
],
);
}
Widget taskPerformance() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Task Performance", fontWeight: 600),
SizedBox(
height: 299,
child: Theme(
data: ThemeData(),
child: SfCircularChart(
margin: MySpacing.zero,
series: [
RadialBarSeries<ChartSampleData, String>(
dataLabelSettings: const DataLabelSettings(isVisible: true, textStyle: TextStyle(fontSize: 10.0)),
dataSource: <ChartSampleData>[
ChartSampleData(x: 'Complete', y: 7, text: '100%', pointColor: contentTheme.primary),
ChartSampleData(x: 'Active', y: 5, text: '100%', pointColor: contentTheme.success),
ChartSampleData(x: 'Assigned', y: 8, text: '100%', pointColor: contentTheme.info),
],
trackColor: contentTheme.background,
cornerStyle: CornerStyle.bothCurve,
gap: '10%',
radius: '90%',
xValueMapper: (ChartSampleData data, _) => data.x as String,
yValueMapper: (ChartSampleData data, _) => data.y,
pointRadiusMapper: (ChartSampleData data, _) => data.text,
pointColorMapper: (ChartSampleData data, _) => data.pointColor,
dataLabelMapper: (ChartSampleData data, _) => data.x as String)
],
tooltipBehavior: controller.tooltipBehavior,
),
),
)
],
),
);
}
Widget incomeAnalytics() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Income Analytics", fontWeight: 600),
SfCircularChart(
margin: MySpacing.zero,
legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap),
series: [
PieSeries<ChartSampleData, String>(
dataSource: <ChartSampleData>[
ChartSampleData(x: 'USA', y: 700000, text: '60%'),
ChartSampleData(x: 'Germany', y: 450000, text: '50%'),
ChartSampleData(x: 'China', y: 600000, text: '65%'),
ChartSampleData(x: 'India', y: 400000, text: '55%'),
ChartSampleData(x: 'Brazil', y: 350000, text: '40%'),
ChartSampleData(x: 'Russia', y: 300000, text: '35%'),
ChartSampleData(x: 'South Africa', y: 250000, text: '30%')
],
xValueMapper: (ChartSampleData data, _) => data.x as String,
yValueMapper: (ChartSampleData data, _) => data.y,
dataLabelMapper: (ChartSampleData data, _) => data.x as String,
startAngle: 100,
endAngle: 100,
pointRadiusMapper: (ChartSampleData data, _) => data.text,
dataLabelSettings: const DataLabelSettings(isVisible: true, labelPosition: ChartDataLabelPosition.outside),
),
],
tooltipBehavior: TooltipBehavior(enable: true, tooltipPosition: TooltipPosition.auto, duration: 2 * 1000),
)
],
),
);
}
Widget taskList() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.all(24),
child: MyText.bodyMedium("Task List", fontWeight: 600),
),
SizedBox(
height: 300,
child: ListView.separated(
itemCount: controller.task.length,
shrinkWrap: true,
padding: MySpacing.x(24),
itemBuilder: (context, index) {
TaskListModel task = controller.task[index];
return Row(
children: [
Theme(
data: ThemeData(visualDensity: getCompactDensity),
child: Checkbox(
value: task.isSelectTask,
onChanged: (value) => controller.onSelectTask(task),
visualDensity: getCompactDensity,
),
),
MySpacing.width(12),
MyContainer.rounded(
height: 32,
width: 32,
paddingAll: 0,
child: Image.asset(Images.avatars[index % Images.avatars.length], fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(child: MyText.bodyMedium(task.title, maxLines: 1)),
MyText.labelMedium(task.status,
color: task.status == 'Pending'
? contentTheme.primary
: task.status == 'Completed'
? contentTheme.success
: null),
],
);
},
separatorBuilder: (context, index) {
return MySpacing.height(24);
},
),
)
],
),
);
}
Widget recentTransaction() {
Widget recentTransaction(String title, String subTitle, String price) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
MyContainer.roundBordered(
paddingAll: 12,
child: MyText(title[0].capitalize.toString()),
),
MySpacing.width(24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title),
MySpacing.height(4),
MyText.bodySmall(subTitle),
],
),
),
MyText.bodySmall(price),
],
)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 0,
height: 367,
child: ListView(
padding: MySpacing.all(24),
children: [
MyText.bodyMedium("Recent Transaction", fontWeight: 600),
MySpacing.height(24),
recentTransaction("Charles", "Feb 28,2023 - 12:54PM", "price"),
MySpacing.height(24),
recentTransaction("David", "Feb 28,2023 - 12:54PM", "price"),
MySpacing.height(24),
recentTransaction("Leonard", "Feb 28,2023 - 12:54PM", "price"),
MySpacing.height(24),
recentTransaction("Steven", "Feb 28,2023 - 12:54PM", "price"),
MySpacing.height(24),
recentTransaction("Steven", "Feb 28,2023 - 12:54PM", "price"),
],
),
);
}
Widget taskSummary() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Task Summary", fontWeight: 600),
MyContainer(
onTap: () {},
paddingAll: 8,
color: contentTheme.light,
child: MyText.labelSmall("View All", fontWeight: 600),
)
],
),
MySpacing.height(24),
SizedBox(
height: 344,
child: SfCartesianChart(
plotAreaBorderWidth: 0,
margin: MySpacing.zero,
legend: Legend(isVisible: true, position: LegendPosition.bottom),
primaryXAxis: const CategoryAxis(majorGridLines: MajorGridLines(width: 0), labelPlacement: LabelPlacement.onTicks),
primaryYAxis: const NumericAxis(
axisLine: AxisLine(width: 0), edgeLabelPlacement: EdgeLabelPlacement.shift, labelFormat: '{value}', majorTickLines: MajorTickLines(size: 0)),
series: [
SplineSeries<ChartSampleData, String>(
dataSource: controller.chartData,
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.y,
markerSettings: const MarkerSettings(isVisible: true),
name: 'This Week'),
SplineSeries<ChartSampleData, String>(
dataSource: controller.chartData,
name: 'Last Week',
markerSettings: const MarkerSettings(isVisible: true),
xValueMapper: (ChartSampleData sales, _) => sales.x as String,
yValueMapper: (ChartSampleData sales, _) => sales.secondSeriesYValue,
)
],
tooltipBehavior: TooltipBehavior(enable: true),
),
)
],
),
);
}
Widget projectSummary() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Project Summary", fontWeight: 600),
MySpacing.height(24),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 84,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('S.No', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Title', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Assign to', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Due Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Priority', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Action', color: contentTheme.primary)),
],
rows: controller.projectSummary
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.bodyMedium("#${data.id}", fontWeight: 600)),
DataCell(MyText.bodyMedium(data.title, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.assignTo, fontWeight: 600)),
DataCell(MyText.bodyMedium(Utils.getDateStringFromDateTime(data.date), fontWeight: 600)),
DataCell(MyText.bodyMedium(data.priority, fontWeight: 600)),
DataCell(MyText.bodyMedium(data.status, fontWeight: 600)),
DataCell(Row(
children: [
MyContainer(
onTap: () {},
color: contentTheme.primary,
paddingAll: 8,
child: Icon(LucideIcons.download, size: 16, color: contentTheme.onPrimary),
),
MySpacing.width(12),
MyContainer(
onTap: () {},
color: contentTheme.secondary,
paddingAll: 8,
child: Icon(LucideIcons.pencil, size: 16, color: contentTheme.onPrimary),
),
],
))
]))
.toList()),
)
],
),
);
}
}

View File

@ -1,506 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:marco/controller/dashboard/sales_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/utils/utils.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_container.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_list_extension.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/images.dart';
import 'package:marco/model/chart_model.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
class SalesScreen extends StatefulWidget {
const SalesScreen({super.key});
@override
State<SalesScreen> createState() => _SalesScreenState();
}
class _SalesScreenState extends State<SalesScreen> with UIMixin {
SalesController controller = Get.put(SalesController());
@override
Widget build(BuildContext context) {
return Layout(
child: GetBuilder(
init: controller,
tag: 'sales_dashboard_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Crypto", fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Dashboard'),
MyBreadcrumbItem(name: 'Crypto', active: true),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats("Total Income", "\$3,50,000", "15.00%")),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats("Profit", "\$1,20,000", "10.00%")),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats("Total Views", "15000", "5.00%")),
MyFlexItem(sizes: 'lg-3 md-6 sm-6', child: stats("Conversion Rate", "18.75%", "3.50%")),
MyFlexItem(sizes: 'lg-6 md-6', child: visitorsReport()),
MyFlexItem(sizes: 'lg-6 md-6', child: otherStatistics()),
MyFlexItem(sizes: 'lg-3.5 md-6', child: recentTransaction()),
MyFlexItem(sizes: 'lg-3.5 md-6', child: recentActivity()),
MyFlexItem(sizes: 'lg-2.5 md-6', child: countryWiseSale()),
MyFlexItem(sizes: 'lg-2.5 md-6', child: dealSource()),
MyFlexItem(child: recentOrder()),
],
),
),
],
);
},
),
);
}
Widget stats(String title, String changes, String percentage) {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 144,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title),
MyText.titleLarge(changes, fontWeight: 600),
Row(
children: [
MyContainer(
paddingAll: 4,
color: contentTheme.success.withValues(alpha:0.2),
child: MyText.labelSmall(percentage, color: contentTheme.success),
),
MySpacing.width(8),
Expanded(child: MyText.labelSmall("Compare to last month")),
],
)
],
));
}
Widget visitorsReport() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Visitors Report", fontWeight: 600),
MySpacing.height(24),
SfCartesianChart(
margin: MySpacing.zero,
primaryXAxis: CategoryAxis(),
tooltipBehavior: controller.visitorChart,
axes: <ChartAxis>[
NumericAxis(
numberFormat: NumberFormat.compact(),
majorGridLines: const MajorGridLines(width: 0),
opposedPosition: true,
name: 'yAxis1',
interval: 1000,
minimum: 0,
maximum: 7000)
],
series: [
ColumnSeries<ChartSampleData, String>(
animationDuration: 2000,
width: 0.5,
borderRadius: const BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(4)),
color: contentTheme.success,
dataSource: controller.visitorChartData,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.y,
name: 'Unit Sold'),
LineSeries<ChartSampleData, String>(
animationDuration: 4500,
animationDelay: 2000,
dataSource: controller.visitorChartData,
xValueMapper: (ChartSampleData data, _) => data.x,
yValueMapper: (ChartSampleData data, _) => data.yValue,
yAxisName: 'yAxis1',
markerSettings: const MarkerSettings(isVisible: true),
name: 'Total Transaction')
],
),
],
),
);
}
Widget otherStatistics() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Other Statistics", fontWeight: 600),
MySpacing.height(24),
SfCartesianChart(
plotAreaBorderWidth: 0,
margin: MySpacing.zero,
legend: Legend(isVisible: true, overflowMode: LegendItemOverflowMode.wrap, position: LegendPosition.bottom),
primaryXAxis: const NumericAxis(edgeLabelPlacement: EdgeLabelPlacement.shift, majorGridLines: MajorGridLines(width: 0)),
primaryYAxis: const NumericAxis(labelFormat: '{value}', axisLine: AxisLine(width: 0), majorTickLines: MajorTickLines(color: Colors.transparent)),
series: [
LineSeries<ChartData, num>(
dataSource: controller.statisticsData,
xValueMapper: (ChartData sales, _) => sales.x,
yValueMapper: (ChartData sales, _) => sales.y,
name: 'Pending',
color: contentTheme.secondary,
markerSettings: const MarkerSettings(isVisible: true)),
LineSeries<ChartData, num>(
dataSource: controller.statisticsData,
name: 'Delivered',
color: contentTheme.primary,
xValueMapper: (ChartData sales, _) => sales.x,
yValueMapper: (ChartData sales, _) => sales.y2,
markerSettings: const MarkerSettings(isVisible: true))
],
tooltipBehavior: TooltipBehavior(enable: true),
)
],
),
);
}
Widget recentTransaction() {
Widget recentTransactionWidget(String transactionMethod, String transactionType, String price, String date, IconData? icon, Color color) {
return Row(
children: [
MyContainer.rounded(
height: 44,
width: 44,
paddingAll: 0,
color: color.withValues(alpha:0.2),
child: Icon(icon, color: color),
),
MySpacing.width(24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(transactionMethod, fontWeight: 600, maxLines: 1),
MySpacing.height(4),
MyText.bodySmall(transactionType, fontWeight: 600, muted: true, maxLines: 1),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
MyText.bodyMedium(price, fontWeight: 600),
MyText.bodySmall(date, fontWeight: 600, muted: true),
],
),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 475,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: MyText.bodyMedium("Recent Transaction", fontWeight: 600)),
InkWell(onTap: () {}, child: MyText.labelSmall("View All", fontWeight: 600)),
],
),
MySpacing.height(24),
recentTransactionWidget("Digital Wallet", "Online Transaction", "\$350.00", "Nov 23, 2023", LucideIcons.gift, contentTheme.primary),
MySpacing.height(24),
recentTransactionWidget("Bank Account", "Purchase", "\$150.00", "Nov 23, 2023", LucideIcons.coins, contentTheme.success),
MySpacing.height(24),
recentTransactionWidget("PayPal", "Transfer", "\$500.00", "Nov 22, 2023", LucideIcons.shopping_cart, contentTheme.purple),
MySpacing.height(24),
recentTransactionWidget("Digital Wallet", "Bill Payment", "\$120.00", "Nov 21, 2023", LucideIcons.wallet, contentTheme.warning),
MySpacing.height(24),
recentTransactionWidget("Credit Card", "Subscription", "\$20.00", "Nov 20, 2023", LucideIcons.id_card, contentTheme.danger),
MySpacing.height(24),
recentTransactionWidget("Digital Wallet", "Refund", "\$100.00", "Nov 19, 2023", LucideIcons.circle_arrow_up, contentTheme.info),
],
),
);
}
Widget countryWiseSale() {
Widget countryWiseSaleWidget(String image, name, count) {
return Row(
children: [
MyContainer.rounded(
paddingAll: 0,
height: 44,
width: 44,
clipBehavior: Clip.antiAliasWithSaveLayer,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(child: MyText.bodyMedium(name, fontWeight: 600, overflow: TextOverflow.ellipsis)),
MyContainer(
borderRadiusAll: 8,
padding: MySpacing.xy(8, 8),
color: contentTheme.success.withAlpha(36),
child: MyText.bodySmall(numberFormatter(count), fontWeight: 600, color: contentTheme.success),
)
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 475,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Country wise sale", fontWeight: 600),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/united_states.png', "France", "25000"),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/argentina.png', "Brazil", "17500"),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/germany.png', "India", "12500"),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/mexico.png', "Japan", "22000"),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/russia.png', "United Kingdom", "30000"),
MySpacing.height(24),
countryWiseSaleWidget('assets/country/canada.png', "Australia", "18000"),
],
),
);
}
Widget recentActivity() {
Widget recentActivityWidget(String title) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyContainer.rounded(paddingAll: 4, child: MyContainer.rounded(paddingAll: 4, color: contentTheme.primary, child: MyContainer.rounded(paddingAll: 4))),
MySpacing.width(12),
Expanded(child: MyText.bodyMedium(title, fontWeight: 600, maxLines: 2))
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 475,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Recent Activity", fontWeight: 600),
MySpacing.height(24),
recentActivityWidget(
"Ava Thompson placed an order for 3 units of Wireless Earbuds, 2 units of Bluetooth Speakers, and 1 unit of Smart Home Thermostat"),
MySpacing.height(24),
recentActivityWidget(
"Noah Jackson upgraded his subscription to the Gold service plan, gaining access to premium features, priority support, and 20GB cloud storage for his team of 15 employees."),
MySpacing.height(24),
recentActivityWidget(
"Emma Harris added 5 new items to the shopping cart, including a designer handbag, a set of luxury skincare products, a Bluetooth speaker, a fitness tracker, and a pair of leather boots"),
MySpacing.height(24),
recentActivityWidget(
"Liam Davis purchased 1 unit of Electric Scooter, along with an additional helmet and charging station for enhanced convenience. Delivery expected in 5-7 business days."),
MySpacing.height(24),
recentActivityWidget(
"Mason Martinez returned 2 units of Smartphone, citing dissatisfaction with the camera quality. The items will be processed for a full refund once inspected."),
MySpacing.height(24),
recentActivityWidget(
"Isabella Robinson upgraded to the Platinum Plan with 5 users, unlocking advanced analytics tools, exclusive discounts, and premium customer support for her growing e-commerce team."),
MySpacing.height(24),
recentActivityWidget(
"Elijah Walker completed a purchase of 6 ergonomic office chairs, 3 sit-stand desks, and a set of new monitor arms for the team, improving the comfort and productivity of the workspace."),
],
),
);
}
Widget dealSource() {
Widget dealSourceWidget(String image, String title, String subtitle, String totalLeads) {
return Row(
children: [
MyContainer.rounded(
height: 44,
width: 44,
paddingAll: 0,
child: Image.asset(image, fit: BoxFit.cover),
),
MySpacing.width(12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium(title, fontWeight: 600, maxLines: 1),
MyText.bodySmall(subtitle, maxLines: 1),
],
),
),
MyText.bodyMedium('\$$totalLeads', fontWeight: 600),
],
);
}
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
height: 475,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Deal Source", fontWeight: 600),
MySpacing.height(24),
dealSourceWidget("assets/social/uxerflow_logo.png", "Website", "userflow.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/dribbble-logo.png", "Dribbble", "dribbble.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/facebook-logo.png", "Facebook", "facebook.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/instagram-logo.png", "Instagram", "instagram.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/LinkedIn-logo.png", "Linkedin", "linkedin.com", "50"),
MySpacing.height(24),
dealSourceWidget("assets/social/twitter-logo.png", "Twitter", "twitter.com", "50"),
],
),
);
}
Widget recentOrder() {
return MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withValues(alpha:0.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.bodyMedium("Recent Order", fontWeight: 600),
MySpacing.height(24),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
sortAscending: true,
columnSpacing: 150,
onSelectAll: (_) => {},
headingRowColor: WidgetStatePropertyAll(contentTheme.primary.withAlpha(40)),
dataRowMaxHeight: 60,
showBottomBorder: true,
clipBehavior: Clip.antiAliasWithSaveLayer,
border: TableBorder.all(borderRadius: BorderRadius.circular(4), style: BorderStyle.solid, width: .4, color: Colors.grey),
columns: [
DataColumn(label: MyText.labelLarge('Product', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Quantity', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Customer', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Status', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Price', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Date', color: contentTheme.primary)),
DataColumn(label: MyText.labelLarge('Action', color: contentTheme.primary)),
],
rows: controller.recentOrder
.mapIndexed((index, data) => DataRow(cells: [
DataCell(MyText.labelMedium(data.productName)),
DataCell(MyText.labelMedium('${data.quantity}')),
DataCell(Row(
children: [
MyContainer.rounded(
height: 32,
width: 32,
paddingAll: 0,
child: Image.asset(Images.avatars[index % Images.avatars.length]),
),
MySpacing.width(12),
MyText.labelMedium('${data.customer}'),
],
)),
DataCell(
MyContainer(
paddingAll: 4,
color: data.status == 'Shipped'
? contentTheme.success
: data.status == 'Delivery'
? contentTheme.info
: contentTheme.danger,
child: MyText.labelMedium(
'${data.status}',
color: data.status == 'Success' ? contentTheme.onSuccess : contentTheme.onDanger,
),
),
),
DataCell(MyText.labelMedium('\$${data.price}')),
DataCell(MyText.labelMedium('${Utils.getDateTimeStringFromDateTime(data.orderDate)}')),
DataCell(Row(
children: [
MyContainer.rounded(
onTap: () {},
paddingAll: 8,
color: contentTheme.primary,
child: Icon(LucideIcons.eye, size: 16, color: contentTheme.onPrimary),
),
MySpacing.width(20),
MyContainer.rounded(
onTap: () {},
paddingAll: 8,
color: contentTheme.secondary,
child: Icon(LucideIcons.pencil, size: 16, color: contentTheme.onSecondary),
),
],
)),
]))
.toList()),
),
],
),
);
}
}

View File

@ -1,303 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/task_planing/report_task_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_button.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/my_text_style.dart';
import 'package:marco/view/layouts/layout.dart';
import 'package:marco/helpers/widgets/avatar.dart';
import 'package:marco/helpers/widgets/my_team_model_sheet.dart';
class CommentTaskScreen extends StatefulWidget {
const CommentTaskScreen({super.key});
@override
State<CommentTaskScreen> createState() => _CommentTaskScreenState();
}
class _Member {
final String firstName;
_Member(this.firstName);
}
class _CommentTaskScreenState extends State<CommentTaskScreen> with UIMixin {
final ReportTaskController controller = Get.put(ReportTaskController());
@override
Widget build(BuildContext context) {
final taskData = Get.arguments as Map<String, dynamic>;
print("Task Data: $taskData");
controller.basicValidator.getController('assigned_date')?.text =
taskData['assignedOn'] ?? '';
controller.basicValidator.getController('assigned_by')?.text =
taskData['assignedBy'] ?? '';
controller.basicValidator.getController('work_area')?.text =
taskData['location'] ?? '';
controller.basicValidator.getController('activity')?.text =
taskData['activity'] ?? '';
controller.basicValidator.getController('planned_work')?.text =
taskData['plannedWork'] ?? '';
controller.basicValidator.getController('completed_work')?.text =
taskData['completedWork'] ?? '';
controller.basicValidator.getController('team_members')?.text =
(taskData['teamMembers'] as List<dynamic>).join(', ');
controller.basicValidator.getController('assigned')?.text =
taskData['assigned'] ?? '';
controller.basicValidator.getController('task_id')?.text =
taskData['taskId'] ?? '';
return Layout(
child: GetBuilder<ReportTaskController>(
init: controller,
tag: 'comment_task_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Comment Task",
fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Daily Progress Report'),
MyBreadcrumbItem(name: 'Comment Task'),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: "lg-8 md-12", child: detail()),
],
),
),
],
);
},
),
);
}
Widget detail() {
return Form(
key: controller.basicValidator.formKey,
child: MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withOpacity(0.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(LucideIcons.server, size: 16),
MySpacing.width(12),
MyText.titleMedium("Activity Summary", fontWeight: 600),
],
),
MySpacing.height(24),
// Static fields
buildRow(
"Assigned By",
controller.basicValidator
.getController('assigned_by')
?.text
.trim()),
buildRow(
"Work Area",
controller.basicValidator
.getController('work_area')
?.text
.trim()),
buildRow(
"Activity",
controller.basicValidator
.getController('activity')
?.text
.trim()),
buildRow(
"Planned Work",
controller.basicValidator
.getController('planned_work')
?.text
.trim()),
buildRow(
"Completed Work",
controller.basicValidator
.getController('completed_work')
?.text
.trim()),
buildTeamMembers(),
MyText.labelMedium("Comment"),
MySpacing.height(8),
TextFormField(
validator: controller.basicValidator.getValidation('comment'),
controller: controller.basicValidator.getController('comment'),
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: "eg: Work done successfully",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
// Buttons
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
MyButton.text(
onPressed: () => Get.back(),
padding: MySpacing.xy(20, 16),
splashColor: contentTheme.secondary.withValues(alpha: 0.1),
child: MyText.bodySmall('Cancel'),
),
MySpacing.width(12),
MyButton(
onPressed: () async {
if (controller.basicValidator.validateForm()) {
await controller.reportTask(
projectId: controller.basicValidator
.getController('task_id')
?.text ??
'', // Replace with actual ID
comment: controller.basicValidator
.getController('comment')
?.text ??
'',
completedTask: int.tryParse(controller.basicValidator
.getController('completed_work')
?.text ??
'') ??
0,
checklist: [],
reportedDate: DateTime.now(),
);
}
},
elevation: 0,
padding: MySpacing.xy(20, 16),
backgroundColor: contentTheme.primary,
borderRadiusAll: AppStyle.buttonRadius.medium,
child: MyText.bodySmall(
'Comment',
color: contentTheme.onPrimary,
),
),
],
),
// Loading spinner
Obx(() {
return controller.isLoading.value
? Center(child: CircularProgressIndicator())
: SizedBox.shrink();
}),
],
),
),
);
}
Widget buildTeamMembers() {
final teamMembersText =
controller.basicValidator.getController('team_members')?.text ?? '';
final members = teamMembersText
.split(',')
.map((e) => e.trim())
.where((e) => e.isNotEmpty)
.toList();
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MyText.labelMedium("Team Members:"),
MySpacing.width(12),
GestureDetector(
onTap: () {
TeamBottomSheet.show(
context: context,
teamMembers: members.map((name) => _Member(name)).toList(),
);
},
child: SizedBox(
height: 32,
width: 100,
child: Stack(
children: [
for (int i = 0; i < members.length.clamp(0, 3); i++)
Positioned(
left: i * 24.0,
child: Tooltip(
message: members[i],
child: Avatar(
firstName: members[i],
lastName: '',
size: 32,
),
),
),
if (members.length > 3)
Positioned(
left: 2 * 24.0,
child: CircleAvatar(
radius: 16,
backgroundColor: Colors.grey.shade300,
child: MyText.bodyMedium(
'+${members.length - 3}',
style: const TextStyle(
fontSize: 12, color: Colors.black87),
),
),
),
],
),
),
),
],
),
);
}
Widget buildRow(String label, String? value) {
print("Label: $label, Value: $value");
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("$label:"),
MySpacing.width(12),
Expanded(
child: MyText.bodyMedium(value?.isNotEmpty == true ? value! : "-"),
),
],
),
);
}
}

View File

@ -1,269 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:get/get.dart';
import 'package:marco/controller/task_planing/report_task_controller.dart';
import 'package:marco/helpers/theme/app_theme.dart';
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
import 'package:marco/helpers/utils/my_shadow.dart';
import 'package:marco/helpers/widgets/my_breadcrumb.dart';
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
import 'package:marco/helpers/widgets/my_button.dart';
import 'package:marco/helpers/widgets/my_card.dart';
import 'package:marco/helpers/widgets/my_flex.dart';
import 'package:marco/helpers/widgets/my_flex_item.dart';
import 'package:marco/helpers/widgets/my_spacing.dart';
import 'package:marco/helpers/widgets/my_text.dart';
import 'package:marco/helpers/widgets/my_text_style.dart';
import 'package:marco/view/layouts/layout.dart';
class ReportTaskScreen extends StatefulWidget {
const ReportTaskScreen({super.key});
@override
State<ReportTaskScreen> createState() => _ReportTaskScreenState();
}
class _ReportTaskScreenState extends State<ReportTaskScreen> with UIMixin {
final ReportTaskController controller = Get.put(ReportTaskController());
@override
Widget build(BuildContext context) {
final taskData = Get.arguments as Map<String, dynamic>;
print("Task Data: $taskData");
controller.basicValidator.getController('assigned_date')?.text =
taskData['assignedOn'] ?? '';
controller.basicValidator.getController('assigned_by')?.text =
taskData['assignedBy'] ?? '';
controller.basicValidator.getController('work_area')?.text =
taskData['location'] ?? '';
controller.basicValidator.getController('activity')?.text =
taskData['activity'] ?? '';
controller.basicValidator.getController('team_size')?.text =
taskData['teamSize'].toString();
controller.basicValidator.getController('assigned')?.text =
taskData['assigned'] ?? '';
controller.basicValidator.getController('task_id')?.text =
taskData['taskId'] ?? '';
return Layout(
child: GetBuilder<ReportTaskController>(
init: controller,
tag: 'report_task_controller',
builder: (controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: MySpacing.x(flexSpacing),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MyText.titleMedium("Report Task",
fontSize: 18, fontWeight: 600),
MyBreadcrumb(
children: [
MyBreadcrumbItem(name: 'Daily Progress Report'),
MyBreadcrumbItem(name: 'Report Task'),
],
),
],
),
),
MySpacing.height(flexSpacing),
Padding(
padding: MySpacing.x(flexSpacing / 2),
child: MyFlex(
children: [
MyFlexItem(sizes: "lg-8 md-12", child: detail()),
],
),
),
],
);
},
),
);
}
Widget detail() {
return Form(
key: controller.basicValidator.formKey,
child: MyCard.bordered(
borderRadiusAll: 4,
border: Border.all(color: Colors.grey.withOpacity(0.2)),
shadow: MyShadow(elevation: 1, position: MyShadowPosition.bottom),
paddingAll: 24,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(LucideIcons.server, size: 16),
MySpacing.width(12),
MyText.titleMedium("General", fontWeight: 600),
],
),
MySpacing.height(24),
// Static fields
buildRow(
"Assigned Date",
controller.basicValidator
.getController('assigned_date')
?.text
.trim()),
buildRow(
"Assigned By",
controller.basicValidator
.getController('assigned_by')
?.text
.trim()),
buildRow(
"Work Area",
controller.basicValidator
.getController('work_area')
?.text
.trim()),
buildRow(
"Activity",
controller.basicValidator
.getController('activity')
?.text
.trim()),
buildRow(
"Team Size",
controller.basicValidator
.getController('team_size')
?.text
.trim()),
buildRow(
"Assigned",
controller.basicValidator
.getController('assigned')
?.text
.trim()),
// Input fields
MyText.labelMedium("Completed Work"),
MySpacing.height(8),
TextFormField(
validator:
controller.basicValidator.getValidation('completed_work'),
controller:
controller.basicValidator.getController('completed_work'),
keyboardType: TextInputType.number,
decoration: InputDecoration(
hintText: "eg: 10",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
MyText.labelMedium("Comment"),
MySpacing.height(8),
TextFormField(
validator: controller.basicValidator.getValidation('comment'),
controller: controller.basicValidator.getController('comment'),
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: "eg: Work done successfully",
hintStyle: MyTextStyle.bodySmall(xMuted: true),
border: outlineInputBorder,
enabledBorder: outlineInputBorder,
focusedBorder: focusedInputBorder,
contentPadding: MySpacing.all(16),
isCollapsed: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
),
),
MySpacing.height(24),
// Buttons
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
MyButton.text(
onPressed: () => Get.back(),
padding: MySpacing.xy(20, 16),
splashColor: contentTheme.secondary.withValues(alpha: 0.1),
child: MyText.bodySmall('Cancel'),
),
MySpacing.width(12),
MyButton(
onPressed: controller.reportStatus.value == ApiStatus.loading
? null
: () async {
if (controller.basicValidator.validateForm()) {
await controller.reportTask(
projectId: controller.basicValidator
.getController('task_id')
?.text ??
'',
comment: controller.basicValidator
.getController('comment')
?.text ??
'',
completedTask: int.tryParse(controller
.basicValidator
.getController('completed_work')
?.text ??
'') ??
0,
checklist: [],
reportedDate: DateTime.now(),
);
}
},
elevation: 0,
padding: MySpacing.xy(20, 16),
backgroundColor: contentTheme.primary,
borderRadiusAll: AppStyle.buttonRadius.medium,
child: Obx(() {
if (controller.reportStatus.value == ApiStatus.loading) {
return SizedBox(
height: 16,
width: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
contentTheme.onPrimary),
),
);
} else {
return MyText.bodySmall(
'Save',
color: contentTheme.onPrimary,
);
}
}),
),
],
),
],
),
),
);
}
Widget buildRow(String label, String? value) {
print("Label: $label, Value: $value");
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
MyText.labelMedium("$label:"),
MySpacing.width(12),
Expanded(
child: MyText.bodyMedium(value?.isNotEmpty == true ? value! : "-"),
),
],
),
);
}
}

View File

@ -100,8 +100,6 @@ flutter:
- assets/country/ - assets/country/
- assets/data/ - assets/data/
- assets/dummy/ - assets/dummy/
- assets/dummy/ecommerce/
- assets/dummy/single_product/
- assets/lang/ - assets/lang/
- assets/logo/ - assets/logo/
- assets/logo/loading_logo.png - assets/logo/loading_logo.png