diff --git a/lib/main.dart b/lib/main.dart index 2a2f8d8..6ada054 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - +import 'package:vector/views/leader.dart'; import 'view_models/home_view_model.dart'; +import 'views/leaderboard.dart'; void main() { runApp(const MyApp()); @@ -13,16 +14,18 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( - providers: [ChangeNotifierProvider(create: (_) => HomeViewModel())], + providers: [ + ChangeNotifierProvider(create: (_) => HomeViewModel()), + ], child: MaterialApp( - title: 'Vector', + title: 'Fitness Tracker', debugShowCheckedModeBanner: false, theme: ThemeData( - colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + brightness: Brightness.dark, useMaterial3: true, ), - home: const Scaffold(body: Center(child: Text('Vector'))), + home: Board(), ), ); } -} +} \ No newline at end of file diff --git a/lib/views/home_view.dart b/lib/views/home_view.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/views/leader.dart b/lib/views/leader.dart new file mode 100644 index 0000000..8d92b66 --- /dev/null +++ b/lib/views/leader.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; + +class Board extends StatefulWidget { + @override + _BoardState createState() => _BoardState(); +} + +class _BoardState extends State { + String sel = "Week"; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Column( + children: [ + const SizedBox(height: 60), + _head(), + _tabs(), + _podium(), + _list(), + ], + ), + // Navigation bar property removed from here + ); + } + + Widget _head() => Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Row( + children: [ + const Icon(Icons.arrow_back_ios, color: Colors.white, size: 18), + const Text(" Back", style: TextStyle(color: Colors.white)), + const Expanded(child: Center(child: Text("Leaderboard", + style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold)))), + const SizedBox(width: 60), + ], + ), + ); + + Widget _tabs() => Container( + margin: const EdgeInsets.all(19), + padding: const EdgeInsets.all(4), + decoration: BoxDecoration(color: const Color(0XFF5D4973), borderRadius: BorderRadius.circular(7)), + child: Row( + children: ["Week", "Month", "Year"].map((t) => _tabItem(t)).toList(), + ), + ); + + Widget _tabItem(String t) { + bool active = sel == t; + return Expanded( + child: GestureDetector( + onTap: () => setState(() => sel = t), + child: Container( + padding: const EdgeInsets.symmetric(vertical: 10), + decoration: BoxDecoration( + color: active ? const Color(0xFF6A3D91) : Colors.transparent, + borderRadius: BorderRadius.circular(10), + ), + child: Text(t, textAlign: TextAlign.center, + style: TextStyle(color: active ? Colors.white : Colors.white54, fontWeight: FontWeight.bold)), + ), + ), + ); + } + + Widget _podium() => Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + _bar("Sia", "12000", 130, 2), + _bar("Ria", "13000", 170, 1), + _bar("Lia", "11000", 110, 3), + ], + ), + ); + + Widget _bar(String n, String s, double h, int r) => Expanded( + child: Column( + children: [ + const Text("👑", style: TextStyle(fontSize: 20)), + Text(n, style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Container( + padding: const EdgeInsets.all(4), + decoration: BoxDecoration(color: const Color(0xFF9F4987).withOpacity(0.2), borderRadius: BorderRadius.circular(8)), + child: Text(s, style: const TextStyle(color: Colors.white, fontSize: 10)), + ), + const SizedBox(height: 8), + Container( + height: h, width: double.infinity, margin: const EdgeInsets.symmetric(horizontal: 5), + decoration: BoxDecoration( + color: const Color(0xFFAA4FA9).withOpacity(r == 1 ? 1 : 0.7), + borderRadius: const BorderRadius.vertical(top: Radius.circular(15)), + ), + alignment: Alignment.center, + child: Text("$r", style: const TextStyle(color: Colors.white24, fontSize: 40, fontWeight: FontWeight.bold)), + ), + ], + ), + ); + + Widget _list() => Expanded( + child: Container( + decoration: const BoxDecoration(color: Color(0xFF1F1135), borderRadius: BorderRadius.vertical(top: Radius.circular(30))), + child: ListView.builder( + padding: const EdgeInsets.all(20), + itemCount: 15, + itemBuilder: (c, i) => _item(i + 4), + ), + ), + ); + + Widget _item(int r) => Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(16), + decoration: BoxDecoration(color: const Color(0xFF8E52AE), borderRadius: BorderRadius.circular(15)), + child: Row( + children: [ + Text("#$r", style: const TextStyle(color: Colors.white70)), + const SizedBox(width: 15), + const Text("Rahul Singh", style: TextStyle(color: Colors.white)), + const Spacer(), + const Text("10k steps", style: TextStyle(color: Colors.white54, fontSize: 12)), + Icon(r % 3 == 0 ? Icons.arrow_drop_down : Icons.arrow_drop_up, color: r % 3 == 0 ? Colors.red : Colors.green), + ], + ), + ); +} \ No newline at end of file diff --git a/lib/views/leaderboard.dart b/lib/views/leaderboard.dart new file mode 100644 index 0000000..8439456 --- /dev/null +++ b/lib/views/leaderboard.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; + +class StepLeaderboard extends StatefulWidget { + @override + State createState() => _StepLeaderboardState(); +} + +class _StepLeaderboardState extends State { + // 1. Track the selected period + String selectedPeriod = "Week"; + + // 2. Data maps for different periods + final Map>> allData = { + "Week": [ + {"rank": 1, "name": "User 1", "steps": "16500", "status": "Top-1 for 6 days"}, + {"rank": 2, "name": "User 2", "steps": "16000", "status": "Top-10 for 6 days"}, + ], + "Month": [ + {"rank": 1, "name": "User 2", "steps": "450,000", "status": "Monthly King"}, + {"rank": 2, "name": "User 5", "steps": "420,000", "status": "Rising Star"}, + ], + "Year": [ + {"rank": 1, "name": "User 8", "steps": "5,200,000", "status": "All-Time Pro"}, + ], + }; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + backgroundColor: Colors.black, + title: const Text("Daily Step Challenge", style: TextStyle(color: Colors.white)), + centerTitle: true, + ), + body: Column( + children: [ + _buildSegmentedControl(), + const SizedBox(height: 10), + Expanded(child: _buildLeaderboardList()), + ], + ), + ); + } + + Widget _buildSegmentedControl() { + return Container( + margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + decoration: BoxDecoration( + color: const Color(0xFF1A1A1A), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + children: [ + _filterTab("Week"), + _filterTab("Month"), + _filterTab("Year"), + ], + ), + ); + } + + Widget _filterTab(String label) { + bool isActive = selectedPeriod == label; + return Expanded( + child: GestureDetector( + onTap: () { + // 3. Update the state when clicked + setState(() { + selectedPeriod = label; + }); + }, + child: Container( + padding: const EdgeInsets.symmetric(vertical: 12), + decoration: BoxDecoration( + color: isActive ? const Color(0xFF6B429C) : Colors.transparent, + borderRadius: BorderRadius.circular(10), + ), + child: Text( + label, + textAlign: TextAlign.center, + style: TextStyle( + color: isActive ? Colors.white : Colors.grey, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ); + } + + Widget _buildLeaderboardList() { + // 4. Get the list based on selection + final players = allData[selectedPeriod]!; + + return ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 20), + itemCount: players.length, + itemBuilder: (context, index) { + final user = players[index]; + return Container( + margin: const EdgeInsets.only(bottom: 12), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: const Color(0xFF8E54D3), + borderRadius: BorderRadius.circular(20), + ), + child: Column( + children: [ + Row( + children: [ + Text("# ${user['rank']}", style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20)), + const SizedBox(width: 30), + Text(user['name'], style: const TextStyle(color: Colors.white, fontSize: 18)), + const Spacer(), + Text("${user['steps']} steps", style: const TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ], + ), + const SizedBox(height: 12), + Text(user['status'], style: TextStyle(color: Colors.white.withOpacity(0.8))), + ], + ), + ); + }, + ); + } +} \ No newline at end of file diff --git a/lib/views/streak.dart b/lib/views/streak.dart new file mode 100644 index 0000000..dbe269c --- /dev/null +++ b/lib/views/streak.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; + +void main() => runApp(const MaterialApp(home: StreakPage())); + +class StreakPage extends StatefulWidget { + const StreakPage({super.key}); + + @override + State createState() => _StreakPageState(); +} + +class _StreakPageState extends State { + int streakCount = 40; + + int currentStep = 1; + + void _incrementStreak(int index) { + setState(() { + currentStep = index; + //streakCount++; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: Center( + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 16), + padding: const EdgeInsets.all(24), + decoration: BoxDecoration( + color: const Color(0xFF1C1C1E), + borderRadius: BorderRadius.circular(24), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "$streakCount days streak!", + style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white), + ), + const Text( + "This is what consistency looks like", + style: TextStyle(color: Colors.grey, fontSize: 12), + ), + ], + ), + const Text("🔥", style: TextStyle(fontSize: 30)), + ], + ), + const SizedBox(height: 30), + + Stack( + alignment: Alignment.center, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: Container(height: 2, color: Colors.white10), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildStreakNode(0, label: "31\ndec"), + _buildStreakNode(1, icon: Icons.directions_run), + _buildStreakNode(2, icon: Icons.ice_skating), + _buildStreakNode(3, icon: Icons.directions_bike), + ], + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget _buildStreakNode(int index, {String? label, IconData? icon}) { + bool isCompleted = index <= currentStep; + bool isFirst = index == 0; + + return GestureDetector( + onTap: () => _incrementStreak(index), + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isFirst + ? const Color(0xFF3D5AFE) + : (isCompleted ? const Color(0xFF2E7D32) : const Color(0xFF2C2C2E)), + ), + child: Center( + child: icon != null + ? Icon(icon, color: isCompleted ? Colors.white : Colors.white24, size: 20) + : Text( + label!, + textAlign: TextAlign.center, + style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold), + ), + ), + ), + ); + } +} \ No newline at end of file