작은 화면(폰) 레이아웃만 데스크탑과 톤을 맞춤 - 큰 화면(사이드바/좌석
그리드)은 그대로 둠.
- 검정 배경 요약바(_buildSummaryCards)를 없애고, 데스크탑 사이드바와
같은 흰색 캡슐(_sidebarStatPill)을 가로로 3개 배치. 탭하면 바로
전체/출석/미출석 필터가 적용됨
- 전체 학생 수 캡슐 바로 아래 있던 필터 칩 줄(전체/출석자/미출석자 +
학년 칩)은 위 캡슐과 기능이 겹쳐서 제거하고, 데스크탑과 동일한
"학생 나눠보기"(런치패드 학년 필터 메뉴) 버튼으로 대체
- 더 이상 안 쓰는 _buildSummaryCards/_summaryCard/_buildFilterChips 삭제
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
나머지 화면들(교사 회원가입, 학생 계정 관리, 관리자 대시보드, 스마트기기
반출 신청/대장, NFC 태그 쓰기/체크인, 비밀번호 변경)에 남아있던 예전
ScaffoldMessenger.showSnackBar를 전부 AppNotice로 교체.
- AppNotice.show에 선택적 color 파라미터 추가 - NFC 태그 쓰기/체크인
화면처럼 성공(초록)/실패(빨강) 등 색으로 구분하던 알림은 그 색을
그대로 유지하면서 모양/위치만 통일된 알약 스타일로 바뀜
- 알림 직후 화면을 전환(로그인 성공 후 대시보드 이동, 회원가입 성공 후
로그인 화면 복귀 등)하던 곳들도, AppNotice가 화면(Scaffold)이 아니라
전역 Overlay를 쓰기 때문에 전환 중에 알림이 잘리지 않고 새 화면 위에
계속 보임 (기존 스낵바 방식보다 개선됨)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
_runAction이 아직 예전 ScaffoldMessenger.showSnackBar(하단 스낵바)를
쓰고 있어서, 하교 처리/반출 허용/출석시간 설정/테스트 초기화 결과가
다른 화면과 다르게 아래에서 떴던 문제 수정. AppNotice.show로 교체해서
웹은 왼쪽 위, 앱은 하단(기존 위치)에 나머지 화면들과 같은 스타일로 뜨게 함.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 상단 검정 AppBar 대신 투명 배경 + 가운데 둥근 알약 제목으로 변경
- 새로고침/자습실 출석시간 설정/반출 허용 시간 설정/하교 처리/테스트용
초기화를 "자습실 시간 설정 메뉴" 하나로 모아서, 메인 대시보드의
로그아웃/설정 메뉴와 같은 런치패드 스타일(배경 블러) 오버레이로 표시
- 데스크탑은 사이드바에 전용 버튼을 추가하고, 폰에서는 앱바의 "..."
아이콘으로 같은 메뉴에 접근 (모바일 기능 접근성 유지)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
80명 이상인 자습실 인원을 스크롤 없이 최대한 한눈에 보기 위해,
데스크탑(교실 컴퓨터) 레이아웃을 왼쪽 요약/필터 사이드바 + 오른쪽
촘촘한 좌석 그리드 구조로 바꿈. 학생 한 명당 칸을 92x62 크기로 작게
줄여 한 화면에 훨씬 많은 인원이 들어가게 했고, 사이드바의 인원 수
캡슐(전체/출석/미출석)을 눌러 바로 필터링할 수 있게 함. 학년 필터는
런치패드 스타일 오버레이 메뉴로 이동. 모바일 카드 리스트 레이아웃은
그대로 유지.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
임의로 20% 축소하던 방식 대신, 1x1 타일 목표 크기(184px, 계정 프로필
카드와 비슷한 크기)를 기준으로 그리드 폭을 계산하도록 변경. 화면이
목표 크기보다 넓으면 가운데로 모아 여백을 주고, 좁으면(폰) 화면 폭에
그대로 맞춘다.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 화면이 넓어져도 열 개수를 6개까지 늘리지 않고 4열에서 고정
- 그리드 캔버스 자체 너비를 700px로 제한하고 20% 더 줄여서, 타일이
화면을 꽉 채우는 느낌 대신 가운데에 여백을 두고 정갈하게 보이게 함
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 화면 전체를 차지하던 색상 배너를 작은 둥근 프로필 카드로 교체하고 가운데에 배치
- 앱바는 ">" 메뉴 버튼만 올라가는 투명한 얇은 바로 변경
- 균일한 그리드 대신 flutter_staggered_grid_view로 타일마다 크기가 다른
매이슨리 레이아웃 적용 (NFC 태그는 세로로 길게, 실시간 출석/서버 DB 제어는
가로로 넓게) - 화면 폭에 따라 열 개수가 자동으로 바뀌어 폰에서도 안 깨짐
- 가로로 넓지만 낮은 타일에서 내용이 넘치지 않도록 카드 배율 계산을
가로/세로 중 작은 쪽 기준으로 변경
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 좌우 슬라이드 대신 맥북 런치패드처럼 확대+페이드로 나타나고 전환 중 뒤 화면이
블러 처리되는 LaunchpadPageRoute 추가, 대시보드의 모든 기능 타일 이동에 적용
- 오른쪽 위 설정 아이콘 + 로그아웃 아이콘 2개를 ">" 버튼 1개로 통합하고,
누르면 로그아웃/설정 메뉴가 런치패드 스타일 오버레이(배경 블러 유지)로 뜨게 변경
- 기능 타일을 누를 때 뜨는 안내 메시지를 스낵바 대신 알약(pill) 모양 알림으로 교체
(AppNotice) - 웹에서는 왼쪽 위, 앱에서는 기존처럼 아래쪽에 표시. 푸시 알림과는 무관.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 폰처럼 작은 화면에서 6칸 고정 격자 때문에 레이아웃이 깨지는 문제로,
타일 드래그 이동/크기조절 기능을 kTileEditingEnabled 플래그로 임시 비활성화
(관련 코드는 그대로 유지 - 작은 화면 대응 방안 마련 후 플래그만 켜면 재사용 가능)
- 비활성화 상태에서는 화면 폭에 따라 열이 자동으로 줄어드는 기본 그리드 사용
- 설정 화면의 "UI 편집" 항목은 비활성화 표시로 안내
- 로그인 화면에 "로그인 상태 유지" 체크박스 추가 (기본 체크됨, 해제 시 세션 저장 안 함)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 이름/부제, "스마트 관리 시스템 메뉴" 제목을 중앙 정렬
- 타일을 1x1~4x4 크기로 자유 배치할 수 있는 편집 모드 추가 (6x4 캔버스, 삼성 One UI 위젯 편집 방식)
- 타일 배치는 계정별로 서버에 저장/복원 (dashboard_layout_controller.dart)
- 설정 화면(톱니바퀴 아이콘) > "UI 편집" 진입점 추가
- shared_preferences로 로그인 유지 기능 추가 (비밀번호는 저장하지 않음)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
앱 전체 MaterialApp의 ThemeData가 여전히 primarySwatch: Colors.indigo
였던 게 진짜 원인이었음 — 개별 화면 색은 고쳤지만, 기본 위젯 스타일
(포커스 안 된 텍스트필드 밑줄, FilterChip 선택 색 등)은 전부 이
전역 테마를 그대로 따라가고 있어서 여전히 예전 색으로 보였음.
ColorScheme을 AppPalette 기준으로 재구성해 해결.
추가로 팔레트 작업에서 빠졌던 화면들도 마무리:
- teacher_register_screen.dart (교사 회원가입)
- nfc_tag_writer_screen.dart (NFC 태그 쓰기)
- change_password_screen.dart (미사용이지만 일관성을 위해 정리)
- teacher_attendance_page.dart의 주머니 번호 칩 색상
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
화면 타이틀, 스낵바/다이얼로그 메시지, 백그라운드 알림 문구 등
사용자에게 노출되는 텍스트에서 이모티콘을 전부 제거 (코드 주석은
대상 아님). 아이콘 위젯은 그대로 유지.
main_dashboard.dart의 "계정 강제 삭제" 타일 아이콘 색상도 빨간색
대신 다른 타일과 동일한 검정(AppPalette.ink)으로 통일.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
coolors.co 무채색 팔레트(1c1c1c-daddd8-ecebe4-eef0f2-fafaff)를
lib/theme/app_palette.dart에 정의하고, 로그인/대시보드/출석 확인/
학생 계정 관리/스마트기기 반출(신청·대장)/관리자 화면 전반의
배너·배경·카드·기본 버튼 색을 이 팔레트로 교체.
기능적으로 의미 있는 색(위반/미출석/삭제/거절 등 경고성 빨간색,
승인 대기 등 상태 표시)은 그대로 유지 — 구조적/장식적 색상만
무채색으로 통일해 위험한 동작이 시각적으로 더 도드라지게 함.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
StudentDashboard, TeacherDashboard, AdminDashboard(진입 라우팅)를
MainDashboard 하나로 합치고, 역할(role)에 따라 배너 색상/문구와
보이는 타일만 달라지게 함. 그리드 레이아웃/카드 디자인은 이제
한 곳에서만 관리되어, 앞으로 UI를 고치면 모든 역할에 자동 적용됨.
- 2061(개발자) 계정에 기존에 빠져있던 "스마트기기 반출 대장" 타일 추가
- role=='admin' 실 계정도 이제 학생 계정 관리/출석 확인 등 교사 기능에
접근 가능 (관리자는 교사 권한을 포함하는 것으로 정리)
- 작은 DB 초기화 전용 화면(admin_dashboard.dart)은 "서버 DB 제어"
타일의 목적지로만 유지, 로그인 직후 랜딩 화면 역할은 제거
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
자동 감지 하드웨어가 아직 없어서, 승인된(APPROVED) 요청에 선생님이
기기를 실제로 돌려받았을 때 누르는 "기기 반납 확인" 버튼을 추가.
누르면 상태가 반납완료로 바뀌어 10분 후 미반납 알림이 더 이상
가지 않는다 (백엔드는 별도 저장소에서 이미 배포 완료).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
계획 변경에 따라 저울/아두이노 기반 픽업·반납·무단반출 감지를 없애고
순수 시간 기반 알림만 남김 (백엔드는 별도 저장소에서 이미 배포 완료).
- 승인 시 현재 로그인한 선생님의 teacherId/teacherName을 서버에 함께
전송하여 저장하고, 대장에 "OOO 선생님이 허용했습니다" 표시
- 반납 시간 초과 알림은 승인한 선생님에게만 전송 (서버가 해당 선생님의
등록된 기기를 못 찾으면 전체 선생님에게 대체 발송)
- 대장 카드의 상태 표시에서 IN_USE/RETURNED(픽업 대기) 문구 제거
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
학생 타일의 이름/상태/학년칩 폰트와 아이콘 크기를 키워 가독성을
높이고, 계정 추가/엑셀 등록 정사각형 칸의 크기를 학생 목록 타일과
동일한 크기(tileSize)로 통일했다.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
계정 추가/엑셀 등록 정사각형 칸은 기존 크기의 25%로 축소하고,
학생 목록 타일은 기존보다 50% 더 큰 정사각형으로 확대. 목록 폭은
더 이상 위 두 칸 폭에 종속되지 않고 전체 폭을 사용하도록 변경.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
웹 넓은 화면에서 계정 추가/엑셀 일괄 등록을 정사각형 2칸으로
나란히 배치(왼쪽 계정 추가, 오른쪽 엑셀 등록)하고, 그 아래 학생
목록을 두 칸 합친 폭에 맞춘 타일 그리드로 변경. 각 타일은 아이콘/
이름/상태/액션 버튼을 모두 중앙 정렬. 폰 화면은 기존처럼 세로 스택
유지.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
웹(넓은 화면)에서 항상 2개씩 줄바꿈되던 버그 수정. 학생 대시보드와
동일하게 LayoutBuilder로 폭이 800 이상이면 한 줄에 5개, 좁으면
기존처럼 2개씩 보이도록 함.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
패드는 NFC를 못 쓰므로 학생이 사용 시간/목적을 신청하면 선생님이
대시보드의 반출 대장에서 승인/거절하는 흐름을 추가. 저울-아두이노
연동(무게 기반 픽업/반납 감지)은 백엔드에 구현되어 있으나 실기기
연동은 추후 진행.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 두 화면이 서로 다른 기능만 갖고 있던 문제 해결: 선생님 화면(엑셀 일괄등록,
학년 지정, 커스텀 초기비번)에 마스터 화면에만 있던 실시간 학생 목록 조회 +
기기 리셋(학생이 폰 바꿨을 때 재등록용) 기능을 합침
- 학번을 직접 타이핑하던 블라인드 학년변경/삭제 다이얼로그를 목록의
행별 액션(학년 칩, 기기 리셋 버튼, 삭제 버튼)으로 교체
- 계정 생성/삭제/학년변경 성공 시 목록 자동 새로고침
- 마스터(2061) 계정의 "학생 계정 관리" 카드도 이 통합 화면으로 연결하고,
중복되던 student_management_screen.dart / student_management_controller.dart 삭제
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 학생 계정 관리 화면에 드래그앤드롭/클릭 업로드 영역 추가
(excel, desktop_drop, file_picker 패키지 도입)
- .xlsx 파싱 → 미리보기 팝업 → 확인 후 한 명씩 순서대로 계정 생성,
결과(성공/실패)를 요약해서 보여줌. 초기 비밀번호는 1234 고정
- file_picker의 웹 구현체가 pickFile(s)를 아직 구현하지 않아서
(UnimplementedError) 웹에서는 package:web으로 직접 <input type=file>을
다뤄서 우회 (lib/function/excel_file_picker_web.dart), 다른 플랫폼은
기존 file_picker 사용 (excel_file_picker_io.dart)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 학생 계정 관리 화면에 학번으로 학년을 지정/변경하는 카드+다이얼로그 추가
- 계정 생성 성공 판정을 HTTP 상태코드가 아닌 응답 status 필드로 정확히 확인하도록 수정
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 실시간 출석 현황을 학년별 섹션으로 묶어서 표시 (백엔드에 grade 필드 추가)
- 학생 계정 추가 폼에 학년 선택 드롭다운 추가
- 학생 계정 생성/삭제가 실제로는 존재하지 않는 엔드포인트를 호출하던
버그 수정 (/api/users/register-student, /api/users/delete/{id} →
/api/users/create, /api/users/delete)
- 학생 대시보드(개발자 모드) 카드 그리드가 넓은 화면에서 과도하게
커지던 레이아웃 버그 수정, 웹은 5열/폰은 2열로 반응형 처리
- 버전 1.2.0+6
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- iOS는 조도 센서/백그라운드 서비스가 불가능해서 근접센서(UIDevice
proximityMonitoring) + 가이드 접근 안내로 대체 구현 (Core NFC와 마찬가지로
네이티브 플러그인 필요해서 ProximityMonitorPlugin.swift 추가)
- 교사 대시보드 실시간 출석 현황: 모바일 리스트/데스크톱 표를 타일 그리드로
통일해서 한눈에 보기 쉽게 변경
- 서버를 학교 자체 서버(Cloudflare Tunnel, api.backsanhi.shop)로 이전하면서
기본 BASE_URL 갱신
- Firebase CLI 로컬 캐시(.firebase/)는 소스가 아니라 gitignore 처리
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- config.dart의 baseUrl/webVapidKey와 학교 이름을 String.fromEnvironment로 전환
- 기본값은 기존 백산고 값 그대로라 인자 없이 빌드하면 지금과 동일하게 동작
- 다른 학교는 --dart-define=BASE_URL=...=SCHOOL_NAME=...=WEB_VAPID_KEY=...로 빌드