Skip to content

feat: 로그인 화면 구현 및 api 연결 완료#17

Merged
surfwithus merged 11 commits intomainfrom
feat/login
Jul 15, 2025
Merged

feat: 로그인 화면 구현 및 api 연결 완료#17
surfwithus merged 11 commits intomainfrom
feat/login

Conversation

@surfwithus
Copy link
Copy Markdown
Collaborator

@surfwithus surfwithus commented Jul 15, 2025

로그인 플로우 화면들을 구현하였고,
로그인 api를 연결하여 로그인 기능을 완성하였습니다.

Summary by CodeRabbit

  • 신규 기능

    • 비밀번호 입력을 통한 로그인 화면 및 로그인 완료 화면이 추가되었습니다.
    • 가족 코드 생성 및 가족 참여 기능이 별도의 서비스로 분리되어 개선되었습니다.
    • 회원가입 및 로그인, 가족 코드 생성/참여를 위한 신규 서비스가 도입되었습니다.
    • 액세스 토큰을 저장/관리하는 기능이 추가되었습니다.
  • 버그 수정 및 개선

    • 이메일, 이름 등 입력값 검증 시 안내 메시지와 스낵바 스타일이 개선되었습니다.
    • 가족명, 가족코드 입력 화면의 흐름과 UI가 더욱 직관적으로 변경되었습니다.
    • 회원가입 단계별 진행 흐름이 간소화되고, 오류 메시지가 명확해졌습니다.
  • 스타일

    • 여러 입력 및 안내 메시지의 색상, 정렬, 버튼 크기 등 UI 요소가 개선되었습니다.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 15, 2025

Walkthrough

이 변경사항은 온기 앱의 회원가입 및 로그인 플로우를 대대적으로 리팩토링하고, 가족 코드 생성 및 가입, 토큰 저장 등 인증 관련 서비스와 화면을 새롭게 도입합니다. 기존의 인증 로직은 분리된 서비스 클래스로 이동되었으며, 각 화면의 UI와 동작이 명확히 분리 및 개선되었습니다.

Changes

파일/그룹 변경 요약
frontend/ongi/lib/main.dart 불필요한 화면 import 제거, /login 라우트가 LoginPwScreen으로 변경됨
frontend/ongi/lib/screens/login/login_pw_screen.dart
frontend/ongi/lib/screens/login/login_ready_screen.dart
새로운 로그인 비밀번호 입력 및 로그인 완료 화면 추가
frontend/ongi/lib/screens/signup/familycode_create_screen.dart
frontend/ongi/lib/screens/signup/familycode_screen.dart
가족 코드 생성/가입 로직을 별도 서비스로 분리, 등록 로직 단순화 및 UI/에러 처리 개선
frontend/ongi/lib/screens/signup/familyname_screen.dart 회원가입 로직 제거, 가족 이름 저장 및 네비게이션만 수행, UI 구조 변경
frontend/ongi/lib/screens/signup/mode_screen.dart 모드 선택 시 회원가입 및 자동 로그인 처리 로직 추가, 에러 및 피드백 강화
frontend/ongi/lib/screens/signup/ready_screen.dart 텍스트 정렬 및 스타일 변경, 버튼 패딩/레이아웃 조정
frontend/ongi/lib/screens/signup/username_screen.dart 빈 입력 시 스낵바 스타일 개선(색상, 둥근 테두리, 지속시간 등)
frontend/ongi/lib/screens/start_screen.dart 이메일 입력 검증 강화(한글 포함 여부, 스낵바 스타일 개선)
frontend/ongi/lib/services/code_service.dart 가족 코드 생성용 CodeService 신규 도입
frontend/ongi/lib/services/family_join_service.dart 가족 가입용 FamilyJoinService 신규 도입
frontend/ongi/lib/services/login_service.dart 로그인 처리용 LoginService 신규 도입
frontend/ongi/lib/services/signup_service.dart AuthService → SignupService로 클래스명 변경
frontend/ongi/lib/services/email_service.dart import 순서만 변경, 기능 변화 없음
frontend/ongi/lib/utils/token_storage.dart 액세스 토큰 저장/조회/삭제용 TokenStorage 신규 도입

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LoginPwScreen
    participant LoginService
    participant TokenStorage
    participant LoginReadyScreen
    participant HomeScreen

    User->>LoginPwScreen: 비밀번호 입력 및 로그인 버튼 클릭
    LoginPwScreen->>LoginService: login(email, password)
    LoginService->>TokenStorage: saveAccessToken(token)
    LoginService-->>LoginPwScreen: 로그인 결과 반환(성공/실패)
    alt 로그인 성공
        LoginPwScreen->>LoginReadyScreen: username 전달하며 이동
        LoginReadyScreen->>HomeScreen: 2초 후 자동 이동
    else 로그인 실패
        LoginPwScreen->>User: 에러 스낵바 표시
    end
Loading
sequenceDiagram
    participant User
    participant FamilycodeCreateScreen
    participant CodeService

    User->>FamilycodeCreateScreen: "생성하기" 클릭
    FamilycodeCreateScreen->>CodeService: familyCreate(familyName)
    CodeService-->>FamilycodeCreateScreen: familyCode 반환
    FamilycodeCreateScreen->>User: 코드 표시 및 "함께하기" 버튼 활성화
Loading

Possibly related PRs

Poem

🥕
새로운 가족 코드, 로그인도 척척!
당근같이 깔끔해진 온기 앱의 복도,
서비스 쪼개고, 스낵바에 색 입혀
토큰은 안전하게, 가입은 부드럽게!
오늘도 코드를 뜀박질하는 토끼,
온기 가득, 가족도 든든히!
🐰


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@surfwithus surfwithus merged commit 10c79db into main Jul 15, 2025
2 of 4 checks passed
@surfwithus surfwithus deleted the feat/login branch July 15, 2025 10:16
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

♻️ Duplicate comments (1)
frontend/ongi/lib/services/family_join_service.dart (1)

6-6: 하드코딩된 베이스 URL을 환경 설정으로 분리하세요.

다른 서비스들과 마찬가지로 베이스 URL이 하드코딩되어 있습니다. 중앙 집중식 설정 관리가 필요합니다.

🧹 Nitpick comments (4)
frontend/ongi/lib/utils/token_storage.dart (1)

1-20: 전체적으로 견고한 에러 처리 추가를 고려해보세요.

현재 구현은 기본적인 기능을 잘 제공하지만, SharedPreferences 작업에 대한 에러 처리를 추가하면 더 견고한 코드가 될 것입니다.

예를 들어, 다음과 같은 에러 처리를 추가할 수 있습니다:

static Future<void> saveAccessToken(String token) async {
  try {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(_accessTokenKey, token);
  } catch (e) {
    // 로그 또는 에러 처리
    rethrow;
  }
}
frontend/ongi/lib/screens/start_screen.dart (1)

200-216: 한국어 문자 검증 로직이 잘 구현되었습니다.

정규표현식을 사용한 한국어 검증이 올바르게 구현되어 있고, 일관된 스낵바 스타일이 적용되었습니다.

// 성능 개선을 위해 정규표현식을 static final로 선언하는 것을 고려해보세요:
static final RegExp _koreanRegex = RegExp(r'[ㄱ-ㅎㅏ-ㅣ가-힣]');
frontend/ongi/lib/screens/login/login_pw_screen.dart (1)

83-106: 비밀번호 표시/숨기기 토글 기능을 추가하세요

사용자 경험 향상을 위해 비밀번호를 표시하거나 숨길 수 있는 토글 버튼을 추가하는 것이 좋습니다.

상태 변수를 추가하고:

bool _isPasswordVisible = false;

