diff --git a/assets/images/Background.png b/assets/images/Background.png
new file mode 100644
index 00000000..02529ba3
Binary files /dev/null and b/assets/images/Background.png differ
diff --git a/assets/images/Logo.svg b/assets/images/Logo.svg
new file mode 100644
index 00000000..0a592c03
--- /dev/null
+++ b/assets/images/Logo.svg
@@ -0,0 +1,38 @@
+
diff --git a/assets/images/Vector.png b/assets/images/Vector.png
new file mode 100644
index 00000000..c105e7e3
Binary files /dev/null and b/assets/images/Vector.png differ
diff --git a/assets/images/black-logo.png b/assets/images/black-logo.png
new file mode 100644
index 00000000..0d42805c
Binary files /dev/null and b/assets/images/black-logo.png differ
diff --git a/assets/images/login_logo.svg b/assets/images/login_logo.svg
new file mode 100644
index 00000000..0e5f7681
--- /dev/null
+++ b/assets/images/login_logo.svg
@@ -0,0 +1,12 @@
+
diff --git a/assets/images/logo_horizontal.png b/assets/images/logo_horizontal.png
new file mode 100644
index 00000000..2d29681a
Binary files /dev/null and b/assets/images/logo_horizontal.png differ
diff --git a/assets/images/web_Background.svg b/assets/images/web_Background.svg
new file mode 100644
index 00000000..11c967e0
--- /dev/null
+++ b/assets/images/web_Background.svg
@@ -0,0 +1,323 @@
+
diff --git a/assets/images/white-logo.png b/assets/images/white-logo.png
new file mode 100644
index 00000000..2e73e35b
Binary files /dev/null and b/assets/images/white-logo.png differ
diff --git a/lib/main.dart b/lib/main.dart
index ace34de6..22b0ee28 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,126 +1,29 @@
+import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
-import 'package:syncrow_web/pages/auth/view/login_page.dart';
+import 'package:syncrow_web/pages/home/view/home_page.dart';
void main() {
runApp(const MyApp());
}
-
class MyApp extends StatelessWidget {
const MyApp({super.key});
-
- // This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
- title: 'Flutter Demo',
+ debugShowCheckedModeBanner: false,
+ scrollBehavior: const MaterialScrollBehavior().copyWith(
+ dragDevices: {
+ PointerDeviceKind.mouse,
+ PointerDeviceKind.touch,
+ PointerDeviceKind.stylus,
+ PointerDeviceKind.unknown
+ },
+ ),
theme: ThemeData(
- // This is the theme of your application.
- //
- // TRY THIS: Try running your application with "flutter run". You'll see
- // the application has a purple toolbar. Then, without quitting the app,
- // try changing the seedColor in the colorScheme below to Colors.green
- // and then invoke "hot reload" (save your changes or press the "hot
- // reload" button in a Flutter-supported IDE, or press "r" if you used
- // the command line to start the app).
- //
- // Notice that the counter didn't reset back to zero; the application
- // state is not lost during the reload. To reset the state, use hot
- // restart instead.
- //
- // This works for code too, not just values: Most code changes can be
- // tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
- home: LoginPage(),
- );
- }
-}
-
-class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- // This widget is the home page of your application. It is stateful, meaning
- // that it has a State object (defined below) that contains fields that affect
- // how it looks.
-
- // This class is the configuration for the state. It holds the values (in this
- // case the title) provided by the parent (in this case the App widget) and
- // used by the build method of the State. Fields in a Widget subclass are
- // always marked "final".
-
- final String title;
-
- @override
- State createState() => _MyHomePageState();
-}
-
-class _MyHomePageState extends State {
- int _counter = 0;
-
- void _incrementCounter() {
- setState(() {
- // This call to setState tells the Flutter framework that something has
- // changed in this State, which causes it to rerun the build method below
- // so that the display can reflect the updated values. If we changed
- // _counter without calling setState(), then the build method would not be
- // called again, and so nothing would appear to happen.
- _counter++;
- });
- }
-
- @override
- Widget build(BuildContext context) {
- // This method is rerun every time setState is called, for instance as done
- // by the _incrementCounter method above.
- //
- // The Flutter framework has been optimized to make rerunning build methods
- // fast, so that you can just rebuild anything that needs updating rather
- // than having to individually change instances of widgets.
- return Scaffold(
- appBar: AppBar(
- // TRY THIS: Try changing the color here to a specific color (to
- // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
- // change color while the other colors stay the same.
- backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- // Here we take the value from the MyHomePage object that was created by
- // the App.build method, and use it to set our appbar title.
- title: Text(widget.title),
- ),
- body: Center(
- // Center is a layout widget. It takes a single child and positions it
- // in the middle of the parent.
- child: Column(
- // Column is also a layout widget. It takes a list of children and
- // arranges them vertically. By default, it sizes itself to fit its
- // children horizontally, and tries to be as tall as its parent.
- //
- // Column has various properties to control how it sizes itself and
- // how it positions its children. Here we use mainAxisAlignment to
- // center the children vertically; the main axis here is the vertical
- // axis because Columns are vertical (the cross axis would be
- // horizontal).
- //
- // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
- // action in the IDE, or press "p" in the console), to see the
- // wireframe for each widget.
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- const Text(
- 'You have pushed the button this many times:',
- ),
- Text(
- '$_counter',
- style: Theme.of(context).textTheme.headlineMedium,
- ),
- ],
- ),
- ),
- floatingActionButton: FloatingActionButton(
- onPressed: _incrementCounter,
- tooltip: 'Increment',
- child: const Icon(Icons.add),
- ), // This trailing comma makes auto-formatting nicer for build methods.
+ home: const HomePage(),
);
}
}
diff --git a/lib/pages/auth/view/login_mobile_page.dart b/lib/pages/auth/view/login_mobile_page.dart
new file mode 100644
index 00000000..9dc81efe
--- /dev/null
+++ b/lib/pages/auth/view/login_mobile_page.dart
@@ -0,0 +1,220 @@
+import 'dart:ui';
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:syncrow_web/utils/assets.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_bloc.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_event.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_state.dart';
+import 'package:syncrow_web/pages/home/view/home_page.dart';
+
+class LoginMobilePage extends StatelessWidget {
+ const LoginMobilePage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: BlocProvider(
+ create: (context) => LoginBloc(),
+ child: BlocConsumer(
+ listener: (context, state) {
+ if (state is LoginSuccess) {
+ // Navigate to home screen after successful login
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => const HomePage()),
+ );
+ } else if (state is LoginFailure) {
+ // Show error message
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text(state.error),
+ ),
+ );
+ }
+ },
+ builder: (context, state) {
+ if (state is LoginLoading) {
+ return const Center(child: CircularProgressIndicator());
+ } else {
+ return _buildLoginForm(context);
+ }
+ },
+ ),
+ ),
+
+ );
+ }
+
+ Widget _buildLoginForm(BuildContext context) {
+ final loginBloc = BlocProvider.of(context);
+ final TextEditingController _usernameController = TextEditingController();
+ final TextEditingController _passwordController = TextEditingController();
+ return Center(
+ child: Stack(
+ children: [
+ Container(
+ width: MediaQuery.sizeOf(context).width,
+ height: MediaQuery.sizeOf(context).height,
+ decoration: const BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ Assets.background,
+ ),
+ fit: BoxFit.cover,
+ ),
+ ),
+ ),
+ Container(
+ width: MediaQuery.sizeOf(context).width,
+ height: MediaQuery.sizeOf(context).height,
+ decoration: const BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(Assets.vector),
+ fit: BoxFit.cover,
+ opacity: 0.9,
+ ),
+ ),
+ ),
+ SingleChildScrollView(
+ child: Container(
+ margin: const EdgeInsets.all(50),
+ decoration: BoxDecoration(
+ color: Colors.black.withOpacity(0.3),
+ borderRadius: const BorderRadius.all(Radius.circular(20))),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Padding(
+ padding: const EdgeInsets.all(15.0),
+ child: SvgPicture.asset(
+ Assets.loginLogo,
+ ),
+ ),
+ Container(
+ margin: const EdgeInsets.all(15),
+ decoration: BoxDecoration(
+ color: Colors.white.withOpacity(0.3),
+ borderRadius: const BorderRadius.all(Radius.circular(30))),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(height: 15),
+ const Text(
+ 'Login',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 24,
+ fontWeight: FontWeight.bold),
+ ),
+ const SizedBox(height: 15),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ const Text(
+ "Email",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ SizedBox(
+ child: TextFormField(
+ decoration: InputDecoration(
+ labelText: 'Email',
+ labelStyle: TextStyle(color: Colors.white),
+ hintText: 'username@gmail.com',
+ hintStyle: TextStyle(color: Colors.grey),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: BorderSide(color: Colors.white),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: BorderSide(color: Colors.white),
+ ),
+ filled: true,
+ fillColor: Colors.white,
+ contentPadding: EdgeInsets.symmetric(
+ vertical: 16.0, horizontal: 12.0),
+ ),
+ style: TextStyle(color: Colors.black),
+ )),
+ ],
+ ),
+ const SizedBox(height: 15.0),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ const Text(
+ "Password",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ SizedBox(
+ child: TextFormField(
+ decoration: InputDecoration(
+ labelText: 'Password',
+ labelStyle: TextStyle(color: Colors.white),
+ hintText: 'Password',
+ hintStyle: TextStyle(color: Colors.grey),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: BorderSide(color: Colors.white),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: BorderSide(color: Colors.white),
+ ),
+ filled: true,
+ fillColor: Colors.white,
+ contentPadding: EdgeInsets.symmetric(
+ vertical: 16.0, horizontal: 12.0),
+ ),
+ style: TextStyle(color: Colors.black),
+ )),
+ const SizedBox(height: 20.0),
+ const Text(
+ "Forgot Password?",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ ],
+ ),
+ const SizedBox(height: 20.0),
+ ElevatedButton(
+ onPressed: () async {
+ // Trigger login event
+ loginBloc.add(
+ LoginButtonPressed(
+ username: _usernameController.text,
+ password: _passwordController.text,
+ ),
+ );
+ },
+ child: const Text('Login'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages/auth/view/login_page.dart b/lib/pages/auth/view/login_page.dart
index de451e50..d5644b5e 100644
--- a/lib/pages/auth/view/login_page.dart
+++ b/lib/pages/auth/view/login_page.dart
@@ -1,100 +1,18 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:syncrow_web/pages/auth/bloc/login_bloc.dart';
-import 'package:syncrow_web/pages/auth/bloc/login_event.dart';
-import 'package:syncrow_web/pages/auth/bloc/login_state.dart';
-import 'package:syncrow_web/pages/home/view/home_page.dart';
+import 'package:syncrow_web/pages/auth/view/login_mobile_page.dart';
+import 'package:syncrow_web/pages/auth/view/login_web_page.dart';
+import 'package:syncrow_web/utils/responsive_layout.dart';
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('Login'),
- ),
- body: BlocProvider(
- create: (context) => LoginBloc(),
- child: BlocConsumer(
- listener: (context, state) {
- if (state is LoginSuccess) {
- // Navigate to home screen after successful login
- Navigator.pushReplacement(
- context,
- MaterialPageRoute(builder: (context) => const HomePage()),
- );
- } else if (state is LoginFailure) {
- // Show error message
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text(state.error),
- ),
- );
- }
- },
- builder: (context, state) {
- if (state is LoginLoading) {
- return const Center(child: CircularProgressIndicator());
- } else {
- return _buildLoginForm(context);
- }
- },
- ),
- ),
- );
- }
-
- Widget _buildLoginForm(BuildContext context) {
- final loginBloc = BlocProvider.of(context);
- final TextEditingController _usernameController = TextEditingController();
- final TextEditingController _passwordController = TextEditingController();
-
- return Center(
- child: Padding(
- padding: const EdgeInsets.all(20.0),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- SizedBox(
- width: MediaQuery.sizeOf(context).width * 0.4,
- child: TextField(
- controller: _usernameController,
- decoration: const InputDecoration(
- labelText: 'Username',
- ),
- ),
- ),
- const SizedBox(height: 20.0),
- SizedBox(
- width: MediaQuery.sizeOf(context).width * 0.4,
- child: TextField(
- controller: _passwordController,
- obscureText: true,
- decoration: const InputDecoration(
- labelText: 'Password',
- ),
- ),
- ),
- const SizedBox(height: 20.0),
- ElevatedButton(
- onPressed: () async {
- // Trigger login event
- loginBloc.add(
- LoginButtonPressed(
- username: _usernameController.text,
- password: _passwordController.text,
- ),
- );
- },
- child: const Text('Login'),
- ),
- ],
- ),
- ),
+ return const ResponsiveLayout(
+ desktopBody: LoginWebPage(),
+ mobileBody:LoginMobilePage()
);
}
}
diff --git a/lib/pages/auth/view/login_web_page.dart b/lib/pages/auth/view/login_web_page.dart
new file mode 100644
index 00000000..e367f96a
--- /dev/null
+++ b/lib/pages/auth/view/login_web_page.dart
@@ -0,0 +1,230 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:syncrow_web/utils/assets.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_bloc.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_event.dart';
+import 'package:syncrow_web/pages/auth/bloc/login_state.dart';
+import 'package:syncrow_web/pages/home/view/home_page.dart';
+
+class LoginWebPage extends StatelessWidget {
+ const LoginWebPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ // appBar: AppBar(
+ // title: const Text('Login'),
+ // ),
+ body: BlocProvider(
+ create: (context) => LoginBloc(),
+ child: BlocConsumer(
+ listener: (context, state) {
+ if (state is LoginSuccess) {
+ // Navigate to home screen after successful login
+ Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(builder: (context) => const HomePage()),
+ );
+ } else if (state is LoginFailure) {
+ // Show error message
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text(state.error),
+ ),
+ );
+ }
+ },
+ builder: (context, state) {
+ if (state is LoginLoading) {
+ return const Center(child: CircularProgressIndicator());
+ } else {
+ return _buildLoginForm(context);
+ }
+ },
+ ),
+ ),
+ );
+ }
+
+ Widget _buildLoginForm(BuildContext context) {
+ final loginBloc = BlocProvider.of(context);
+ final TextEditingController _usernameController = TextEditingController();
+ final TextEditingController _passwordController = TextEditingController();
+ return Center(
+ child: Stack(
+ children: [
+ Container(
+ width: MediaQuery.sizeOf(context).width,
+ height: MediaQuery.sizeOf(context).height,
+ child: SvgPicture.asset(
+ Assets.webBackground,
+ fit: BoxFit.cover,
+ ),
+ ),
+ Container(
+ width: MediaQuery.sizeOf(context).width,
+ height: MediaQuery.sizeOf(context).height,
+ decoration: const BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(Assets.vector),
+ fit: BoxFit.cover,
+ opacity: 0.9,
+ ),
+ ),
+ ),
+ Container(
+ margin: const EdgeInsets.all(50),
+ decoration: BoxDecoration(
+ color: Colors.black.withOpacity(0.3),
+ borderRadius: const BorderRadius.all(Radius.circular(20)),
+ ),
+ child:Center(
+ child: ListView(
+ shrinkWrap: true,
+ children: [
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Spacer(),
+ Expanded(
+ flex: 2,
+ child: SvgPicture.asset(
+ Assets.loginLogo,
+ ),
+ ),
+ const Spacer(),
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.white.withOpacity(0.3),
+ borderRadius: const BorderRadius.all(Radius.circular(30)),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 20),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(height: 15),
+ const Text(
+ 'Login',
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 24,
+ fontWeight: FontWeight.bold),
+ ),
+ const SizedBox(height: 30),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ const Text(
+ "Email",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ SizedBox(
+ width: MediaQuery.sizeOf(context).width * 0.2,
+ child: TextFormField(
+ controller: _usernameController,
+ decoration: InputDecoration(
+ labelText: 'Email',
+ labelStyle: const TextStyle(color: Colors.white),
+ hintText: 'username@gmail.com',
+ hintStyle: const TextStyle(color: Colors.grey),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(color: Colors.white),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(color: Colors.white),
+ ),
+ filled: true,
+ fillColor: Colors.white,
+ contentPadding: const EdgeInsets.symmetric(
+ vertical: 16.0, horizontal: 12.0),
+ ),
+ style: const TextStyle(color: Colors.black),
+ ),
+ ),
+ ],
+ ),
+ const SizedBox(height: 20.0),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ const Text(
+ "Password",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ SizedBox(
+ width: MediaQuery.sizeOf(context).width * 0.2,
+ child: TextFormField(
+ controller: _passwordController,
+ decoration: InputDecoration(
+ labelText: 'Password',
+ labelStyle: const TextStyle(color: Colors.white),
+ hintText: 'Password',
+ hintStyle: const TextStyle(color: Colors.grey),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(color: Colors.white),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(color: Colors.white),
+ ),
+ filled: true,
+ fillColor: Colors.white,
+ contentPadding: const EdgeInsets.symmetric(
+ vertical: 16.0, horizontal: 12.0),
+ ),
+ style: const TextStyle(color: Colors.black),
+ ),
+ ),
+ const SizedBox(height: 20.0),
+ const Text(
+ "Forgot Password?",
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 13,
+ fontWeight: FontWeight.bold),
+ ),
+ ],
+ ),
+ const SizedBox(height: 20.0),
+ ElevatedButton(
+ onPressed: () async {
+ // Trigger login event
+ loginBloc.add(
+ LoginButtonPressed(
+ username: _usernameController.text,
+ password: _passwordController.text,
+ ),
+ );
+ },
+ child: const Text('Login'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ const Spacer(),
+ ],
+ ),
+ ],
+ )),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/pages/home/view/home_page.dart b/lib/pages/home/view/home_page.dart
index a28a4d0e..de8f0821 100644
--- a/lib/pages/home/view/home_page.dart
+++ b/lib/pages/home/view/home_page.dart
@@ -2,16 +2,29 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/home/bloc/home_bloc.dart';
import 'package:syncrow_web/pages/home/view/tree_page.dart';
+import 'package:syncrow_web/utils/style.dart';
+import 'package:syncrow_web/web_layout/web_scaffold.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
-
@override
Widget build(BuildContext context) {
- return Scaffold(
- body: BlocProvider(
- create: (context) => HomeBloc(),
- child: const TreeWidget(),
- ));
+ return WebScaffold(
+ appBarTitle: 'Space Management',
+ appBarBody:[
+ Text(
+ 'Community structure',
+ style: appBarTextStyle,
+ ),
+ Text(
+ 'Community ',
+ style: appBarTextStyle
+ ),
+ ],
+ scaffoldBody: BlocProvider(
+ create: (context) => HomeBloc(),
+ child: const TreeWidget(),
+ ),
+ );
}
}
diff --git a/lib/pages/home/view/tree_page.dart b/lib/pages/home/view/tree_page.dart
index 21033607..a213c84e 100644
--- a/lib/pages/home/view/tree_page.dart
+++ b/lib/pages/home/view/tree_page.dart
@@ -29,11 +29,11 @@ class TreeWidget extends StatelessWidget {
if (state is HomeInitial) {
return Wrap(
children: [
- Container(
+ SizedBox(
width: 100,
child: TextFormField(
decoration:
- InputDecoration(labelText: "Subtree separation"),
+ const InputDecoration(labelText: "Subtree separation"),
onChanged: (text) {
firstNodeName = text;
},
@@ -55,7 +55,6 @@ class TreeWidget extends StatelessWidget {
onPressed: () {
final node1 = Node.Id(firstNodeName);
final node2 = Node.Id(secondNodeName);
-
context.read().add(CreateNewNode(
sourceNode: node1, destinationNode: node2));
},
@@ -99,7 +98,6 @@ class TreeWidget extends StatelessWidget {
Widget rectangleWidget(String text, Node node, BuildContext blocContext) {
String nodeName = '';
-
return InkWell(
onTap: () {
showDialog(
@@ -145,6 +143,7 @@ Widget rectangleWidget(String text, Node node, BuildContext blocContext) {
BoxShadow(color: Colors.blue[100]!, spreadRadius: 1),
],
),
- child: Text(text)),
+ child: Text(text)
+ ),
);
}
diff --git a/lib/utils/assets.dart b/lib/utils/assets.dart
new file mode 100644
index 00000000..1e5e0d00
--- /dev/null
+++ b/lib/utils/assets.dart
@@ -0,0 +1,12 @@
+class Assets {
+ Assets._();
+ static const String background = "assets/images/Background.png";
+ static const String webBackground = "assets/images/web_Background.svg";
+ static const String blackLogo = "assets/images/black-logo.png";
+ static const String logo = "assets/images/Logo.svg";
+ static const String logoHorizontal = "assets/images/logo_horizontal.png";
+ static const String vector = "assets/images/Vector.png";
+ static const String loginLogo = "assets/images/login_logo.svg";
+ static const String whiteLogo = "assets/images/white-logo.png";
+ static const String window = "assets/images/Window.png";
+}
diff --git a/lib/utils/color_manager.dart b/lib/utils/color_manager.dart
new file mode 100644
index 00000000..36e5b0fc
--- /dev/null
+++ b/lib/utils/color_manager.dart
@@ -0,0 +1,30 @@
+import 'package:flutter/material.dart';
+
+abstract class ColorsManager {
+ static const Color textPrimaryColor = Color(0xFF5D5D5D);
+ static const Color switchOffColor = Color(0x7F8D99AE);
+ static const Color primaryColor = Color(0xFF0030CB);//023DFE
+ static const Color secondaryTextColor = Color(0xFF848484);
+ static Color primaryColorWithOpacity = const Color(0xFF023DFE).withOpacity(0.6);
+ static const Color whiteColors = Colors.white;
+ static const Color secondaryColor = Color(0xFF023DFE);
+ static const Color onSecondaryColor = Color(0xFF023DFE);
+
+ static const Color primaryTextColor = Colors.black;
+
+ static const Color greyColor = Color(0xFFd5d5d5);
+
+ static const Color backgroundColor = Color(0xFFececec);
+ static const Color dozeColor = Color(0xFFFEC258);
+ static const Color relaxColor = Color(0xFFFBD288);
+ static const Color readingColor = Color(0xFFF7D69C);
+ static const Color energizingColor = Color(0xFFEDEDED);
+ static const Color dividerColor = Color(0xFFEBEBEB);
+ static const Color slidingBlueColor = Color(0x99023DFE);
+ static const Color blackColor = Color(0xFF000000);
+ static const Color lightGreen = Color(0xFF00FF0A);
+ static const Color grayColor = Color(0xFF999999);
+ static const Color red = Colors.red;
+ static const Color graysColor = Color(0xffEBEBEB);
+ static const Color textGray = Color(0xffD5D5D5);
+}
diff --git a/lib/utils/responsive_layout.dart b/lib/utils/responsive_layout.dart
new file mode 100644
index 00000000..13b584ea
--- /dev/null
+++ b/lib/utils/responsive_layout.dart
@@ -0,0 +1,21 @@
+
+
+import 'package:flutter/material.dart';
+
+
+class ResponsiveLayout extends StatelessWidget {
+ final Widget desktopBody;
+ final Widget mobileBody;
+ const ResponsiveLayout({super.key,required this.desktopBody,required this.mobileBody});
+ @override
+ Widget build(BuildContext context) {
+ return LayoutBuilder(builder: (context, constraints) {
+ if(constraints.maxWidth<600){
+ return mobileBody;
+ }else{
+ return desktopBody;
+ }
+ },
+ );
+ }
+}
diff --git a/lib/utils/style.dart b/lib/utils/style.dart
new file mode 100644
index 00000000..677aac50
--- /dev/null
+++ b/lib/utils/style.dart
@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+
+import 'color_manager.dart';
+
+InputDecoration? textBoxDecoration = InputDecoration(
+ focusColor: ColorsManager.grayColor,
+ suffixIcon: const Icon(Icons.search),
+ hintText: 'Search',
+ filled: true, // Enable background filling
+ fillColor: Colors.grey.shade200, // Set the background color
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(15), // Add border radius
+ borderSide: BorderSide.none, // Remove the underline
+ ),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(15), // Add border radius
+ borderSide: BorderSide.none, // Remove the underline
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(15), // Add border radius
+ borderSide: BorderSide.none, // Remove the underline
+ ),
+);
+
+
+TextStyle appBarTextStyle =
+ const TextStyle(fontSize: 20, color: ColorsManager.whiteColors);
diff --git a/lib/web_layout/menu_sidebar.dart b/lib/web_layout/menu_sidebar.dart
new file mode 100644
index 00000000..f5af64d7
--- /dev/null
+++ b/lib/web_layout/menu_sidebar.dart
@@ -0,0 +1,56 @@
+
+
+import 'package:flutter/material.dart';
+import 'package:syncrow_web/utils/color_manager.dart';
+import 'package:syncrow_web/utils/style.dart';
+
+class MenuSidebar extends StatelessWidget {
+ const MenuSidebar({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Expanded(
+ child: Container(
+ decoration: const BoxDecoration(
+ shape: BoxShape.rectangle,
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black26,
+ offset: Offset(4, 0),
+ blurRadius: 10,
+ )
+ ],
+ color: ColorsManager.whiteColors,
+ ),
+ width: 200,
+ child: Padding(
+ padding: const EdgeInsets.all(15.0),
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ const Text('Community',style: TextStyle(fontSize: 20),),
+ CircleAvatar(
+ backgroundColor: Colors.grey.shade200,
+ child: IconButton(
+ color: ColorsManager.onSecondaryColor,
+ onPressed: () {},
+ icon: const Icon(Icons.add)
+ ),
+ )
+ ],
+ ),
+ const SizedBox(height: 20,),
+ TextFormField(
+ controller: TextEditingController(),
+ decoration:textBoxDecoration
+ ),
+ Container(height: 100,)
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/web_layout/web_app_bar.dart b/lib/web_layout/web_app_bar.dart
new file mode 100644
index 00000000..94773d73
--- /dev/null
+++ b/lib/web_layout/web_app_bar.dart
@@ -0,0 +1,63 @@
+import 'package:flutter/material.dart';
+import 'package:syncrow_web/utils/color_manager.dart';
+
+class WebAppBar extends StatelessWidget {
+ final String? title;
+ final List? body;
+ const WebAppBar({super.key,this.title,this.body});
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 120,
+ decoration: const BoxDecoration(color:ColorsManager.secondaryColor ),
+ padding: const EdgeInsets.all(10),
+ child: Expanded(
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Text(
+ title!,style: const TextStyle(
+ fontSize: 30,
+ color: Colors.white),)
+ ),
+ if (body != null)
+ Expanded(
+ flex: 2,
+ child: Wrap(
+ spacing: 15, // Adjust the spacing as needed
+ children: body!,
+ ),
+ ),
+ Row(
+ children: [
+ IconButton(onPressed: () {},
+ icon: const Icon(Icons.apps_sharp,color: Colors.white,)),
+ const SizedBox(width: 10,),
+ const SizedBox.square(
+ dimension: 40,
+ child: CircleAvatar(
+ backgroundColor: Colors.white,
+ child: SizedBox.square(
+ dimension: 35,
+ child: CircleAvatar(
+ backgroundColor: Colors.grey,
+ child: FlutterLogo(),
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 10,),
+ const Text('mohamamd alnemer ',style: TextStyle(fontSize: 16,color: Colors.white),),
+ ],
+ )
+ ],
+ ),
+ ) ,
+ );
+ }
+
+ // @override
+ // Size get preferredSize => Size.fromHeight(50.0);
+}
\ No newline at end of file
diff --git a/lib/web_layout/web_scaffold.dart b/lib/web_layout/web_scaffold.dart
new file mode 100644
index 00000000..8ea9f506
--- /dev/null
+++ b/lib/web_layout/web_scaffold.dart
@@ -0,0 +1,54 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:syncrow_web/utils/assets.dart';
+import 'package:syncrow_web/web_layout/web_app_bar.dart';
+import 'menu_sidebar.dart';
+
+class WebScaffold extends StatelessWidget {
+ final bool enableMenuSideba;
+ final String? appBarTitle;
+ final List? appBarBody;
+ final Widget? scaffoldBody;
+ const WebScaffold({super.key,this.appBarTitle,this.appBarBody,this.scaffoldBody,this.enableMenuSideba=true});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Stack(
+ children: [
+ SizedBox(
+ width: MediaQuery.sizeOf(context).width,
+ height: MediaQuery.sizeOf(context).height,
+ child: SvgPicture.asset(
+ Assets.webBackground,
+ fit: BoxFit.cover,
+ ),
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ Opacity(
+ opacity: 0.6,
+ child: WebAppBar(
+ title: appBarTitle,
+ body: appBarBody,
+ )
+ ),
+ Expanded(
+ child: Row(
+ children: [
+ if(enableMenuSideba)
+ const MenuSidebar(),
+ Expanded(
+ flex: 5,
+ child: scaffoldBody!
+ )
+ ],
+ ),
+ )
+ ],
+ ),
+ ],
+ ));
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
index 21eb45a3..863a9197 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.5.0"
async:
dependency: transitive
description:
@@ -94,6 +102,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.10+1"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -107,30 +123,46 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.2"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
- sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
+ sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
url: "https://pub.dev"
source: hosted
- version: "10.0.0"
+ version: "10.0.4"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
- sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
+ sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "3.0.3"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
- sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "3.0.1"
lints:
dependency: transitive
description:
@@ -159,10 +191,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
url: "https://pub.dev"
source: hosted
- version: "1.11.0"
+ version: "1.12.0"
nested:
dependency: transitive
description:
@@ -179,6 +211,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.0"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.2"
provider:
dependency: transitive
description:
@@ -236,10 +284,42 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.7.0"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.2"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
vector_math:
dependency: transitive
description:
@@ -252,10 +332,26 @@ packages:
dependency: transitive
description:
name: vm_service
- sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+ sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
url: "https://pub.dev"
source: hosted
- version: "13.0.0"
+ version: "14.2.1"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.5.0"
sdks:
- dart: ">=3.3.1 <4.0.0"
- flutter: ">=1.17.0"
+ dart: ">=3.4.0 <4.0.0"
+ flutter: ">=3.18.0-18.0.pre.54"
diff --git a/pubspec.yaml b/pubspec.yaml
index 2dc3fdbc..5b17566f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -38,7 +38,8 @@ dependencies:
flutter_bloc: ^8.1.5
equatable: ^2.0.5
graphview: ^1.2.0
-
+ flutter_svg: ^2.0.10+1
+
dev_dependencies:
flutter_test:
@@ -63,9 +64,9 @@ flutter:
uses-material-design: true
# To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
+ assets:
+ - assets/images/
+
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware