Version casi lista
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import SwiftUI
|
||||
|
||||
extension Color {
|
||||
// Primary
|
||||
static let mealMoodCoral = Color(hex: "#FFB4A2")
|
||||
static let mealMoodMint = Color(hex: "#B8E6D5")
|
||||
|
||||
// Background
|
||||
static let mealMoodBackground = Color(hex: "#FFF9F5")
|
||||
static let mealMoodSurface = Color.white
|
||||
|
||||
// Text
|
||||
static let mealMoodTextPrimary = Color(hex: "#2D2D2D")
|
||||
static let mealMoodTextSecondary = Color(hex: "#6B6B6B")
|
||||
|
||||
// Feedback
|
||||
static let mealMoodSuccess = Color(hex: "#A8D5BA")
|
||||
static let mealMoodWarning = Color(hex: "#FFD6A5")
|
||||
static let mealMoodError = Color(hex: "#FF9999")
|
||||
|
||||
init(hex: String) {
|
||||
let scanner = Scanner(string: hex)
|
||||
scanner.currentIndex = hex.hasPrefix("#") ? hex.index(after: hex.startIndex) : hex.startIndex
|
||||
var rgb: UInt64 = 0
|
||||
scanner.scanHexInt64(&rgb)
|
||||
let r = Double((rgb & 0xFF0000) >> 16) / 255.0
|
||||
let g = Double((rgb & 0x00FF00) >> 8) / 255.0
|
||||
let b = Double(rgb & 0x0000FF) / 255.0
|
||||
self.init(red: r, green: g, blue: b)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
import Foundation
|
||||
|
||||
extension Date {
|
||||
func addingDays(_ days: Int) -> Date {
|
||||
Calendar.current.date(byAdding: .day, value: days, to: self)!
|
||||
}
|
||||
|
||||
func addingMinutes(_ minutes: Int) -> Date {
|
||||
Calendar.current.date(byAdding: .minute, value: minutes, to: self)!
|
||||
}
|
||||
|
||||
func startOfWeek() -> Date {
|
||||
let calendar = Calendar.current
|
||||
var cal = calendar
|
||||
cal.firstWeekday = 2 // Monday
|
||||
let components = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
|
||||
return cal.date(from: components) ?? self
|
||||
}
|
||||
|
||||
func dayOfWeekIndex() -> Int {
|
||||
let calendar = Calendar.current
|
||||
let weekday = calendar.component(.weekday, from: self)
|
||||
// Convert to 0=Monday format
|
||||
return (weekday + 5) % 7
|
||||
}
|
||||
|
||||
var isToday: Bool {
|
||||
Calendar.current.isDateInToday(self)
|
||||
}
|
||||
|
||||
var isPast: Bool {
|
||||
self < Calendar.current.startOfDay(for: Date())
|
||||
}
|
||||
|
||||
func formattedWeekRange() -> String {
|
||||
let endDate = self.addingDays(6)
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = Locale.current
|
||||
|
||||
let dayFormatter = DateFormatter()
|
||||
dayFormatter.dateFormat = "d"
|
||||
|
||||
let monthFormatter = DateFormatter()
|
||||
monthFormatter.dateFormat = "MMM"
|
||||
|
||||
let startDay = dayFormatter.string(from: self)
|
||||
let endDay = dayFormatter.string(from: endDate)
|
||||
let month = monthFormatter.string(from: endDate)
|
||||
|
||||
return "\(startDay)-\(endDay) \(month)"
|
||||
}
|
||||
|
||||
func startOfMonth() -> Date {
|
||||
let calendar = Calendar.current
|
||||
let components = calendar.dateComponents([.year, .month], from: self)
|
||||
return calendar.date(from: components) ?? self
|
||||
}
|
||||
|
||||
func addingMonths(_ months: Int) -> Date {
|
||||
Calendar.current.date(byAdding: .month, value: months, to: self) ?? self
|
||||
}
|
||||
|
||||
func monthYearLabel(locale: Locale = .current) -> String {
|
||||
let formatter = DateFormatter()
|
||||
formatter.locale = locale
|
||||
formatter.setLocalizedDateFormatFromTemplate("LLLL yyyy")
|
||||
return formatter.string(from: self)
|
||||
}
|
||||
}
|
||||
|
||||
func combineDateAndTime(date: Date, time: Date) -> Date {
|
||||
let calendar = Calendar.current
|
||||
let dateComponents = calendar.dateComponents([.year, .month, .day], from: date)
|
||||
let timeComponents = calendar.dateComponents([.hour, .minute], from: time)
|
||||
|
||||
var combined = DateComponents()
|
||||
combined.year = dateComponents.year
|
||||
combined.month = dateComponents.month
|
||||
combined.day = dateComponents.day
|
||||
combined.hour = timeComponents.hour
|
||||
combined.minute = timeComponents.minute
|
||||
|
||||
return calendar.date(from: combined) ?? date
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import SwiftUI
|
||||
|
||||
extension Font {
|
||||
static let mealMoodH1 = Font.system(size: 28, weight: .bold, design: .rounded)
|
||||
static let mealMoodH2 = Font.system(size: 20, weight: .semibold, design: .rounded)
|
||||
static let mealMoodH3 = Font.system(size: 18, weight: .semibold, design: .rounded)
|
||||
|
||||
static let mealMoodBody = Font.system(size: 16, weight: .regular, design: .default)
|
||||
static let mealMoodBodyBold = Font.system(size: 16, weight: .semibold, design: .default)
|
||||
|
||||
static let mealMoodCaption = Font.system(size: 12, weight: .medium, design: .default)
|
||||
static let mealMoodSmall = Font.system(size: 14, weight: .regular, design: .default)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import Foundation
|
||||
|
||||
func localizedString(_ key: String, language: AppLanguage) -> String {
|
||||
let resolvedLanguage = language.resolved()
|
||||
|
||||
if let path = Bundle.main.path(forResource: resolvedLanguage.localeIdentifier, ofType: "lproj"),
|
||||
let bundle = Bundle(path: path) {
|
||||
let localized = bundle.localizedString(forKey: key, value: nil, table: nil)
|
||||
if localized != key {
|
||||
return localized
|
||||
}
|
||||
}
|
||||
|
||||
if let path = Bundle.main.path(forResource: "en", ofType: "lproj"),
|
||||
let bundle = Bundle(path: path) {
|
||||
let english = bundle.localizedString(forKey: key, value: nil, table: nil)
|
||||
if english != key {
|
||||
return english
|
||||
}
|
||||
}
|
||||
|
||||
return NSLocalizedString(key, comment: "")
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import SwiftUI
|
||||
|
||||
struct MealCardStyle: ViewModifier {
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.background(Color.mealMoodSurface)
|
||||
.cornerRadius(16)
|
||||
.shadow(color: Color.black.opacity(0.05), radius: 8, y: 4)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 16)
|
||||
.stroke(Color(hex: "#F0F0F0"), lineWidth: 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
func mealCardStyle() -> some View {
|
||||
modifier(MealCardStyle())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user