forked from baron/baron-sso
input 레이아웃 , 한글 번역 수정
This commit is contained in:
@@ -432,152 +432,167 @@ class _LoginScreenState extends ConsumerState<LoginScreen>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Center(
|
body: LayoutBuilder(
|
||||||
child: Container(
|
builder: (context, constraints) {
|
||||||
constraints: const BoxConstraints(maxWidth: 400),
|
return SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(24),
|
child: ConstrainedBox(
|
||||||
child: Column(
|
constraints: BoxConstraints(minHeight: constraints.maxHeight),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Center(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
child: Container(
|
||||||
children: [
|
constraints: const BoxConstraints(maxWidth: 400),
|
||||||
Text(
|
padding: const EdgeInsets.all(24),
|
||||||
"Baron SSO",
|
child: Column(
|
||||||
style: GoogleFonts.outfit(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
fontSize: 32,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
fontWeight: FontWeight.bold,
|
children: [
|
||||||
),
|
Text(
|
||||||
textAlign: TextAlign.center,
|
"Baron SSO",
|
||||||
),
|
style: GoogleFonts.outfit(
|
||||||
const SizedBox(height: 40),
|
fontSize: 32,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
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),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
textAlign: TextAlign.center,
|
||||||
TextField(
|
),
|
||||||
controller: _passwordController,
|
const SizedBox(height: 40),
|
||||||
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"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
// Phone Form
|
TabBar(
|
||||||
Column(
|
controller: _tabController,
|
||||||
children: [
|
tabs: const [
|
||||||
TextField(
|
Tab(text: "이메일"),
|
||||||
controller: _phoneController,
|
Tab(text: "전화번호"),
|
||||||
decoration: const InputDecoration(
|
Tab(text: "QR 코드"),
|
||||||
labelText: "Phone Number",
|
],
|
||||||
hintText: "010-1234-5678",
|
),
|
||||||
border: OutlineInputBorder(),
|
const SizedBox(height: 24),
|
||||||
prefixIcon: Icon(Icons.phone_android),
|
|
||||||
|
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
|
// Phone Form
|
||||||
Column(
|
Padding(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
padding: const EdgeInsets.only(top: 16.0),
|
||||||
children: [
|
child: Column(
|
||||||
if (_isQrLoading)
|
children: [
|
||||||
const CircularProgressIndicator()
|
TextField(
|
||||||
else if (_qrImageBase64 != null)
|
controller: _phoneController,
|
||||||
Column(
|
decoration: const InputDecoration(
|
||||||
children: [
|
labelText: "휴대폰 번호",
|
||||||
Container(
|
hintText: "010-1234-5678",
|
||||||
padding: const EdgeInsets.all(16),
|
border: OutlineInputBorder(),
|
||||||
decoration: BoxDecoration(
|
prefixIcon: Icon(Icons.phone_android),
|
||||||
border: Border.all(color: Colors.grey.shade300),
|
),
|
||||||
borderRadius: BorderRadius.circular(12),
|
),
|
||||||
),
|
const SizedBox(height: 24),
|
||||||
child: QrImageView(
|
FilledButton(
|
||||||
data: _qrImageBase64!,
|
onPressed: _handleSmsLogin,
|
||||||
version: QrVersions.auto,
|
style: FilledButton.styleFrom(
|
||||||
size: 200.0,
|
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
|
// QR Login View
|
||||||
? "Remaining Time: ${_formatTime(_qrRemainingSeconds)}"
|
Column(
|
||||||
: "QR Code Expired",
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
style: TextStyle(
|
children: [
|
||||||
color: _qrRemainingSeconds > 30 ? Colors.blue : Colors.red,
|
if (_isQrLoading)
|
||||||
fontWeight: FontWeight.bold,
|
const CircularProgressIndicator()
|
||||||
),
|
else if (_qrImageBase64 != null)
|
||||||
),
|
Column(
|
||||||
const SizedBox(height: 8),
|
children: [
|
||||||
const Text(
|
Container(
|
||||||
"Scan with your mobile app",
|
padding: const EdgeInsets.all(16),
|
||||||
style: TextStyle(color: Colors.grey, fontSize: 12),
|
decoration: BoxDecoration(
|
||||||
),
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
TextButton(
|
borderRadius: BorderRadius.circular(12),
|
||||||
onPressed: _startQrFlow,
|
),
|
||||||
child: const Text("Refresh QR")
|
child: QrImageView(
|
||||||
),
|
data: _qrImageBase64!,
|
||||||
],
|
version: QrVersions.auto,
|
||||||
)
|
size: 200.0,
|
||||||
else
|
),
|
||||||
const Text("Failed to load QR code."),
|
),
|
||||||
],
|
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 코드를 불러오지 못했습니다."),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
);
|
||||||
),
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user