반려동물 등록 페이지 ui / 반응형
12
app/assets/icons/calendaricon.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1_12643)">
|
||||||
|
<circle cx="10" cy="10" r="10" fill="#FF7500"/>
|
||||||
|
<path d="M11.0585 15.1849H8.92441C6.91251 15.1849 5.90629 15.1849 5.28154 14.5596C4.65678 13.9343 4.65625 12.9286 4.65625 10.9167V9.84969C4.65625 7.83779 4.65625 6.83157 5.28154 6.20682C5.90682 5.58206 6.91251 5.58153 8.92441 5.58153H11.0585C13.0704 5.58153 14.0766 5.58153 14.7014 6.20682C15.3261 6.8321 15.3267 7.83779 15.3267 9.84969V10.9167C15.3267 12.9286 15.3267 13.9349 14.7014 14.5596C14.353 14.9085 13.8862 15.0627 13.1926 15.1305M7.32385 5.58153V4.78125M12.6591 5.58153V4.78125M15.0599 8.24913H9.32455M4.65625 8.24913H6.72364" stroke="white" stroke-width="1.3" stroke-linecap="round"/>
|
||||||
|
<path d="M13.1913 12.5114C13.1913 12.6529 13.1351 12.7886 13.035 12.8886C12.935 12.9887 12.7993 13.0449 12.6578 13.0449C12.5163 13.0449 12.3806 12.9887 12.2805 12.8886C12.1805 12.7886 12.1243 12.6529 12.1243 12.5114C12.1243 12.3699 12.1805 12.2341 12.2805 12.1341C12.3806 12.034 12.5163 11.9778 12.6578 11.9778C12.7993 11.9778 12.935 12.034 13.035 12.1341C13.1351 12.2341 13.1913 12.3699 13.1913 12.5114ZM13.1913 10.3773C13.1913 10.5188 13.1351 10.6545 13.035 10.7545C12.935 10.8546 12.7993 10.9108 12.6578 10.9108C12.5163 10.9108 12.3806 10.8546 12.2805 10.7545C12.1805 10.6545 12.1243 10.5188 12.1243 10.3773C12.1243 10.2358 12.1805 10.1001 12.2805 10C12.3806 9.89996 12.5163 9.84375 12.6578 9.84375C12.7993 9.84375 12.935 9.89996 13.035 10C13.1351 10.1001 13.1913 10.2358 13.1913 10.3773ZM10.5237 12.5114C10.5237 12.6529 10.4675 12.7886 10.3674 12.8886C10.2674 12.9887 10.1317 13.0449 9.99018 13.0449C9.84869 13.0449 9.71298 12.9887 9.61293 12.8886C9.51287 12.7886 9.45666 12.6529 9.45666 12.5114C9.45666 12.3699 9.51287 12.2341 9.61293 12.1341C9.71298 12.034 9.84869 11.9778 9.99018 11.9778C10.1317 11.9778 10.2674 12.034 10.3674 12.1341C10.4675 12.2341 10.5237 12.3699 10.5237 12.5114ZM10.5237 10.3773C10.5237 10.5188 10.4675 10.6545 10.3674 10.7545C10.2674 10.8546 10.1317 10.9108 9.99018 10.9108C9.84869 10.9108 9.71298 10.8546 9.61293 10.7545C9.51287 10.6545 9.45666 10.5188 9.45666 10.3773C9.45666 10.2358 9.51287 10.1001 9.61293 10C9.71298 9.89996 9.84869 9.84375 9.99018 9.84375C10.1317 9.84375 10.2674 9.89996 10.3674 10C10.4675 10.1001 10.5237 10.2358 10.5237 10.3773ZM7.8561 12.5114C7.8561 12.6529 7.79989 12.7886 7.69984 12.8886C7.59978 12.9887 7.46408 13.0449 7.32258 13.0449C7.18108 13.0449 7.04538 12.9887 6.94533 12.8886C6.84527 12.7886 6.78906 12.6529 6.78906 12.5114C6.78906 12.3699 6.84527 12.2341 6.94533 12.1341C7.04538 12.034 7.18108 11.9778 7.32258 11.9778C7.46408 11.9778 7.59978 12.034 7.69984 12.1341C7.79989 12.2341 7.8561 12.3699 7.8561 12.5114ZM7.8561 10.3773C7.8561 10.5188 7.79989 10.6545 7.69984 10.7545C7.59978 10.8546 7.46408 10.9108 7.32258 10.9108C7.18108 10.9108 7.04538 10.8546 6.94533 10.7545C6.84527 10.6545 6.78906 10.5188 6.78906 10.3773C6.78906 10.2358 6.84527 10.1001 6.94533 10C7.04538 9.89996 7.18108 9.84375 7.32258 9.84375C7.46408 9.84375 7.59978 9.89996 7.69984 10C7.79989 10.1001 7.8561 10.2358 7.8561 10.3773Z" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1_12643">
|
||||||
|
<rect width="20" height="20" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
3
app/assets/icons/findicon.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.70833 9.16667C2.70833 7.45381 3.38876 5.81111 4.59994 4.59994C5.81111 3.38876 7.45381 2.70833 9.16667 2.70833C10.8795 2.70833 12.5222 3.38876 13.7334 4.59994C14.9446 5.81111 15.625 7.45381 15.625 9.16667C15.625 10.8795 14.9446 12.5222 13.7334 13.7334C12.5222 14.9446 10.8795 15.625 9.16667 15.625C7.45381 15.625 5.81111 14.9446 4.59994 13.7334C3.38876 12.5222 2.70833 10.8795 2.70833 9.16667ZM9.16667 0.625C4.45 0.625 0.625 4.45 0.625 9.16667C0.625 13.8833 4.45 17.7083 9.16667 17.7083C10.8854 17.7083 12.4852 17.2008 13.8251 16.3273C14.1779 16.0973 14.6488 16.1222 14.9466 16.42L17.0074 18.4807C17.3328 18.8062 17.8605 18.8062 18.1859 18.4807L18.4807 18.1859C18.8062 17.8605 18.8062 17.3328 18.4807 17.0074L16.4205 14.9471C16.1225 14.6491 16.0978 14.1778 16.3281 13.8248C17.2286 12.4439 17.7112 10.8258 17.7083 9.16667C17.7083 4.45 13.8842 0.625 9.16667 0.625Z" fill="#1F1F1F"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
10
app/assets/icons/flowericon.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_46_845)">
|
||||||
|
<path d="M8.52082 5.16501C9.00013 5.16501 9.45981 4.9746 9.79873 4.63568C10.1377 4.29676 10.3281 3.83708 10.3281 3.35777C10.3281 2.91701 10.2412 2.48057 10.0726 2.07337C9.90391 1.66616 9.65668 1.29616 9.34502 0.984503C9.03336 0.672841 8.66336 0.425618 8.25616 0.256948C7.84895 0.0882781 7.41251 0.00146484 6.97176 0.00146484C6.49245 0.00146484 6.03277 0.19187 5.69385 0.530793C5.35492 0.869716 5.16452 1.32939 5.16452 1.8087C5.16452 1.32939 4.97411 0.869716 4.63519 0.530793C4.29627 0.19187 3.83659 0.00146484 3.35728 0.00146484C2.46713 0.00146484 1.61344 0.355074 0.984015 0.984503C0.354586 1.61393 0.000976563 2.46762 0.000976562 3.35777C0.000976563 3.83708 0.191382 4.29676 0.530305 4.63568C0.869228 4.9746 1.32891 5.16501 1.80822 5.16501C1.32891 5.16501 0.869228 5.35541 0.530305 5.69433C0.191382 6.03326 0.000976563 6.49294 0.000976562 6.97225C0.000976562 7.413 0.0877898 7.84944 0.25646 8.25665C0.42513 8.66385 0.672353 9.03385 0.984015 9.34551C1.61344 9.97494 2.46713 10.3285 3.35728 10.3285C3.83659 10.3285 4.29627 10.1381 4.63519 9.79922C4.97411 9.4603 5.16452 9.00062 5.16452 8.52131C5.16452 9.00062 5.35492 9.4603 5.69385 9.79922C6.03277 10.1381 6.49245 10.3285 6.97176 10.3285C7.41251 10.3285 7.84895 10.2417 8.25616 10.0731C8.66336 9.9044 9.03336 9.65717 9.34502 9.34551C9.65668 9.03385 9.90391 8.66385 10.0726 8.25665C10.2412 7.84944 10.3281 7.413 10.3281 6.97225C10.3281 6.49294 10.1377 6.03326 9.79873 5.69433C9.45981 5.35541 9.00013 5.16501 8.52082 5.16501Z" fill="#6BE500"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_46_845">
|
||||||
|
<rect width="10.33" height="10.33" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
7
app/assets/icons/profileicon.svg
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<svg width="29" height="35" viewBox="0 0 29 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.46191 0.957031C8.04783 0.957123 9.33301 2.24316 9.33301 3.8291C9.33292 5.41496 8.04778 6.7001 6.46191 6.7002C4.87597 6.7002 3.58994 5.41502 3.58984 3.8291C3.58984 2.24311 4.87592 0.957031 6.46191 0.957031Z" fill="#C8C8C8" stroke="#C8C8C8" stroke-width="1.91447"/>
|
||||||
|
<path d="M21.7871 0.957031C23.373 0.957123 24.6582 2.24316 24.6582 3.8291C24.6581 5.41496 23.373 6.7001 21.7871 6.7002C20.2012 6.7002 18.9151 5.41502 18.915 3.8291C18.915 2.24311 20.2011 0.957031 21.7871 0.957031Z" fill="#C8C8C8" stroke="#C8C8C8" stroke-width="1.91447"/>
|
||||||
|
<path d="M14.1196 21.0566C14.1196 24.2289 15.0768 31.5862 8.37621 31.5862C6.85297 31.5862 5.39211 30.9811 4.31501 29.904C3.23792 28.8269 2.63281 27.366 2.63281 25.8428" stroke="#C8C8C8" stroke-width="5.26478" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M14.1801 21.0566C14.1801 24.2289 13.2229 31.5862 19.9235 31.5862C21.4467 31.5862 22.9076 30.9811 23.9847 29.904C25.0618 28.8269 25.6669 27.366 25.6669 25.8428" stroke="#C8C8C8" stroke-width="5.26478" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M17.9401 20.5747C17.9401 21.8957 14.1112 23.925 14.1112 23.925C14.1112 23.925 10.2822 21.8957 10.2822 20.5747C10.2822 19.2537 11.2395 18.1816 14.1112 18.1816C16.9829 18.1816 17.9401 19.2537 17.9401 20.5747Z" fill="white" stroke="#C8C8C8" stroke-width="5.26478" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/assets/img/badicon.png
Normal file
|
After Width: | Height: | Size: 703 B |
BIN
app/assets/img/goodicon.png
Normal file
|
After Width: | Height: | Size: 862 B |
BIN
app/assets/img/profile.png
Normal file
|
After Width: | Height: | Size: 971 B |
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
@ -35,10 +36,17 @@ class RupApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return ScreenUtilInit(
|
||||||
navigatorKey: navigatorKey,
|
designSize: const Size(375, 812), // 기준 디자인 해상도 set
|
||||||
debugShowCheckedModeBanner: false,
|
minTextAdapt: true,
|
||||||
home: const SplashScreen(),
|
splitScreenMode: true,
|
||||||
|
builder: (context, child) {
|
||||||
|
return MaterialApp(
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: const SplashScreen(),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
|
import 'pet_registration_screen.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatelessWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
@ -6,17 +8,64 @@ class HomeScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: const SafeArea(
|
backgroundColor: Colors.white,
|
||||||
child: Center(
|
body: SafeArea(
|
||||||
child: Text(
|
child: Column(
|
||||||
'로그인 성공!\n여기는 메인 홈 화면입니다.',
|
children: [
|
||||||
textAlign: TextAlign.center,
|
Padding(
|
||||||
style: TextStyle(
|
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h),
|
||||||
fontFamily: 'SCDream',
|
child: Material(
|
||||||
fontWeight: FontWeight.w500,
|
color: Colors.transparent,
|
||||||
fontSize: 18,
|
child: InkWell(
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
8.r,
|
||||||
|
), // Optional: Add radius
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const PetRegistrationScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min, // Wrap content only
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/img/profile.png',
|
||||||
|
width: 40.w,
|
||||||
|
height: 40.h,
|
||||||
|
),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
Text(
|
||||||
|
'반려동물 등록 +',
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'SCDream',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 15.sp,
|
||||||
|
letterSpacing: 0.45.sp,
|
||||||
|
color: const Color(0xFF1f1f1f),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'로그인 성공!\n여기는 메인 홈 화면입니다.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontFamily: 'SCDream',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
fontSize: 18.sp,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import 'main_screen.dart';
|
import 'main_screen.dart';
|
||||||
|
|
||||||
class IdentityVerificationScreen extends StatelessWidget {
|
class IdentityVerificationScreen extends StatelessWidget {
|
||||||
@ -12,13 +13,13 @@ class IdentityVerificationScreen extends StatelessWidget {
|
|||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black, size: 20),
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black, size: 20.w),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
title: const Text(
|
title: Text(
|
||||||
'본인 인증',
|
'본인 인증',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -27,52 +28,52 @@ class IdentityVerificationScreen extends StatelessWidget {
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: EdgeInsets.all(20.0.w),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
const Text(
|
Text(
|
||||||
'더 안전한 서비스 이용을 위해\n본인 인증을 진행해 주세요.',
|
'더 안전한 서비스 이용을 위해\n본인 인증을 진행해 주세요.',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20.sp,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 40),
|
SizedBox(height: 40.h),
|
||||||
|
|
||||||
// 본인 인증 UI (Placeholder)
|
// 본인 인증 UI (Placeholder)
|
||||||
Container(
|
Container(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: EdgeInsets.all(20.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[100],
|
color: Colors.grey[100],
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10.r),
|
||||||
border: Border.all(color: Colors.grey[300]!),
|
border: Border.all(color: Colors.grey[300]!),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const Icon(
|
Icon(
|
||||||
Icons.shield_outlined,
|
Icons.shield_outlined,
|
||||||
size: 50,
|
size: 50.w,
|
||||||
color: Color(0xFFFF7500),
|
color: const Color(0xFFFF7500),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
const Text(
|
Text(
|
||||||
'PASS / 문자 인증',
|
'PASS / 문자 인증',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
const Text(
|
Text(
|
||||||
'(현재 UI만 구현된 상태입니다)',
|
'(현재 UI만 구현된 상태입니다)',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 12,
|
fontSize: 12.sp,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -92,22 +93,22 @@ class IdentityVerificationScreen extends StatelessWidget {
|
|||||||
(route) => false,
|
(route) => false,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const Text(
|
child: Text(
|
||||||
'다음에 하기 (건너뛰기)',
|
'다음에 하기 (건너뛰기)',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 14,
|
fontSize: 14.sp,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
|
|
||||||
// 인증하기 버튼 (현재는 동작 X)
|
// 인증하기 버튼 (현재는 동작 X)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 50,
|
height: 50.h,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@ -118,21 +119,21 @@ class IdentityVerificationScreen extends StatelessWidget {
|
|||||||
backgroundColor: const Color(0xFFFF7500),
|
backgroundColor: const Color(0xFFFF7500),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Text(
|
child: Text(
|
||||||
'인증하기',
|
'인증하기',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import '../services/auth_service.dart';
|
import '../services/auth_service.dart';
|
||||||
import 'main_screen.dart';
|
import 'main_screen.dart';
|
||||||
import 'terms_agreement_screen.dart'; // Import TermsAgreementScreen
|
import 'terms_agreement_screen.dart'; // Import TermsAgreementScreen
|
||||||
@ -71,17 +72,17 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(
|
icon: Icon(
|
||||||
Icons.arrow_back_ios,
|
Icons.arrow_back_ios,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
size: 20,
|
size: 16.w, // Responsive size
|
||||||
),
|
),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
title: const Text(
|
title: Text(
|
||||||
'로그인',
|
'간편 로그인',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15.sp, // Responsive font size
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -90,20 +91,28 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 240),
|
padding: EdgeInsets.fromLTRB(
|
||||||
|
20.w,
|
||||||
|
0,
|
||||||
|
20.w,
|
||||||
|
240.h,
|
||||||
|
), // Responsive padding
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20.h), // Responsive height
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Image.asset('assets/img/foot.png', width: 30),
|
Image.asset(
|
||||||
SizedBox(width: 10),
|
'assets/img/foot.png',
|
||||||
|
width: 30.w,
|
||||||
|
), // Responsive width
|
||||||
|
SizedBox(width: 10.w), // Responsive width
|
||||||
Text(
|
Text(
|
||||||
'로그인',
|
'간편 로그인',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24,
|
fontSize: 24.sp, // Responsive font size
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -111,29 +120,29 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
Text(
|
Text(
|
||||||
'RUP에 어서오세요!\n지금 로그인하고 다양한 서비스를 이용해보세요.',
|
'똑똑한 반려생활을 위한 첫걸음,\nRUP에 오신것을 환영해요!',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14.sp,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
),
|
),
|
||||||
Spacer(),
|
const Spacer(),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Image.asset('assets/img/cat.png', height: 150),
|
child: Image.asset('assets/img/cat.png', height: 150.h),
|
||||||
),
|
),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bottomSheet: Container(
|
bottomSheet: Container(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 40),
|
padding: EdgeInsets.fromLTRB(20.w, 20.h, 20.w, 40.h),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@ -144,31 +153,31 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
backgroundColor: const Color(0xFF00D03F),
|
backgroundColor: const Color(0xFF00D03F),
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
iconPath: 'assets/icons/navericon.svg',
|
iconPath: 'assets/icons/navericon.svg',
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
SizedBox(height: 15.h),
|
||||||
// Kakao Login Button
|
// Kakao Login Button
|
||||||
_SocialLoginButton(
|
_SocialLoginButton(
|
||||||
text: '카카오 로그인',
|
text: '카카오 로그인',
|
||||||
textColor: const Color(0xFF212121),
|
textColor: const Color(0xFF212121),
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
backgroundColor: const Color(0xFFFAE100),
|
backgroundColor: const Color(0xFFFAE100),
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
iconPath: 'assets/icons/kakaoicon.svg',
|
iconPath: 'assets/icons/kakaoicon.svg',
|
||||||
),
|
),
|
||||||
const SizedBox(height: 15),
|
SizedBox(height: 15.h),
|
||||||
// Google Login Button
|
// Google Login Button
|
||||||
_SocialLoginButton(
|
_SocialLoginButton(
|
||||||
text: '구글 로그인',
|
text: '구글 로그인',
|
||||||
textColor: const Color(0xFF17191A),
|
textColor: const Color(0xFF17191A),
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
onPressed: _handleGoogleLogin,
|
onPressed: _handleGoogleLogin,
|
||||||
iconPath: 'assets/icons/googleicon.svg',
|
iconPath: 'assets/icons/googleicon.svg',
|
||||||
@ -180,7 +189,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
if (_isLoading)
|
if (_isLoading)
|
||||||
Container(
|
Container(
|
||||||
color: Colors.black.withOpacity(0.5),
|
color: Colors.black.withValues(alpha: 0.5),
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
child: const Center(child: CircularProgressIndicator()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -208,13 +217,13 @@ class _SocialLoginButton extends StatelessWidget {
|
|||||||
this.isBordered = false,
|
this.isBordered = false,
|
||||||
this.fontFamily = 'SCDream',
|
this.fontFamily = 'SCDream',
|
||||||
this.fontWeight = FontWeight.w500,
|
this.fontWeight = FontWeight.w500,
|
||||||
this.fontSize = 16,
|
required this.fontSize, // Make required to ensure passed value is used
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 50,
|
height: 50.h,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: onPressed,
|
onPressed: onPressed,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
@ -226,14 +235,14 @@ class _SocialLoginButton extends StatelessWidget {
|
|||||||
? BorderSide(color: Colors.grey[300]!)
|
? BorderSide(color: Colors.grey[300]!)
|
||||||
: BorderSide.none,
|
: BorderSide.none,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
iconPath,
|
iconPath,
|
||||||
width: 24,
|
width: 24.w,
|
||||||
height: 24,
|
height: 24.h,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -247,7 +256,7 @@ class _SocialLoginButton extends StatelessWidget {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 24),
|
SizedBox(width: 24.w),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import 'home_screen.dart';
|
import 'home_screen.dart';
|
||||||
import 'reservation_screen.dart';
|
import 'reservation_screen.dart';
|
||||||
import 'mungnyangz_screen.dart';
|
import 'mungnyangz_screen.dart';
|
||||||
@ -37,8 +38,8 @@ class _MainScreenState extends State<MainScreen> {
|
|||||||
Widget _buildSvgIcon(String assetName, int index) {
|
Widget _buildSvgIcon(String assetName, int index) {
|
||||||
return SvgPicture.asset(
|
return SvgPicture.asset(
|
||||||
assetName,
|
assetName,
|
||||||
width: 24,
|
width: 24.w,
|
||||||
height: 24,
|
height: 24.h,
|
||||||
colorFilter: ColorFilter.mode(
|
colorFilter: ColorFilter.mode(
|
||||||
_selectedIndex == index
|
_selectedIndex == index
|
||||||
? AppColors.highlight
|
? AppColors.highlight
|
||||||
@ -52,66 +53,82 @@ class _MainScreenState extends State<MainScreen> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: IndexedStack(index: _selectedIndex, children: _screens),
|
body: IndexedStack(index: _selectedIndex, children: _screens),
|
||||||
bottomNavigationBar: BottomNavigationBar(
|
bottomNavigationBar: Container(
|
||||||
currentIndex: _selectedIndex,
|
padding: EdgeInsets.symmetric(vertical: 10.h),
|
||||||
onTap: _onItemTapped,
|
decoration: const BoxDecoration(
|
||||||
type: BottomNavigationBarType.fixed,
|
color: Colors.white,
|
||||||
selectedItemColor: AppColors.highlight,
|
border: Border(top: BorderSide(color: Color(0xFFEEEEEE), width: 1.0)),
|
||||||
unselectedItemColor: AppColors.inactive,
|
|
||||||
selectedLabelStyle: TextStyle(
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.w500, // Medium
|
|
||||||
),
|
),
|
||||||
unselectedLabelStyle: TextStyle(
|
child: Theme(
|
||||||
fontFamily: 'SCDream',
|
data: Theme.of(context).copyWith(
|
||||||
fontSize: 12,
|
splashColor: Colors.transparent,
|
||||||
fontWeight: FontWeight.w400, // Regular
|
highlightColor: Colors.transparent,
|
||||||
),
|
|
||||||
showUnselectedLabels: true,
|
|
||||||
items: [
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
|
||||||
child: _buildSvgIcon('assets/icons/homeicon.svg', 0),
|
|
||||||
),
|
|
||||||
label: '홈',
|
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
child: BottomNavigationBar(
|
||||||
icon: Padding(
|
backgroundColor: Colors.white,
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
elevation: 0, // Remove default shadow since we have a border
|
||||||
child: _buildSvgIcon('assets/icons/appointmenticon.svg', 1),
|
currentIndex: _selectedIndex,
|
||||||
|
onTap: _onItemTapped,
|
||||||
|
type: BottomNavigationBarType.fixed,
|
||||||
|
selectedItemColor: AppColors.highlight,
|
||||||
|
unselectedItemColor: AppColors.inactive,
|
||||||
|
selectedLabelStyle: TextStyle(
|
||||||
|
fontFamily: 'SCDream',
|
||||||
|
fontSize: 12.sp,
|
||||||
|
fontWeight: FontWeight.w500, // Medium
|
||||||
),
|
),
|
||||||
label: '예약/조회',
|
unselectedLabelStyle: TextStyle(
|
||||||
),
|
fontFamily: 'SCDream',
|
||||||
BottomNavigationBarItem(
|
fontSize: 12.sp,
|
||||||
icon: Padding(
|
fontWeight: FontWeight.w400, // Regular
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
),
|
||||||
child: Image.asset(
|
showUnselectedLabels: true,
|
||||||
_selectedIndex == 2
|
items: [
|
||||||
? 'assets/img/catdog_on.png'
|
BottomNavigationBarItem(
|
||||||
: 'assets/img/catdog_off.png',
|
icon: Padding(
|
||||||
width: 24,
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
height: 24,
|
child: _buildSvgIcon('assets/icons/homeicon.svg', 0),
|
||||||
|
),
|
||||||
|
label: '홈',
|
||||||
),
|
),
|
||||||
),
|
BottomNavigationBarItem(
|
||||||
label: '멍냥즈',
|
icon: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
|
child: _buildSvgIcon('assets/icons/appointmenticon.svg', 1),
|
||||||
|
),
|
||||||
|
label: '예약/조회',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
|
child: Image.asset(
|
||||||
|
_selectedIndex == 2
|
||||||
|
? 'assets/img/catdog_on.png'
|
||||||
|
: 'assets/img/catdog_off.png',
|
||||||
|
width: 29.w,
|
||||||
|
height: 26.h,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
label: '멍냥즈',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
|
child: _buildSvgIcon('assets/icons/shopicon.svg', 3),
|
||||||
|
),
|
||||||
|
label: '상점',
|
||||||
|
),
|
||||||
|
BottomNavigationBarItem(
|
||||||
|
icon: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 10.h),
|
||||||
|
child: _buildSvgIcon('assets/icons/myicon.svg', 4),
|
||||||
|
),
|
||||||
|
label: '내 정보',
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
),
|
||||||
icon: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
|
||||||
child: _buildSvgIcon('assets/icons/shopicon.svg', 3),
|
|
||||||
),
|
|
||||||
label: '상점',
|
|
||||||
),
|
|
||||||
BottomNavigationBarItem(
|
|
||||||
icon: Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 10),
|
|
||||||
child: _buildSvgIcon('assets/icons/myicon.svg', 4),
|
|
||||||
),
|
|
||||||
label: '내 정보',
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import '../utils/log_manager.dart';
|
import '../utils/log_manager.dart';
|
||||||
|
|
||||||
class MungNyangzScreen extends StatelessWidget {
|
class MungNyangzScreen extends StatelessWidget {
|
||||||
@ -8,6 +8,7 @@ class MungNyangzScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: ValueListenableBuilder<List<String>>(
|
child: ValueListenableBuilder<List<String>>(
|
||||||
valueListenable: LogManager().logs,
|
valueListenable: LogManager().logs,
|
||||||
@ -18,19 +19,19 @@ class MungNyangzScreen extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
padding: const EdgeInsets.all(10),
|
padding: EdgeInsets.all(10.w),
|
||||||
itemCount: logs.length,
|
itemCount: logs.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.only(bottom: 5),
|
margin: EdgeInsets.only(bottom: 5.h),
|
||||||
padding: const EdgeInsets.all(8),
|
padding: EdgeInsets.all(8.w),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.black12,
|
color: Colors.black12,
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5.r),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
logs[index],
|
logs[index],
|
||||||
style: const TextStyle(fontSize: 12, fontFamily: 'SCDream'),
|
style: TextStyle(fontSize: 12.sp, fontFamily: 'SCDream'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../services/auth_service.dart';
|
import '../services/auth_service.dart';
|
||||||
import 'welcome_screen.dart';
|
import 'welcome_screen.dart';
|
||||||
import 'notice_screen.dart'; // 공지사항 화면 임포트
|
import 'notice_screen.dart';
|
||||||
import '../data/terms_data.dart'; // 데이터 임포트
|
import '../data/terms_data.dart';
|
||||||
|
|
||||||
class MyInfoScreen extends StatefulWidget {
|
class MyInfoScreen extends StatefulWidget {
|
||||||
const MyInfoScreen({super.key});
|
const MyInfoScreen({super.key});
|
||||||
@ -97,10 +97,10 @@ class _MyInfoScreenState extends State<MyInfoScreen> {
|
|||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
backgroundColor: Colors.transparent, // 둥근 모서리 적용을 위해 투명
|
backgroundColor: Colors.transparent,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return DraggableScrollableSheet(
|
return DraggableScrollableSheet(
|
||||||
initialChildSize: 0.85, // 화면의 85% 높이로 시작
|
initialChildSize: 0.85,
|
||||||
minChildSize: 0.5,
|
minChildSize: 0.5,
|
||||||
maxChildSize: 0.95,
|
maxChildSize: 0.95,
|
||||||
builder: (_, controller) {
|
builder: (_, controller) {
|
||||||
@ -228,10 +228,8 @@ class _MyInfoScreenState extends State<MyInfoScreen> {
|
|||||||
? const Center(child: Text('정보를 불러올 수 없습니다.'))
|
? const Center(child: Text('정보를 불러올 수 없습니다.'))
|
||||||
: SafeArea(
|
: SafeArea(
|
||||||
child: Column(
|
child: Column(
|
||||||
// Column으로 변경하여 하단 고정 영역 확보
|
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
// 상단 스크롤 영역
|
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -243,10 +241,10 @@ class _MyInfoScreenState extends State<MyInfoScreen> {
|
|||||||
color: Colors.grey[100],
|
color: Colors.grey[100],
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const CircleAvatar(
|
const CircleAvatar(
|
||||||
radius: 40,
|
radius: 35,
|
||||||
backgroundColor: Colors.grey,
|
backgroundColor: Colors.grey,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.person,
|
Icons.person,
|
||||||
@ -254,23 +252,28 @@ class _MyInfoScreenState extends State<MyInfoScreen> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(width: 20),
|
||||||
Text(
|
Column(
|
||||||
_userInfo!['nickname'] ?? '이름 없음',
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
style: const TextStyle(
|
children: [
|
||||||
fontFamily: 'SCDream',
|
Text(
|
||||||
fontSize: 20,
|
_userInfo!['nickname'] ?? '이름 없음',
|
||||||
fontWeight: FontWeight.bold,
|
style: const TextStyle(
|
||||||
),
|
fontFamily: 'SCDream',
|
||||||
),
|
fontSize: 20,
|
||||||
const SizedBox(height: 8),
|
fontWeight: FontWeight.bold,
|
||||||
Text(
|
),
|
||||||
_userInfo!['email'] ?? '이메일 없음',
|
),
|
||||||
style: TextStyle(
|
const SizedBox(height: 8),
|
||||||
fontFamily: 'SCDream',
|
Text(
|
||||||
fontSize: 14,
|
_userInfo!['email'] ?? '이메일 없음',
|
||||||
color: Colors.grey[600],
|
style: TextStyle(
|
||||||
),
|
fontFamily: 'SCDream',
|
||||||
|
fontSize: 14,
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -299,7 +302,7 @@ class _MyInfoScreenState extends State<MyInfoScreen> {
|
|||||||
title: '버전 정보',
|
title: '버전 정보',
|
||||||
icon: Icons.info_outline,
|
icon: Icons.info_outline,
|
||||||
trailingText: '1.0.0',
|
trailingText: '1.0.0',
|
||||||
onTap: () {}, // 클릭 효과를 위해 빈 함수 전달
|
onTap: () {},
|
||||||
),
|
),
|
||||||
// 회원 탈퇴 버튼 removed from here
|
// 회원 탈퇴 버튼 removed from here
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
|
|
||||||
class NoticeScreen extends StatelessWidget {
|
class NoticeScreen extends StatelessWidget {
|
||||||
const NoticeScreen({super.key});
|
const NoticeScreen({super.key});
|
||||||
@ -26,49 +27,47 @@ class NoticeScreen extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text(
|
title: Text(
|
||||||
'공지사항',
|
'공지사항',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
|
fontSize: 18.sp, // Added responsive font size
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black, size: 20),
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black, size: 20.w),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
body: ListView.separated(
|
body: ListView.separated(
|
||||||
itemCount: notices.length,
|
itemCount: notices.length,
|
||||||
separatorBuilder: (context, index) =>
|
separatorBuilder: (context, index) =>
|
||||||
const Divider(height: 1, color: Color(0xFFEEEEEE)),
|
Divider(height: 1.h, color: const Color(0xFFEEEEEE)),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final notice = notices[index];
|
final notice = notices[index];
|
||||||
return ExpansionTile(
|
return ExpansionTile(
|
||||||
tilePadding: const EdgeInsets.symmetric(
|
tilePadding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 8.h),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 8,
|
|
||||||
),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
notice['title']!,
|
notice['title']!,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Padding(
|
subtitle: Padding(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: EdgeInsets.only(top: 4.h),
|
||||||
child: Text(
|
child: Text(
|
||||||
notice['date']!,
|
notice['date']!,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 12,
|
fontSize: 12.sp,
|
||||||
color: Colors.grey[500],
|
color: Colors.grey[500],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -76,16 +75,13 @@ class NoticeScreen extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h),
|
||||||
horizontal: 20,
|
|
||||||
vertical: 20,
|
|
||||||
),
|
|
||||||
color: Colors.grey[50],
|
color: Colors.grey[50],
|
||||||
child: Text(
|
child: Text(
|
||||||
notice['content']!,
|
notice['content']!,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontSize: 14,
|
fontSize: 14.sp,
|
||||||
height: 1.5,
|
height: 1.5,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
|
|||||||
1877
app/lib/screens/pet_registration_screen.dart
Normal file
@ -6,6 +6,7 @@ class ReservationScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
body: const SafeArea(
|
body: const SafeArea(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
|
|
||||||
class ShopScreen extends StatelessWidget {
|
class ShopScreen extends StatelessWidget {
|
||||||
const ShopScreen({super.key});
|
const ShopScreen({super.key});
|
||||||
@ -6,11 +7,12 @@ class ShopScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: const SafeArea(
|
backgroundColor: Colors.white,
|
||||||
|
body: SafeArea(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'상점 화면 준비 중입니다.',
|
'상점 화면 준비 중입니다.',
|
||||||
style: TextStyle(fontFamily: 'SCDream'),
|
style: TextStyle(fontFamily: 'SCDream', fontSize: 14.sp),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,259 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import '../services/auth_service.dart';
|
|
||||||
import 'main_screen.dart';
|
|
||||||
import 'terms_agreement_screen.dart';
|
|
||||||
|
|
||||||
class SignupScreen extends StatefulWidget {
|
|
||||||
const SignupScreen({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SignupScreen> createState() => _SignupScreenState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SignupScreenState extends State<SignupScreen> {
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
Future<void> _handleGoogleLogin() async {
|
|
||||||
setState(() {
|
|
||||||
_isLoading = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
final authService = AuthService();
|
|
||||||
// Returns Map<String, dynamic>? { 'credential': ..., 'isNewUser': bool }
|
|
||||||
final result = await authService.signInWithGoogle();
|
|
||||||
|
|
||||||
if (!mounted) return;
|
|
||||||
|
|
||||||
if (result != null) {
|
|
||||||
final isNewUser = result['isNewUser'] as bool;
|
|
||||||
|
|
||||||
if (isNewUser) {
|
|
||||||
// 신규 가입자 -> 약관 동의 화면으로 이동
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) =>
|
|
||||||
TermsAgreementScreen(idToken: result['idToken']),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// 기존 가입자 -> 메인 화면으로 이동
|
|
||||||
Navigator.pushReplacement(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => const MainScreen()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ScaffoldMessenger.of(
|
|
||||||
context,
|
|
||||||
).showSnackBar(const SnackBar(content: Text('로그인이 취소되었습니다.')));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (!mounted) return;
|
|
||||||
ScaffoldMessenger.of(
|
|
||||||
context,
|
|
||||||
).showSnackBar(SnackBar(content: Text('로그인 실패: $e')));
|
|
||||||
} finally {
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Stack(
|
|
||||||
children: [
|
|
||||||
Scaffold(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
elevation: 0,
|
|
||||||
leading: IconButton(
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.arrow_back_ios,
|
|
||||||
color: Colors.black,
|
|
||||||
size: 20,
|
|
||||||
),
|
|
||||||
onPressed: () => Navigator.pop(context),
|
|
||||||
),
|
|
||||||
title: const Text(
|
|
||||||
'회원가입',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
centerTitle: true,
|
|
||||||
),
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 240),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Image.asset('assets/img/foot.png', width: 30),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
const Text(
|
|
||||||
'간편 로그인',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24,
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
const Text(
|
|
||||||
'똑똑한 반려생활을 위한 첫걸음,\nRUP에 오신것을 환영해요!',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.start,
|
|
||||||
),
|
|
||||||
const Spacer(),
|
|
||||||
Align(
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
child: Image.asset('assets/img/cat.png', height: 150),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
bottomSheet: Container(
|
|
||||||
color: Colors.white,
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 20, 20, 40),
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
||||||
children: [
|
|
||||||
// Naver Login Button
|
|
||||||
_SocialLoginButton(
|
|
||||||
text: '네이버 로그인',
|
|
||||||
textColor: Colors.white,
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 15,
|
|
||||||
backgroundColor: const Color(0xFF00D03F),
|
|
||||||
onPressed: () {},
|
|
||||||
iconPath: 'assets/icons/navericon.svg',
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
// Kakao Login Button
|
|
||||||
_SocialLoginButton(
|
|
||||||
text: '카카오로 3초만에 시작하기',
|
|
||||||
textColor: const Color(0xFF212121),
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 15,
|
|
||||||
backgroundColor: const Color(0xFFFAE100),
|
|
||||||
onPressed: () {},
|
|
||||||
iconPath: 'assets/icons/kakaoicon.svg',
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
// Google Login Button
|
|
||||||
_SocialLoginButton(
|
|
||||||
text: '구글 로그인',
|
|
||||||
textColor: const Color(0xFF17191A),
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 15,
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
onPressed: _handleGoogleLogin,
|
|
||||||
iconPath: 'assets/icons/googleicon.svg',
|
|
||||||
isBordered: true,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_isLoading)
|
|
||||||
Container(
|
|
||||||
color: Colors.black.withOpacity(0.5),
|
|
||||||
child: const Center(child: CircularProgressIndicator()),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SocialLoginButton extends StatelessWidget {
|
|
||||||
final String text;
|
|
||||||
final Color textColor;
|
|
||||||
final Color backgroundColor;
|
|
||||||
final VoidCallback onPressed;
|
|
||||||
final String iconPath;
|
|
||||||
final bool isBordered;
|
|
||||||
final String fontFamily;
|
|
||||||
final double fontSize;
|
|
||||||
final FontWeight fontWeight;
|
|
||||||
|
|
||||||
const _SocialLoginButton({
|
|
||||||
required this.text,
|
|
||||||
required this.textColor,
|
|
||||||
required this.backgroundColor,
|
|
||||||
required this.onPressed,
|
|
||||||
required this.iconPath,
|
|
||||||
this.isBordered = false,
|
|
||||||
this.fontFamily = 'SCDream',
|
|
||||||
this.fontWeight = FontWeight.w500,
|
|
||||||
this.fontSize = 16,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SizedBox(
|
|
||||||
height: 50,
|
|
||||||
child: ElevatedButton(
|
|
||||||
onPressed: onPressed,
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
backgroundColor: backgroundColor,
|
|
||||||
foregroundColor: textColor,
|
|
||||||
elevation: 0,
|
|
||||||
shape: StadiumBorder(
|
|
||||||
side: isBordered
|
|
||||||
? BorderSide(color: Colors.grey[300]!)
|
|
||||||
: BorderSide.none,
|
|
||||||
),
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 20),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
iconPath,
|
|
||||||
width: 24,
|
|
||||||
height: 24,
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: fontFamily,
|
|
||||||
fontWeight: fontWeight,
|
|
||||||
fontSize: fontSize,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import 'welcome_screen.dart';
|
import 'welcome_screen.dart';
|
||||||
import 'main_screen.dart';
|
import 'main_screen.dart';
|
||||||
import '../services/auth_service.dart'; // Import AuthService
|
import '../services/auth_service.dart'; // Import AuthService
|
||||||
@ -30,16 +31,20 @@ class _SplashScreenState extends State<SplashScreen> {
|
|||||||
|
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
// 토큰이 있으면 메인 화면으로 (자동 로그인)
|
// 토큰이 있으면 메인 화면으로 (자동 로그인)
|
||||||
Navigator.pushReplacement(
|
if (mounted) {
|
||||||
context,
|
Navigator.pushReplacement(
|
||||||
MaterialPageRoute(builder: (context) => const MainScreen()),
|
context,
|
||||||
);
|
MaterialPageRoute(builder: (context) => const MainScreen()),
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 토큰이 없으면 웰컴 화면으로
|
// 토큰이 없으면 웰컴 화면으로
|
||||||
Navigator.pushReplacement(
|
if (mounted) {
|
||||||
context,
|
Navigator.pushReplacement(
|
||||||
MaterialPageRoute(builder: (context) => const WelcomeScreen()),
|
context,
|
||||||
);
|
MaterialPageRoute(builder: (context) => const WelcomeScreen()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,14 +56,14 @@ class _SplashScreenState extends State<SplashScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Image.asset('assets/img/maindog.png', width: 150, height: 150),
|
Image.asset('assets/img/maindog.png', width: 150.w, height: 150.h),
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
const Text(
|
Text(
|
||||||
'RUP',
|
'RUP',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 32,
|
fontSize: 32.sp,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import 'identity_verification_screen.dart';
|
import 'identity_verification_screen.dart';
|
||||||
import '../services/auth_service.dart'; // Import AuthService
|
import '../services/auth_service.dart'; // Import AuthService
|
||||||
import '../data/terms_data.dart';
|
import '../data/terms_data.dart';
|
||||||
@ -59,41 +60,41 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
maxChildSize: 0.9,
|
maxChildSize: 0.9,
|
||||||
builder: (_, controller) {
|
builder: (_, controller) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)),
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(20),
|
padding: EdgeInsets.all(20.w),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 40,
|
width: 40.w,
|
||||||
height: 4,
|
height: 4.h,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[300],
|
color: Colors.grey[300],
|
||||||
borderRadius: BorderRadius.circular(2),
|
borderRadius: BorderRadius.circular(2.r),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
Text(
|
Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
child: Text(
|
child: Text(
|
||||||
_getTermContent(index),
|
_getTermContent(index),
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
height: 1.6,
|
height: 1.6,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
@ -101,24 +102,24 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 52,
|
height: 52.h,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: const Color(0xFFFF7500),
|
backgroundColor: const Color(0xFFFF7500),
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30.r),
|
||||||
),
|
),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
child: const Text(
|
child: Text(
|
||||||
'확인',
|
'확인',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
@ -142,14 +143,14 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: const Icon(Icons.arrow_back_ios, color: Colors.black, size: 20),
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black, size: 20.w),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.isViewOnly ? '이용 약관' : '회원가입',
|
widget.isViewOnly ? '이용 약관' : '회원가입',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
@ -161,24 +162,24 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
// Header Area
|
// Header Area
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/img/foot.png',
|
'assets/img/foot.png',
|
||||||
width: 24,
|
width: 24.w,
|
||||||
height: 24,
|
height: 24.h,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
SizedBox(width: 8.w),
|
||||||
const Text(
|
Text(
|
||||||
'서비스 이용 약관',
|
'서비스 이용 약관',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 22,
|
fontSize: 22.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
@ -186,32 +187,32 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
SizedBox(height: 8.h),
|
||||||
Text(
|
Text(
|
||||||
widget.isViewOnly
|
widget.isViewOnly
|
||||||
? 'RUP 서비스의 이용 약관 내용입니다.'
|
? 'RUP 서비스의 이용 약관 내용입니다.'
|
||||||
: '서비스 이용을 위해 약관에 동의해주세요.',
|
: '서비스 이용을 위해 약관에 동의해주세요.',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
SizedBox(height: 30.h),
|
||||||
|
|
||||||
// All Agree Box - *ViewOnly 모드에서는 숨김*
|
// All Agree Box - *ViewOnly 모드에서는 숨김*
|
||||||
if (!widget.isViewOnly) ...[
|
if (!widget.isViewOnly) ...[
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () => _toggleAll(),
|
onTap: () => _toggleAll(),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: 16,
|
vertical: 16.h,
|
||||||
horizontal: 16,
|
horizontal: 16.w,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(color: Colors.grey.shade300),
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -223,11 +224,11 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
? const Color(0xFFFF7500)
|
? const Color(0xFFFF7500)
|
||||||
: Colors.grey,
|
: Colors.grey,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
SizedBox(width: 12.w),
|
||||||
const Text(
|
Text(
|
||||||
'모든 약관에 동의합니다.',
|
'모든 약관에 동의합니다.',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
@ -236,9 +237,9 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
SizedBox(height: 20.h),
|
||||||
const Divider(height: 1, color: Color(0xFFEEEEEE)),
|
Divider(height: 1.h, color: const Color(0xFFEEEEEE)),
|
||||||
const SizedBox(height: 10),
|
SizedBox(height: 10.h),
|
||||||
],
|
],
|
||||||
|
|
||||||
// Individual Items
|
// Individual Items
|
||||||
@ -255,10 +256,10 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
|
|
||||||
// Bottom Button
|
// Bottom Button
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(20, 10, 20, 20),
|
padding: EdgeInsets.fromLTRB(20.w, 10.h, 20.w, 20.h),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 52,
|
height: 52.h,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: widget.isViewOnly
|
onPressed: widget.isViewOnly
|
||||||
? () => Navigator.pop(context)
|
? () => Navigator.pop(context)
|
||||||
@ -299,15 +300,15 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
backgroundColor: const Color(0xFFFF7500),
|
backgroundColor: const Color(0xFFFF7500),
|
||||||
disabledBackgroundColor: Colors.grey[300],
|
disabledBackgroundColor: Colors.grey[300],
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(30),
|
borderRadius: BorderRadius.circular(30.r),
|
||||||
),
|
),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.isViewOnly ? '닫기' : '동의하고 본인 인증하기',
|
widget.isViewOnly ? '닫기' : '동의하고 본인 인증하기',
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 16,
|
fontSize: 16.sp,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
@ -326,7 +327,7 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
// ViewOnly 모드에서는 텍스트 클릭 시 모달 띄우기 (토글 X)
|
// ViewOnly 모드에서는 텍스트 클릭 시 모달 띄우기 (토글 X)
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
padding: EdgeInsets.symmetric(vertical: 4.h),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -339,24 +340,21 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
_showTermDetail(context, title, index);
|
_showTermDetail(context, title, index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8.r),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 8.w),
|
||||||
vertical: 12,
|
|
||||||
horizontal: 8,
|
|
||||||
),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
// 체크 Icon - *ViewOnly 모드에서는 숨김*
|
// 체크 Icon - *ViewOnly 모드에서는 숨김*
|
||||||
if (!widget.isViewOnly) ...[
|
if (!widget.isViewOnly) ...[
|
||||||
Icon(
|
Icon(
|
||||||
Icons.check,
|
Icons.check,
|
||||||
size: 20,
|
size: 20.w,
|
||||||
color: _checks[index]
|
color: _checks[index]
|
||||||
? const Color(0xFFFF7500)
|
? const Color(0xFFFF7500)
|
||||||
: Colors.grey[300],
|
: Colors.grey[300],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
SizedBox(width: 12.w),
|
||||||
],
|
],
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
@ -366,16 +364,16 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
? const Color(0xFFFF7500)
|
? const Color(0xFFFF7500)
|
||||||
: Colors.grey,
|
: Colors.grey,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 14,
|
fontSize: 14.sp,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
SizedBox(width: 8.w),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
style: const TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15.sp,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
),
|
),
|
||||||
@ -388,13 +386,13 @@ class _TermsAgreementScreenState extends State<TermsAgreementScreen> {
|
|||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () => _showTermDetail(context, title, index),
|
onPressed: () => _showTermDetail(context, title, index),
|
||||||
icon: const Icon(
|
icon: Icon(
|
||||||
Icons.arrow_forward_ios,
|
Icons.arrow_forward_ios,
|
||||||
size: 14,
|
size: 14.w,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
splashRadius: 20,
|
splashRadius: 20.r,
|
||||||
padding: const EdgeInsets.all(12),
|
padding: EdgeInsets.all(12.w),
|
||||||
constraints: const BoxConstraints(),
|
constraints: const BoxConstraints(),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -12,4 +12,7 @@ class AppColors {
|
|||||||
|
|
||||||
// 강조색: #FF7500 (버튼, 호버 등 중요!)
|
// 강조색: #FF7500 (버튼, 호버 등 중요!)
|
||||||
static const Color highlight = Color(0xFFFF7500);
|
static const Color highlight = Color(0xFFFF7500);
|
||||||
|
|
||||||
|
// 부강조색: #FBB800
|
||||||
|
static const Color subHighlight = Color(0xFFFBB800);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
|
|
||||||
class IntroBody extends StatelessWidget {
|
class IntroBody extends StatelessWidget {
|
||||||
const IntroBody({super.key});
|
const IntroBody({super.key});
|
||||||
@ -6,8 +7,8 @@ class IntroBody extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.fromLTRB(40, 0, 40, 0),
|
padding: EdgeInsets.fromLTRB(40.w, 0, 40.w, 0),
|
||||||
margin: EdgeInsets.only(top: 156),
|
margin: EdgeInsets.only(top: 156.h),
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
return FittedBox(
|
return FittedBox(
|
||||||
@ -28,7 +29,7 @@ class IntroBody extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
'Right',
|
'Right',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 60,
|
fontSize: 60.sp,
|
||||||
fontFamily: 'Ownglyph',
|
fontFamily: 'Ownglyph',
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
@ -36,17 +37,17 @@ class IntroBody extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
'Use for',
|
'Use for',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 60,
|
fontSize: 60.sp,
|
||||||
fontFamily: 'Ownglyph',
|
fontFamily: 'Ownglyph',
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 26),
|
padding: EdgeInsets.only(bottom: 26.h),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Pet',
|
'Pet',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 60,
|
fontSize: 60.sp,
|
||||||
fontFamily: 'Ownglyph',
|
fontFamily: 'Ownglyph',
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
@ -54,17 +55,26 @@ class IntroBody extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Image.asset('assets/img/mainball.png'),
|
Image.asset(
|
||||||
|
'assets/img/mainball.png',
|
||||||
|
width: 100.w,
|
||||||
|
), // Added explicit width control
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Column(
|
Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Image.asset('assets/img/maindog.png'),
|
Image.asset(
|
||||||
|
'assets/img/maindog.png',
|
||||||
|
width: 150.w,
|
||||||
|
), // Added explicit width control
|
||||||
Opacity(
|
Opacity(
|
||||||
opacity: 0.0,
|
opacity: 0.0,
|
||||||
child: Image.asset('assets/img/mainball.png'),
|
child: Image.asset(
|
||||||
|
'assets/img/mainball.png',
|
||||||
|
width: 100.w,
|
||||||
|
), // Added explicit width control
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../screens/signup_screen.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; // Import screenutil
|
||||||
import '../screens/login_screen.dart';
|
import '../screens/login_screen.dart';
|
||||||
|
|
||||||
class LoginPanel extends StatelessWidget {
|
class LoginPanel extends StatelessWidget {
|
||||||
@ -9,8 +9,8 @@ class LoginPanel extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
color: Color(0xFFFF7500),
|
color: const Color(0xFFFF7500),
|
||||||
padding: EdgeInsets.fromLTRB(40, 0, 40, 40),
|
padding: EdgeInsets.fromLTRB(40.w, 0, 40.w, 40.h),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -18,27 +18,27 @@ class LoginPanel extends StatelessWidget {
|
|||||||
Text(
|
Text(
|
||||||
'간편한 반려생활을 위한 첫걸음,\nRUP에 오신것을 환영합니다!',
|
'간편한 반려생활을 위한 첫걸음,\nRUP에 오신것을 환영합니다!',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12.sp,
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 30),
|
SizedBox(height: 30.h),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(builder: (context) => SignupScreen()),
|
MaterialPageRoute(builder: (context) => const LoginScreen()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
shape: StadiumBorder(),
|
shape: const StadiumBorder(),
|
||||||
padding: EdgeInsets.all(15),
|
padding: EdgeInsets.all(15.w),
|
||||||
),
|
),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@ -49,7 +49,9 @@ class LoginPanel extends StatelessWidget {
|
|||||||
'시작하기',
|
'시작하기',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontFamily: 'SCDream',
|
fontFamily: 'SCDream',
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight
|
||||||
|
.bold, // Fixed typo in previous code if any, bold is correct
|
||||||
|
fontSize: 14.sp, // Added font size
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -58,27 +60,6 @@ class LoginPanel extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 5),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => LoginScreen()),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
'기존 계정으로 로그인',
|
|
||||||
style: TextStyle(
|
|
||||||
fontFamily: 'SCDream',
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 12,
|
|
||||||
color: Colors.white,
|
|
||||||
decoration: TextDecoration.underline,
|
|
||||||
decorationColor: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,9 +6,13 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
|
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||||
|
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||||
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
file_selector_linux
|
||||||
flutter_secure_storage_linux
|
flutter_secure_storage_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import file_selector_macos
|
||||||
import firebase_auth
|
import firebase_auth
|
||||||
import firebase_core
|
import firebase_core
|
||||||
import flutter_secure_storage_macos
|
import flutter_secure_storage_macos
|
||||||
@ -12,6 +13,7 @@ import google_sign_in_ios
|
|||||||
import video_player_avfoundation
|
import video_player_avfoundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
|
||||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||||
|
|||||||
120
app/pubspec.lock
@ -65,6 +65,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.19.1"
|
version: "1.19.1"
|
||||||
|
cross_file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cross_file
|
||||||
|
sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.5+1"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -129,6 +137,38 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
file_selector_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_linux
|
||||||
|
sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.4"
|
||||||
|
file_selector_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_macos
|
||||||
|
sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.5"
|
||||||
|
file_selector_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_platform_interface
|
||||||
|
sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
|
file_selector_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file_selector_windows
|
||||||
|
sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.3+5"
|
||||||
firebase_auth:
|
firebase_auth:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -190,6 +230,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.33"
|
||||||
|
flutter_screenutil:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_screenutil
|
||||||
|
sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.9.3"
|
||||||
flutter_secure_storage:
|
flutter_secure_storage:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -344,6 +400,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
image_picker:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: image_picker
|
||||||
|
sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
|
image_picker_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_android
|
||||||
|
sha256: "297e42bd236c4ac4b091d4277292159b3280545e030cae2be3d503f9ecf7e6a1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.13+12"
|
||||||
|
image_picker_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_for_web
|
||||||
|
sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.1"
|
||||||
|
image_picker_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_ios
|
||||||
|
sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.8.13+3"
|
||||||
|
image_picker_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_linux
|
||||||
|
sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2"
|
||||||
|
image_picker_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_macos
|
||||||
|
sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2+1"
|
||||||
|
image_picker_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_platform_interface
|
||||||
|
sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.11.1"
|
||||||
|
image_picker_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image_picker_windows
|
||||||
|
sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.2"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -41,6 +41,8 @@ dependencies:
|
|||||||
google_sign_in: ^6.2.1 # 구글 로그인 UI/기능 (Updated)
|
google_sign_in: ^6.2.1 # 구글 로그인 UI/기능 (Updated)
|
||||||
dio: ^5.4.0
|
dio: ^5.4.0
|
||||||
flutter_secure_storage: ^9.0.0
|
flutter_secure_storage: ^9.0.0
|
||||||
|
image_picker: ^1.2.1
|
||||||
|
flutter_screenutil: ^5.9.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@ -6,11 +6,14 @@
|
|||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <firebase_auth/firebase_auth_plugin_c_api.h>
|
#include <firebase_auth/firebase_auth_plugin_c_api.h>
|
||||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
FirebaseAuthPluginCApiRegisterWithRegistrar(
|
FirebaseAuthPluginCApiRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi"));
|
registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi"));
|
||||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
file_selector_windows
|
||||||
firebase_auth
|
firebase_auth
|
||||||
firebase_core
|
firebase_core
|
||||||
flutter_secure_storage_windows
|
flutter_secure_storage_windows
|
||||||
|
|||||||