feat: 초기 프로젝트 설정 및 LunchPick 앱 구현

LunchPick(오늘 뭐 먹Z?) Flutter 앱의 초기 구현입니다.

주요 기능:
- 네이버 지도 연동 맛집 추가
- 랜덤 메뉴 추천 시스템
- 날씨 기반 거리 조정
- 방문 기록 관리
- Bluetooth 맛집 공유
- 다크모드 지원

기술 스택:
- Flutter 3.8.1+
- Riverpod 상태 관리
- Hive 로컬 DB
- Clean Architecture

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-07-30 19:03:28 +09:00
commit 85fde36157
237 changed files with 30953 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
import 'package:hive/hive.dart';
part 'recommendation_record.g.dart';
@HiveType(typeId: 3)
class RecommendationRecord extends HiveObject {
@HiveField(0)
final String id;
@HiveField(1)
final String restaurantId;
@HiveField(2)
final DateTime recommendationDate;
@HiveField(3)
final bool visited;
@HiveField(4)
final DateTime createdAt;
RecommendationRecord({
required this.id,
required this.restaurantId,
required this.recommendationDate,
required this.visited,
required this.createdAt,
});
}

View File

@@ -0,0 +1,138 @@
import 'package:hive/hive.dart';
part 'restaurant.g.dart';
@HiveType(typeId: 0)
class Restaurant extends HiveObject {
@HiveField(0)
final String id;
@HiveField(1)
final String name;
@HiveField(2)
final String category;
@HiveField(3)
final String subCategory;
@HiveField(4)
final String? description;
@HiveField(5)
final String? phoneNumber;
@HiveField(6)
final String roadAddress;
@HiveField(7)
final String jibunAddress;
@HiveField(8)
final double latitude;
@HiveField(9)
final double longitude;
@HiveField(10)
final DateTime? lastVisitDate;
@HiveField(11)
final DataSource source;
@HiveField(12)
final DateTime createdAt;
@HiveField(13)
final DateTime updatedAt;
@HiveField(14)
final String? naverPlaceId;
@HiveField(15)
final String? naverUrl;
@HiveField(16)
final String? businessHours;
@HiveField(17)
final DateTime? lastVisited;
@HiveField(18)
final int visitCount;
Restaurant({
required this.id,
required this.name,
required this.category,
required this.subCategory,
this.description,
this.phoneNumber,
required this.roadAddress,
required this.jibunAddress,
required this.latitude,
required this.longitude,
this.lastVisitDate,
required this.source,
required this.createdAt,
required this.updatedAt,
this.naverPlaceId,
this.naverUrl,
this.businessHours,
this.lastVisited,
this.visitCount = 0,
});
Restaurant copyWith({
String? id,
String? name,
String? category,
String? subCategory,
String? description,
String? phoneNumber,
String? roadAddress,
String? jibunAddress,
double? latitude,
double? longitude,
DateTime? lastVisitDate,
DataSource? source,
DateTime? createdAt,
DateTime? updatedAt,
String? naverPlaceId,
String? naverUrl,
String? businessHours,
DateTime? lastVisited,
int? visitCount,
}) {
return Restaurant(
id: id ?? this.id,
name: name ?? this.name,
category: category ?? this.category,
subCategory: subCategory ?? this.subCategory,
description: description ?? this.description,
phoneNumber: phoneNumber ?? this.phoneNumber,
roadAddress: roadAddress ?? this.roadAddress,
jibunAddress: jibunAddress ?? this.jibunAddress,
latitude: latitude ?? this.latitude,
longitude: longitude ?? this.longitude,
lastVisitDate: lastVisitDate ?? this.lastVisitDate,
source: source ?? this.source,
createdAt: createdAt ?? this.createdAt,
updatedAt: updatedAt ?? this.updatedAt,
naverPlaceId: naverPlaceId ?? this.naverPlaceId,
naverUrl: naverUrl ?? this.naverUrl,
businessHours: businessHours ?? this.businessHours,
lastVisited: lastVisited ?? this.lastVisited,
visitCount: visitCount ?? this.visitCount,
);
}
}
@HiveType(typeId: 1)
enum DataSource {
@HiveField(0)
NAVER,
@HiveField(1)
USER_INPUT
}

View File

@@ -0,0 +1,11 @@
class ShareDevice {
final String code;
final String deviceId;
final DateTime discoveredAt;
ShareDevice({
required this.code,
required this.deviceId,
required this.discoveredAt,
});
}

View File

@@ -0,0 +1,45 @@
import 'package:hive/hive.dart';
part 'user_settings.g.dart';
@HiveType(typeId: 4)
class UserSettings {
@HiveField(0)
final int revisitPreventionDays;
@HiveField(1)
final bool notificationEnabled;
@HiveField(2)
final String notificationTime;
@HiveField(3)
final Map<String, double> categoryWeights;
@HiveField(4)
final int notificationDelayMinutes;
UserSettings({
this.revisitPreventionDays = 7,
this.notificationEnabled = true,
this.notificationTime = "14:00",
Map<String, double>? categoryWeights,
this.notificationDelayMinutes = 90,
}) : categoryWeights = categoryWeights ?? {};
UserSettings copyWith({
int? revisitPreventionDays,
bool? notificationEnabled,
String? notificationTime,
Map<String, double>? categoryWeights,
int? notificationDelayMinutes,
}) {
return UserSettings(
revisitPreventionDays: revisitPreventionDays ?? this.revisitPreventionDays,
notificationEnabled: notificationEnabled ?? this.notificationEnabled,
notificationTime: notificationTime ?? this.notificationTime,
categoryWeights: categoryWeights ?? this.categoryWeights,
notificationDelayMinutes: notificationDelayMinutes ?? this.notificationDelayMinutes,
);
}
}

View File

@@ -0,0 +1,29 @@
import 'package:hive/hive.dart';
part 'visit_record.g.dart';
@HiveType(typeId: 2)
class VisitRecord extends HiveObject {
@HiveField(0)
final String id;
@HiveField(1)
final String restaurantId;
@HiveField(2)
final DateTime visitDate;
@HiveField(3)
final bool isConfirmed;
@HiveField(4)
final DateTime createdAt;
VisitRecord({
required this.id,
required this.restaurantId,
required this.visitDate,
required this.isConfirmed,
required this.createdAt,
});
}

View File

@@ -0,0 +1,21 @@
class WeatherInfo {
final WeatherData current;
final WeatherData nextHour;
WeatherInfo({
required this.current,
required this.nextHour,
});
}
class WeatherData {
final int temperature;
final bool isRainy;
final String description;
WeatherData({
required this.temperature,
required this.isRainy,
required this.description,
});
}