TextField를 수정하세요:

               child: TextField(
                 controller: _passwordCtrl,
-                keyboardType: TextInputType.visiblePassword,
+                obscureText: !_isPasswordVisible,
+                keyboardType: TextInputType.text,
                 style: const TextStyle(fontSize: 25, color: AppColors.ongiOrange),
                 decoration: InputDecoration(
                   hintText: 'PASSWORD',
                   hintStyle:
                   TextStyle(color: Colors.grey),
+                  suffixIcon: IconButton(
+                    icon: Icon(
+                      _isPasswordVisible ? Icons.visibility : Icons.visibility_off,
+                      color: AppColors.ongiOrange,
+                    ),
+                    onPressed: () {
+                      setState(() {
+                        _isPasswordVisible = !_isPasswordVisible;
+                      });
+                    },
+                  ),
frontend/ongi/lib/screens/signup/mode_screen.dart (1)

39-55: 이메일이 비어있을 때의 처리를 개선하세요

현재는 모든 필드가 비어있을 때만 에러를 표시하지만, 각 필드별로 구체적인 에러 메시지를 제공하는 것이 좋습니다.

-      if (email.isEmpty || password.isEmpty || name.isEmpty) {
-        ScaffoldMessenger.of(context).showSnackBar(
-          SnackBar(
-            content: const Text(
-              '회원가입 정보가 올바르지 않아요.',
-              style: TextStyle(color: AppColors.ongiOrange),
-            ),
+      if (email.isEmpty) {
+        _showErrorSnackBar('이메일 정보가 없습니다.');
+        return;
+      }
+      if (password.isEmpty) {
+        _showErrorSnackBar('비밀번호 정보가 없습니다.');
+        return;
+      }
+      if (name.isEmpty) {
+        _showErrorSnackBar('이름 정보가 없습니다.');
+        return;
+      }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7523b50 and 087f8df.

📒 Files selected for processing (16)
  • frontend/ongi/lib/main.dart (2 hunks)
  • frontend/ongi/lib/screens/login/login_pw_screen.dart (1 hunks)
  • frontend/ongi/lib/screens/login/login_ready_screen.dart (1 hunks)
  • frontend/ongi/lib/screens/signup/familycode_create_screen.dart (4 hunks)
  • frontend/ongi/lib/screens/signup/familycode_screen.dart (3 hunks)
  • frontend/ongi/lib/screens/signup/familyname_screen.dart (4 hunks)
  • frontend/ongi/lib/screens/signup/mode_screen.dart (3 hunks)
  • frontend/ongi/lib/screens/signup/ready_screen.dart (1 hunks)
  • frontend/ongi/lib/screens/signup/username_screen.dart (1 hunks)
  • frontend/ongi/lib/screens/start_screen.dart (1 hunks)
  • frontend/ongi/lib/services/code_service.dart (1 hunks)
  • frontend/ongi/lib/services/email_service.dart (1 hunks)
  • frontend/ongi/lib/services/family_join_service.dart (1 hunks)
  • frontend/ongi/lib/services/login_service.dart (1 hunks)
  • frontend/ongi/lib/services/signup_service.dart (1 hunks)
  • frontend/ongi/lib/utils/token_storage.dart (1 hunks)
🔇 Additional comments (24)
frontend/ongi/lib/services/email_service.dart (1)

1-2: import 순서 변경 확인 – 문제 없습니다

dart: SDK import 뒤에 외부 패키지 import를 배치한 것은 Dart 스타일 가이드에 부합합니다. 다른 로직 변경이 없으므로 승인합니다.

frontend/ongi/lib/screens/signup/username_screen.dart (1)

118-129: SnackBar 스타일링 개선이 잘 되었습니다.

흰색 배경에 오렌지색 텍스트, 플로팅 동작, 둥근 모서리 등의 스타일링이 추가되어 사용자 경험이 향상되었습니다. 2초 지속 시간도 적절합니다.

frontend/ongi/lib/services/signup_service.dart (1)

4-4: 클래스명 변경 검증 완료

코드베이스 전체에서 이전 클래스명 AuthService에 대한 참조가 존재하지 않음을 확인했습니다.
AuthServiceSignupService로의 변경은 의미적으로 더 명확하며 안전하게 반영되었습니다.

frontend/ongi/lib/main.dart (2)

2-2: 새로운 로그인 화면 import가 적절합니다.

LoginPwScreen을 위한 새로운 import가 추가되었습니다.


26-26: 로그인 라우트 업데이트가 올바릅니다.

LoginPwScreen으로 라우트가 업데이트되어 새로운 로그인 플로우와 일치합니다.

frontend/ongi/lib/screens/signup/ready_screen.dart (2)

33-33: 텍스트 폰트 굵기 변경이 적절합니다.

FontWeight.w800에서 FontWeight.w200으로 변경되어 더 가벼운 텍스트 스타일을 제공합니다.


38-43: 버튼 레이아웃 개선이 잘 되었습니다.

Padding 위젯으로 감싸고 minimumSize 제약 조건을 추가하여 버튼 레이아웃이 개선되었습니다.

frontend/ongi/lib/utils/token_storage.dart (4)

3-4: TokenStorage 클래스 설계가 적절합니다.

토큰 관리를 위한 유틸리티 클래스가 잘 설계되었습니다. private 상수를 사용한 키 관리가 좋습니다.


6-9: 토큰 저장 메서드가 올바르게 구현되었습니다.

SharedPreferences를 사용한 토큰 저장 로직이 적절합니다.


11-14: 토큰 조회 메서드가 올바르게 구현되었습니다.

토큰 조회 로직이 적절하며, null 반환 처리도 올바릅니다.


16-19: 토큰 삭제 메서드가 올바르게 구현되었습니다.

토큰 삭제 로직이 적절합니다.

frontend/ongi/lib/screens/start_screen.dart (1)

187-199: 이메일 형식 검증 메시지가 일관되게 스타일링되었습니다.

기존 검증 로직에 일관된 스낵바 스타일링이 적용되어 사용자 경험이 개선되었습니다.

frontend/ongi/lib/screens/login/login_ready_screen.dart (2)

21-27: 타이머 처리와 네비게이션 로직이 잘 구현되었습니다.

mounted 체크를 통해 메모리 누수를 방지하고, 적절한 타이머 관리가 이루어져 있습니다.


29-33: 리소스 정리가 올바르게 구현되었습니다.

dispose 메서드에서 타이머를 적절히 취소하여 메모리 누수를 방지하고 있습니다.

frontend/ongi/lib/services/login_service.dart (1)

26-29: 토큰 저장 로직이 올바르게 구현되었습니다.

응답 처리와 토큰 저장 로직이 적절히 구현되어 있습니다.

frontend/ongi/lib/screens/signup/familycode_create_screen.dart (3)

19-25: 상태 기반 네비게이션 로직이 잘 구현되었습니다.

코드 생성 후 버튼 클릭 시 바로 다음 화면으로 이동하는 로직이 명확하게 구현되어 있습니다.


31-44: CodeService를 사용한 코드 생성 로직이 올바르게 구현되었습니다.

서비스 분리가 잘 이루어졌고, 응답 처리도 적절합니다.


157-159: 동적 버튼 텍스트 변경이 사용자 경험을 개선합니다.

상태에 따라 버튼 텍스트가 변경되어 사용자에게 명확한 피드백을 제공합니다.

frontend/ongi/lib/services/family_join_service.dart (3)

10-13: 토큰 검증 로직이 올바르게 구현되었습니다.

액세스 토큰 존재 여부를 확인하고 적절한 에러 메시지를 제공합니다.


18-21: Authorization 헤더가 올바르게 구현되었습니다.

Bearer 토큰을 사용한 인증 헤더가 적절히 설정되어 있습니다.


27-31: 상태 코드별 에러 처리가 적절합니다.

200과 201 상태 코드를 모두 성공으로 처리하고, 실패 시 구체적인 에러 메시지를 제공합니다.

frontend/ongi/lib/screens/signup/familyname_screen.dart (1)

18-54: 코드 변경사항이 적절합니다!

가족 이름 저장 로직이 단순화되고 에러 처리가 개선되었습니다.

frontend/ongi/lib/screens/signup/familycode_screen.dart (2)

14-33: 에러 처리가 잘 구현되었습니다!

로딩 상태 관리와 에러 메시지 표시를 위한 헬퍼 메서드가 깔끔하게 구현되었습니다.


35-59: 비동기 처리와 상태 관리가 적절합니다!

로딩 인디케이터와 에러 처리가 사용자 경험을 고려하여 잘 구현되었습니다.

import '../utils/token_storage.dart';

class LoginService {
static const String baseUrl = 'https://ongi-1049536928483.asia-northeast1.run.app';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

하드코딩된 베이스 URL을 환경 설정으로 분리하세요.

베이스 URL이 하드코딩되어 있어 개발/운영 환경 분리가 어렵습니다.

// 환경 설정 파일로 분리하는 것을 고려해보세요:
import 'package:ongi/config/api_config.dart';

class LoginService {
  static const String baseUrl = ApiConfig.baseUrl;
  // ...
}
🤖 Prompt for AI Agents
In frontend/ongi/lib/services/login_service.dart at line 7, the baseUrl is
hardcoded, which hinders environment separation. To fix this, remove the
hardcoded URL and instead import a configuration file (e.g., api_config.dart)
that defines the baseUrl as a constant. Then assign baseUrl from that
configuration to enable easy switching between development and production
environments.

Comment on lines +30 to +32
} else {
throw Exception('로그인 실패: ${response.statusCode} ${response.body}');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

에러 메시지를 더 사용자 친화적으로 개선하세요.

현재 에러 메시지가 기술적인 정보를 포함하고 있어 사용자에게 혼란을 줄 수 있습니다.

} else {
  // 상태 코드별로 구체적인 에러 메시지 제공
  final errorMessage = response.statusCode == 401 
    ? '이메일 또는 비밀번호가 잘못되었습니다.'
    : '로그인에 실패했습니다. 잠시 후 다시 시도해주세요.';
  throw Exception(errorMessage);
}
🤖 Prompt for AI Agents
In frontend/ongi/lib/services/login_service.dart around lines 30 to 32, the
current error message includes technical details like status code and response
body, which can confuse users. Replace this with user-friendly messages by
checking the status code: if it is 401, throw an exception with '이메일 또는 비밀번호가
잘못되었습니다.'; otherwise, throw '로그인에 실패했습니다. 잠시 후 다시 시도해주세요.' to provide clearer,
more helpful feedback.

Comment on lines +28 to +32
if (response.statusCode == 200 || response.statusCode == 201) {
return jsonDecode(response.body);
} else {
throw Exception('회원가입에 실패했습니다. 상태 코드: ${response.statusCode}');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

오류 메시지를 수정하세요

가족 생성 API인데 오류 메시지가 "회원가입에 실패했습니다"로 되어 있습니다.

-        throw Exception('회원가입에 실패했습니다. 상태 코드: ${response.statusCode}');
+        throw Exception('가족 생성에 실패했습니다. 상태 코드: ${response.statusCode}');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (response.statusCode == 200 || response.statusCode == 201) {
return jsonDecode(response.body);
} else {
throw Exception('회원가입에 실패했습니다. 상태 코드: ${response.statusCode}');
}
if (response.statusCode == 200 || response.statusCode == 201) {
return jsonDecode(response.body);
} else {
throw Exception('가족 생성에 실패했습니다. 상태 코드: ${response.statusCode}');
}
🤖 Prompt for AI Agents
In frontend/ongi/lib/services/code_service.dart between lines 28 and 32, the
error message incorrectly states "회원가입에 실패했습니다" which means "Failed to sign up"
but this is for the family creation API. Update the exception message to
accurately reflect the family creation failure, such as "가족 생성에 실패했습니다" and keep
the status code included.

Comment on lines +17 to +26
final response = await http.post(
Uri.parse('$baseUrl/family'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
},
body: jsonEncode({
'name': name,
}),
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

HTTP 요청에 타임아웃을 추가하세요

네트워크 요청이 무한정 대기하는 것을 방지하기 위해 타임아웃 설정을 추가하는 것이 좋습니다.

     try {
       final response = await http.post(
         Uri.parse('$baseUrl/family'),
         headers: {
           'Content-Type': 'application/json',
           'Authorization': 'Bearer $accessToken',
         },
         body: jsonEncode({
           'name': name,
         }),
-      );
+      ).timeout(const Duration(seconds: 10));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
final response = await http.post(
Uri.parse('$baseUrl/family'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
},
body: jsonEncode({
'name': name,
}),
);
final response = await http.post(
Uri.parse('$baseUrl/family'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
},
body: jsonEncode({
'name': name,
}),
).timeout(const Duration(seconds: 10));
🤖 Prompt for AI Agents
In frontend/ongi/lib/services/code_service.dart around lines 17 to 26, the HTTP
POST request does not have a timeout set, which can cause the app to wait
indefinitely if the network is slow or unresponsive. Add a timeout duration to
the http.post call by chaining a timeout method with a reasonable duration
(e.g., 10 seconds) to ensure the request fails gracefully if it takes too long.

Comment on lines +133 to +134
final prefs = await SharedPreferences.getInstance();
final email = prefs.getString('signup_email') ?? '';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

SharedPreferences 키 이름을 명확하게 변경하세요

로그인 화면에서 'signup_email'이라는 키를 사용하는 것은 혼란을 줄 수 있습니다.

                             final prefs = await SharedPreferences.getInstance();
-                            final email = prefs.getString('signup_email') ?? '';
+                            final email = prefs.getString('user_email') ?? '';

또한 이메일이 없을 경우의 처리도 추가하는 것이 좋습니다:

if (email.isEmpty) {
  _showErrorSnackBar('이메일 정보가 없습니다. 다시 로그인해주세요.');
  return;
}
🤖 Prompt for AI Agents
In frontend/ongi/lib/screens/login/login_pw_screen.dart at lines 133-134, rename
the SharedPreferences key from 'signup_email' to a clearer name like
'login_email' to avoid confusion. Additionally, add a check after retrieving the
email to handle the case when it is empty by showing an error snackbar with a
message like '이메일 정보가 없습니다. 다시 로그인해주세요.' and return early to prevent further
processing.

Comment on lines +83 to +106
child: TextField(
controller: _passwordCtrl,
keyboardType: TextInputType.visiblePassword,
style: const TextStyle(fontSize: 25, color: AppColors.ongiOrange),
decoration: InputDecoration(
hintText: 'PASSWORD',
hintStyle:
TextStyle(color: Colors.grey),
contentPadding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 13),
filled: true,
fillColor: Colors.transparent,
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
focusedBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
),
),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

비밀번호 필드에 보안 설정을 추가하세요

비밀번호 입력 필드가 평문으로 표시되고 있습니다. 보안을 위해 obscureText를 사용해야 합니다.

               child: TextField(
                 controller: _passwordCtrl,
-                keyboardType: TextInputType.visiblePassword,
+                obscureText: true,
+                keyboardType: TextInputType.text,
                 style: const TextStyle(fontSize: 25, color: AppColors.ongiOrange),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
child: TextField(
controller: _passwordCtrl,
keyboardType: TextInputType.visiblePassword,
style: const TextStyle(fontSize: 25, color: AppColors.ongiOrange),
decoration: InputDecoration(
hintText: 'PASSWORD',
hintStyle:
TextStyle(color: Colors.grey),
contentPadding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 13),
filled: true,
fillColor: Colors.transparent,
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
focusedBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
),
),
child: TextField(
controller: _passwordCtrl,
+ obscureText: true,
+ keyboardType: TextInputType.text,
style: const TextStyle(fontSize: 25, color: AppColors.ongiOrange),
decoration: InputDecoration(
hintText: 'PASSWORD',
hintStyle: TextStyle(color: Colors.grey),
contentPadding: const EdgeInsets.symmetric(
horizontal: 24, vertical: 13),
filled: true,
fillColor: Colors.transparent,
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
focusedBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: AppColors.ongiOrange, width: 1),
borderRadius: BorderRadius.circular(20),
),
),
),
🤖 Prompt for AI Agents
In frontend/ongi/lib/screens/login/login_pw_screen.dart between lines 83 and
106, the password input field currently displays the entered text in plain view,
which is a security risk. To fix this, add the property obscureText: true to the
TextField widget to mask the password input and enhance security.

Comment on lines +13 to +14
Future<void> _setModeAndRegister(BuildContext context, String mode) async {
final scaffoldMessenger = ScaffoldMessenger.of(context);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

사용하지 않는 변수를 제거하세요

scaffoldMessenger 변수가 선언되었지만 사용되지 않습니다.

   Future<void> _setModeAndRegister(BuildContext context, String mode) async {
-    final scaffoldMessenger = ScaffoldMessenger.of(context);
     ScaffoldMessenger.of(context).showSnackBar(
🤖 Prompt for AI Agents
In frontend/ongi/lib/screens/signup/mode_screen.dart around lines 13 to 14, the
variable scaffoldMessenger is declared but never used. Remove the declaration of
scaffoldMessenger to clean up the code and avoid unused variable warnings.

Neibce pushed a commit to 2025-PNU-SW-Hackathon/PNUSW-2025-OnGi-10 that referenced this pull request Aug 25, 2025
* fix: pretendard 파일 수정

* feat: 시작 화면 구현 및 이메일 유효성 검사 구현 완료

* fix: emailScreen 배경 수정

* feat: signup 기능 구현

* fix: familyname_screen.dart 디자인 수정

* feat: 가족 생성 및 기존 가족 참가 api 연결, snackbar 추가, 로딩 인디케이터 수정, 회원가입 이메일 한글 예외 처리 추가

* fix: 필요 없는 코드 수정

* feat: login 화면 구현 및 api 연결 완료
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant