Line data Source code
1 : import 'package:flutter/material.dart';
2 : import 'package:provider/provider.dart';
3 : import '../../services/auth_service.dart';
4 :
5 : class RegisterScreen extends StatefulWidget {
6 24 : const RegisterScreen({super.key});
7 :
8 0 : @override
9 0 : State<RegisterScreen> createState() => _RegisterScreenState();
10 : }
11 :
12 : class _RegisterScreenState extends State<RegisterScreen> {
13 : final _formKey = GlobalKey<FormState>();
14 : final _nameController = TextEditingController();
15 : final _emailController = TextEditingController();
16 : final _passwordController = TextEditingController();
17 : final _confirmPasswordController = TextEditingController();
18 : bool _isPasswordVisible = false;
19 : bool _isConfirmPasswordVisible = false;
20 :
21 0 : @override
22 : void dispose() {
23 0 : _nameController.dispose();
24 0 : _emailController.dispose();
25 0 : _passwordController.dispose();
26 0 : _confirmPasswordController.dispose();
27 0 : super.dispose();
28 : }
29 :
30 : // 회원가입 처리 함수
31 0 : Future<void> _register() async {
32 0 : if (_formKey.currentState!.validate()) {
33 0 : final authService = Provider.of<AuthService>(context, listen: false);
34 0 : final success = await authService.register(
35 0 : _nameController.text.trim(),
36 0 : _emailController.text.trim(),
37 0 : _passwordController.text,
38 : );
39 :
40 0 : if (success && mounted) {
41 0 : ScaffoldMessenger.of(context).showSnackBar(
42 : const SnackBar(
43 : content: Text('회원가입이 완료되었습니다. 로그인해주세요.'),
44 : backgroundColor: Colors.green,
45 : ),
46 : );
47 0 : Navigator.pop(context); // 로그인 화면으로 돌아가기
48 0 : } else if (mounted) {
49 0 : ScaffoldMessenger.of(context).showSnackBar(
50 : const SnackBar(
51 : content: Text('회원가입에 실패했습니다. 다시 시도해주세요.'),
52 : backgroundColor: Colors.red,
53 : ),
54 : );
55 : }
56 : }
57 : }
58 :
59 0 : @override
60 : Widget build(BuildContext context) {
61 0 : final authService = Provider.of<AuthService>(context);
62 :
63 0 : return Scaffold(
64 0 : appBar: AppBar(
65 : title: const Text('회원가입'),
66 : ),
67 0 : body: SafeArea(
68 0 : child: Center(
69 0 : child: SingleChildScrollView(
70 : padding: const EdgeInsets.all(24.0),
71 0 : child: Form(
72 0 : key: _formKey,
73 0 : child: Column(
74 : mainAxisAlignment: MainAxisAlignment.center,
75 : crossAxisAlignment: CrossAxisAlignment.stretch,
76 0 : children: [
77 : // 이름 입력 필드
78 0 : TextFormField(
79 0 : controller: _nameController,
80 : decoration: const InputDecoration(
81 : labelText: '이름',
82 : prefixIcon: Icon(Icons.person),
83 : border: OutlineInputBorder(),
84 : ),
85 0 : validator: (value) {
86 0 : if (value == null || value.isEmpty) {
87 : return '이름을 입력해주세요';
88 : }
89 : return null;
90 : },
91 : ),
92 : const SizedBox(height: 16),
93 :
94 : // 이메일 입력 필드
95 0 : TextFormField(
96 0 : controller: _emailController,
97 : keyboardType: TextInputType.emailAddress,
98 : decoration: const InputDecoration(
99 : labelText: '이메일',
100 : prefixIcon: Icon(Icons.email),
101 : border: OutlineInputBorder(),
102 : ),
103 0 : validator: (value) {
104 0 : if (value == null || value.isEmpty) {
105 : return '이메일을 입력해주세요';
106 : }
107 0 : if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
108 : return '유효한 이메일 주소를 입력해주세요';
109 : }
110 : return null;
111 : },
112 : ),
113 : const SizedBox(height: 16),
114 :
115 : // 비밀번호 입력 필드
116 0 : TextFormField(
117 0 : controller: _passwordController,
118 0 : obscureText: !_isPasswordVisible,
119 0 : decoration: InputDecoration(
120 : labelText: '비밀번호',
121 : prefixIcon: const Icon(Icons.lock),
122 : border: const OutlineInputBorder(),
123 0 : suffixIcon: IconButton(
124 0 : icon: Icon(
125 0 : _isPasswordVisible ? Icons.visibility : Icons.visibility_off,
126 : ),
127 0 : onPressed: () {
128 0 : setState(() {
129 0 : _isPasswordVisible = !_isPasswordVisible;
130 : });
131 : },
132 : ),
133 : ),
134 0 : validator: (value) {
135 0 : if (value == null || value.isEmpty) {
136 : return '비밀번호를 입력해주세요';
137 : }
138 0 : if (value.length < 6) {
139 : return '비밀번호는 6자 이상이어야 합니다';
140 : }
141 : return null;
142 : },
143 : ),
144 : const SizedBox(height: 16),
145 :
146 : // 비밀번호 확인 입력 필드
147 0 : TextFormField(
148 0 : controller: _confirmPasswordController,
149 0 : obscureText: !_isConfirmPasswordVisible,
150 0 : decoration: InputDecoration(
151 : labelText: '비밀번호 확인',
152 : prefixIcon: const Icon(Icons.lock_outline),
153 : border: const OutlineInputBorder(),
154 0 : suffixIcon: IconButton(
155 0 : icon: Icon(
156 0 : _isConfirmPasswordVisible ? Icons.visibility : Icons.visibility_off,
157 : ),
158 0 : onPressed: () {
159 0 : setState(() {
160 0 : _isConfirmPasswordVisible = !_isConfirmPasswordVisible;
161 : });
162 : },
163 : ),
164 : ),
165 0 : validator: (value) {
166 0 : if (value == null || value.isEmpty) {
167 : return '비밀번호를 다시 입력해주세요';
168 : }
169 0 : if (value != _passwordController.text) {
170 : return '비밀번호가 일치하지 않습니다';
171 : }
172 : return null;
173 : },
174 : ),
175 : const SizedBox(height: 24),
176 :
177 : // 회원가입 버튼
178 0 : ElevatedButton(
179 0 : onPressed: authService.isLoading ? null : _register,
180 0 : style: ElevatedButton.styleFrom(
181 : padding: const EdgeInsets.symmetric(vertical: 16),
182 : backgroundColor: Colors.blue,
183 : foregroundColor: Colors.white,
184 : ),
185 0 : child: authService.isLoading
186 : ? const SizedBox(
187 : width: 20,
188 : height: 20,
189 : child: CircularProgressIndicator(
190 : strokeWidth: 2,
191 : color: Colors.white,
192 : ),
193 : )
194 : : const Text(
195 : '회원가입',
196 : style: TextStyle(fontSize: 16),
197 : ),
198 : ),
199 : const SizedBox(height: 16),
200 :
201 : // 로그인 화면으로 돌아가기
202 0 : Row(
203 : mainAxisAlignment: MainAxisAlignment.center,
204 0 : children: [
205 : const Text('이미 계정이 있으신가요?'),
206 0 : TextButton(
207 0 : onPressed: () {
208 0 : Navigator.pop(context); // 로그인 화면으로 돌아가기
209 : },
210 : child: const Text('로그인'),
211 : ),
212 : ],
213 : ),
214 : ],
215 : ),
216 : ),
217 : ),
218 : ),
219 : ),
220 : );
221 : }
222 : }
|