224 lines
8.0 KiB
Dart
224 lines
8.0 KiB
Dart
import 'package:autos/core/widgets/wave_background.dart';
|
|
import 'package:autos/presentation/providers/user_provider.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
|
|
class SignUpScreen extends ConsumerStatefulWidget {
|
|
const SignUpScreen({super.key});
|
|
|
|
@override
|
|
ConsumerState<SignUpScreen> createState() => _SignUpScreenState();
|
|
}
|
|
|
|
class _SignUpScreenState extends ConsumerState<SignUpScreen> {
|
|
final nameController = TextEditingController(text: "");
|
|
final emailController = TextEditingController(text: "");
|
|
final passwordController = TextEditingController(text: "");
|
|
final phoneController = TextEditingController(text: "");
|
|
bool isPasswordVisible = false;
|
|
|
|
@override
|
|
void dispose() {
|
|
nameController.dispose();
|
|
emailController.dispose();
|
|
passwordController.dispose();
|
|
phoneController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final userState = ref.watch(signupProvider);
|
|
|
|
final size = MediaQuery.of(context).size;
|
|
final double verticalSpace = size.height * 0.02;
|
|
final double horizontalPadding =
|
|
size.width * 0.06; // dynamic horizontal padding
|
|
|
|
ref.listen(signupProvider, (previous, next) {
|
|
if (next.hasValue && next.value != null) {
|
|
Fluttertoast.showToast(
|
|
msg: "Sign up successful! Please log in.",
|
|
toastLength: Toast.LENGTH_SHORT,
|
|
gravity: ToastGravity.BOTTOM,
|
|
backgroundColor: Colors.green,
|
|
textColor: Colors.white,
|
|
fontSize: 16.0,
|
|
);
|
|
Navigator.pop(context);
|
|
}
|
|
|
|
if (next.hasError) {
|
|
Fluttertoast.showToast(
|
|
msg: "⚠️ Sign up failed: ${next.error}",
|
|
toastLength: Toast.LENGTH_LONG,
|
|
gravity: ToastGravity.BOTTOM,
|
|
backgroundColor: Colors.red,
|
|
textColor: Colors.white,
|
|
fontSize: 16.0,
|
|
);
|
|
}
|
|
});
|
|
|
|
return Scaffold(
|
|
resizeToAvoidBottomInset: true,
|
|
body: WaveBackground(
|
|
child: Padding(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: horizontalPadding,
|
|
vertical: verticalSpace,
|
|
),
|
|
child: Center(
|
|
child: SingleChildScrollView(
|
|
child: ConstrainedBox(
|
|
constraints: BoxConstraints(
|
|
maxWidth: size.width < 500
|
|
? size.width
|
|
: 450, // better center layout on tablets
|
|
),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
SizedBox(height: size.height * 0.07),
|
|
|
|
/// Logo
|
|
Image.asset(
|
|
'assets/auth/autos_transp.png',
|
|
height: size.height * 0.14,
|
|
),
|
|
Row(
|
|
children: const [
|
|
Text(
|
|
"Sign Up",
|
|
style: TextStyle(
|
|
fontSize: 32,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
Spacer(),
|
|
],
|
|
),
|
|
SizedBox(height: verticalSpace),
|
|
|
|
/// Name field
|
|
TextField(
|
|
controller: nameController,
|
|
decoration: const InputDecoration(
|
|
hintText: "Enter Name",
|
|
prefixIcon: Icon(Icons.person_outline),
|
|
),
|
|
),
|
|
SizedBox(height: verticalSpace),
|
|
|
|
/// Email field
|
|
TextField(
|
|
controller: emailController,
|
|
decoration: const InputDecoration(
|
|
hintText: "Enter Email",
|
|
prefixIcon: Icon(Icons.email_outlined),
|
|
),
|
|
),
|
|
SizedBox(height: verticalSpace),
|
|
|
|
/// Password field
|
|
TextField(
|
|
controller: passwordController,
|
|
obscureText: !isPasswordVisible,
|
|
decoration: InputDecoration(
|
|
hintText: "Enter Password",
|
|
prefixIcon: const Icon(Icons.lock_outline),
|
|
suffixIcon: IconButton(
|
|
onPressed: () {
|
|
setState(() {
|
|
isPasswordVisible = !isPasswordVisible;
|
|
});
|
|
},
|
|
icon: Icon(
|
|
isPasswordVisible
|
|
? Icons.visibility
|
|
: Icons.visibility_off,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: verticalSpace),
|
|
|
|
/// Phone field
|
|
TextField(
|
|
controller: phoneController,
|
|
keyboardType: TextInputType.phone,
|
|
decoration: const InputDecoration(
|
|
hintText: "Enter Phone Number",
|
|
prefixIcon: Icon(Icons.phone_outlined),
|
|
),
|
|
),
|
|
SizedBox(height: verticalSpace * 2),
|
|
|
|
/// Sign Up button
|
|
userState.isLoading
|
|
? const CircularProgressIndicator()
|
|
: ElevatedButton(
|
|
onPressed: () async {
|
|
await ref
|
|
.read(signupProvider.notifier)
|
|
.signup(
|
|
nameController.text,
|
|
emailController.text,
|
|
passwordController.text,
|
|
phoneController.text,
|
|
);
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFF3B81F9),
|
|
minimumSize: Size(
|
|
double.infinity,
|
|
size.height * 0.05,
|
|
),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(40),
|
|
),
|
|
),
|
|
child: const Text(
|
|
"Sign Up",
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
|
|
SizedBox(height: verticalSpace * 2.5),
|
|
|
|
/// Already have account text
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
const Text("Already have an account? "),
|
|
TextButton(
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
},
|
|
child: const Text(
|
|
"Sign In",
|
|
style: TextStyle(
|
|
color: Color(0xFF3B81F9),
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: verticalSpace),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|