From ebfd60f81ad239975b9d50e77a714234f6e4487f Mon Sep 17 00:00:00 2001 From: chan Date: Mon, 19 Jan 2026 11:16:01 +0900 Subject: [PATCH] =?UTF-8?q?input=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?,=20=ED=95=9C=EA=B8=80=20=EB=B2=88=EC=97=AD=20=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/presentation/login_screen.dart | 293 +++++++++--------- 1 file changed, 154 insertions(+), 139 deletions(-) diff --git a/frontend/lib/features/auth/presentation/login_screen.dart b/frontend/lib/features/auth/presentation/login_screen.dart index 5fb49e47..01ccb57e 100644 --- a/frontend/lib/features/auth/presentation/login_screen.dart +++ b/frontend/lib/features/auth/presentation/login_screen.dart @@ -432,152 +432,167 @@ class _LoginScreenState extends ConsumerState @override Widget build(BuildContext context) { return Scaffold( - body: Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 400), - padding: const EdgeInsets.all(24), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text( - "Baron SSO", - style: GoogleFonts.outfit( - fontSize: 32, - fontWeight: FontWeight.bold, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 40), - - TabBar( - controller: _tabController, - tabs: const [ - Tab(text: "Email"), - Tab(text: "Phone (SMS)"), - Tab(text: "QR"), - ], - ), - const SizedBox(height: 24), - - SizedBox( - height: 350, - child: TabBarView( - controller: _tabController, - children: [ - // Email Form - Column( - children: [ - TextField( - controller: _emailController, - decoration: const InputDecoration( - labelText: "Email", - border: OutlineInputBorder(), - prefixIcon: Icon(Icons.email_outlined), - ), + body: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: constraints.maxHeight), + child: Center( + child: Container( + constraints: const BoxConstraints(maxWidth: 400), + padding: const EdgeInsets.all(24), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + "Baron SSO", + style: GoogleFonts.outfit( + fontSize: 32, + fontWeight: FontWeight.bold, ), - const SizedBox(height: 16), - TextField( - controller: _passwordController, - obscureText: true, - decoration: const InputDecoration( - labelText: "Password (Optional)", - border: OutlineInputBorder(), - prefixIcon: Icon(Icons.lock_outline), - ), - ), - const SizedBox(height: 24), - FilledButton( - onPressed: _handleEmailLogin, - style: FilledButton.styleFrom( - minimumSize: const Size.fromHeight(50), - ), - child: const Text("Sign In / Send Link"), - ), - ], - ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 40), - // Phone Form - Column( - children: [ - TextField( - controller: _phoneController, - decoration: const InputDecoration( - labelText: "Phone Number", - hintText: "010-1234-5678", - border: OutlineInputBorder(), - prefixIcon: Icon(Icons.phone_android), + TabBar( + controller: _tabController, + tabs: const [ + Tab(text: "이메일"), + Tab(text: "전화번호"), + Tab(text: "QR 코드"), + ], + ), + const SizedBox(height: 24), + + SizedBox( + height: 350, + child: TabBarView( + controller: _tabController, + children: [ + // Email Form + Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Column( + children: [ + TextField( + controller: _emailController, + decoration: const InputDecoration( + labelText: "이메일", + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.email_outlined), + ), + ), + const SizedBox(height: 16), + TextField( + controller: _passwordController, + obscureText: true, + decoration: const InputDecoration( + labelText: "비밀번호 (선택)", + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.lock_outline), + ), + ), + const SizedBox(height: 24), + FilledButton( + onPressed: _handleEmailLogin, + style: FilledButton.styleFrom( + minimumSize: const Size.fromHeight(50), + ), + child: const Text("로그인 / 링크 전송"), + ), + ], + ), ), - ), - const SizedBox(height: 24), - FilledButton( - onPressed: _handleSmsLogin, - style: FilledButton.styleFrom( - minimumSize: const Size.fromHeight(50), - ), - child: const Text("Send Login Link"), - ), - const SizedBox(height: 16), - const Text( - "We will send a login link to your phone via SMS.", - style: TextStyle(color: Colors.grey, fontSize: 12), - textAlign: TextAlign.center, - ), - ], - ), - // QR Login View - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (_isQrLoading) - const CircularProgressIndicator() - else if (_qrImageBase64 != null) - Column( - children: [ - Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(12), - ), - child: QrImageView( - data: _qrImageBase64!, - version: QrVersions.auto, - size: 200.0, - ), + // Phone Form + Padding( + padding: const EdgeInsets.only(top: 16.0), + child: Column( + children: [ + TextField( + controller: _phoneController, + decoration: const InputDecoration( + labelText: "휴대폰 번호", + hintText: "010-1234-5678", + border: OutlineInputBorder(), + prefixIcon: Icon(Icons.phone_android), + ), + ), + const SizedBox(height: 24), + FilledButton( + onPressed: _handleSmsLogin, + style: FilledButton.styleFrom( + minimumSize: const Size.fromHeight(50), + ), + child: const Text("로그인 링크 전송"), + ), + const SizedBox(height: 16), + const Text( + "입력하신 번호로 로그인 링크를 문자로 보내드립니다.", + style: TextStyle(color: Colors.grey, fontSize: 12), + textAlign: TextAlign.center, + ), + ], ), - const SizedBox(height: 12), - Text( - _qrRemainingSeconds > 0 - ? "Remaining Time: ${_formatTime(_qrRemainingSeconds)}" - : "QR Code Expired", - style: TextStyle( - color: _qrRemainingSeconds > 30 ? Colors.blue : Colors.red, - fontWeight: FontWeight.bold, - ), - ), - const SizedBox(height: 8), - const Text( - "Scan with your mobile app", - style: TextStyle(color: Colors.grey, fontSize: 12), - ), - TextButton( - onPressed: _startQrFlow, - child: const Text("Refresh QR") - ), - ], - ) - else - const Text("Failed to load QR code."), - ], - ), - ], + ), + + // QR Login View + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_isQrLoading) + const CircularProgressIndicator() + else if (_qrImageBase64 != null) + Column( + children: [ + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(12), + ), + child: QrImageView( + data: _qrImageBase64!, + version: QrVersions.auto, + size: 200.0, + ), + ), + const SizedBox(height: 12), + Text( + _qrRemainingSeconds > 0 + ? "남은 시간: ${_formatTime(_qrRemainingSeconds)}" + : "QR 코드 만료됨", + style: TextStyle( + color: _qrRemainingSeconds > 30 ? Colors.blue : Colors.red, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + const Text( + "모바일 앱으로 스캔하세요", + style: TextStyle(color: Colors.grey, fontSize: 12), + ), + TextButton( + onPressed: _startQrFlow, + child: const Text("QR 코드 새로고침") + ), + ], + ) + else + const Text("QR 코드를 불러오지 못했습니다."), + ], + ), + ], + ), + ), + ], + ), ), ), - ], - ), - ), + ), + ); + }, ), ); }