import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class TambahUser extends StatefulWidget { final String role; const TambahUser({ super.key, required this.role, }); @override State createState() => _TambahUserState(); } class _TambahUserState extends State { final nama = TextEditingController(); final email = TextEditingController(); final password = TextEditingController(); bool isLoading = false; bool hidePassword = true; Future simpan() async { setState(() => isLoading = true); try { final userCred = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email.text.trim(), password: password.text.trim(), ); await FirebaseFirestore.instance .collection('users') .doc(userCred.user!.uid) .set({ 'nama': nama.text.trim(), 'role': widget.role, 'dibuat_pada': FieldValue.serverTimestamp(), }); await FirebaseAuth.instance.signOut(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Pengguna berhasil dibuat'), behavior: SnackBarBehavior.floating, shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))), ), ); Navigator.pop(context); } } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Gagal membuat pengguna: ${e.toString()}'), behavior: SnackBarBehavior.floating, shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))), ), ); } } if (mounted) setState(() => isLoading = false); } Widget input( TextEditingController controller, String label, IconData icon, { bool pass = false, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: const TextStyle( fontSize: 15, color: Color(0xff2D2669), fontWeight: FontWeight.w600, ), ), const SizedBox(height: 10), Row( children: [ Container( width: 52, height: 52, decoration: BoxDecoration( color: const Color(0xffF0EBFF), borderRadius: BorderRadius.circular(14), ), child: Icon( icon, color: const Color(0xff7F56D9), size: 24, ), ), const SizedBox(width: 12), Expanded( child: SizedBox( height: 52, child: TextField( controller: controller, obscureText: pass ? hidePassword : false, style: const TextStyle(fontSize: 14, color: Color(0xff2D2669)), decoration: InputDecoration( filled: true, fillColor: Colors.white, contentPadding: const EdgeInsets.symmetric(horizontal: 16), border: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: Color(0xffD1D5DB)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: Color(0xffD1D5DB)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(14), borderSide: const BorderSide(color: Color(0xff7F56D9), width: 1.5), ), suffixIcon: pass ? IconButton( icon: Icon( hidePassword ? Icons.visibility_outlined : Icons.visibility_off_outlined, color: const Color(0xff7F56D9), size: 20, ), onPressed: () { setState(() { hidePassword = !hidePassword; }); }, ) : null, ), ), ), ), ], ), ], ); } @override void dispose() { nama.dispose(); email.dispose(); password.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final isGuru = widget.role == 'guru'; final judul = isGuru ? 'Tambah Guru' : 'Tambah Orang Tua'; return Scaffold( backgroundColor: const Color(0xffF5F2FF), body: SafeArea( child: Stack( children: [ // ✅ HEADER SESUAI GAYA UNGU Positioned( top: 0, left: 0, right: 0, child: Container( height: 200, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xffEDE9FF), Color(0xffDCD4FF), Color(0xffCBBEFF), ], ), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(60), bottomRight: Radius.circular(60), ), ), ), ), // Pola titik hiasan Positioned( top: 40, right: 30, child: Column( children: List.generate(3, (_) => Row( children: List.generate(3, (_) => Container( width: 3, height: 3, margin: const EdgeInsets.all(2), decoration: BoxDecoration( color: const Color(0xff7F56D9).withOpacity(0.25), shape: BoxShape.circle, ), )), )), ), ), SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), child: Column( children: [ // Tombol Kembali Align( alignment: Alignment.centerLeft, child: Container( width: 44, height: 44, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: const [BoxShadow(color: Color(0x12000000), blurRadius: 8)], ), child: IconButton( padding: EdgeInsets.zero, icon: const Icon( Icons.arrow_back_ios_new, color: Color(0xff7F56D9), size: 20, ), onPressed: () => Navigator.pop(context), ), ), ), const SizedBox(height: 24), // Judul Halaman Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'lib/assets/sekolah.png', height: 70, fit: BoxFit.contain, errorBuilder: (_, __, ___) => const Icon( Icons.school, size: 60, color: Color(0xff7F56D9), ), ), const SizedBox(width: 16), Container( width: 1.5, height: 60, color: const Color(0xff7F56D9).withOpacity(0.3), ), const SizedBox(width: 16), Text( judul, style: const TextStyle( fontSize: 26, fontWeight: FontWeight.bold, color: Color(0xff2D2669), ), ), ], ), const SizedBox(height: 40), // ✅ FORM KARTU Container( width: double.infinity, padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(24), boxShadow: const [ BoxShadow( color: Color(0x10000000), blurRadius: 16, offset: Offset(0, 4), ) ], ), child: Column( children: [ input( nama, 'Nama Lengkap', Icons.person_outline_rounded, ), const SizedBox(height: 24), input( email, 'Alamat Email', Icons.email_outlined, ), const SizedBox(height: 24), input( password, 'Kata Sandi', Icons.lock_outline_rounded, pass: true, ), ], ), ), const SizedBox(height: 30), // ✅ TOMBOL SIMPAN SizedBox( width: double.infinity, height: 52, child: ElevatedButton( onPressed: isLoading ? null : simpan, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xff7F56D9), foregroundColor: Colors.white, elevation: 3, shadowColor: const Color(0xff7F56D9).withOpacity(0.3), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ if (isLoading) const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) else const Icon(Icons.save_rounded, size: 20), const SizedBox(width: 10), Text( isLoading ? 'Menyimpan...' : 'Simpan Data', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ], ), ), ), const SizedBox(height: 40), ], ), ), ], ), ), ); } }