added sth
This commit is contained in:
@@ -1,198 +0,0 @@
|
||||
import SwiftUI
|
||||
import Combine
|
||||
|
||||
// MARK: - Models
|
||||
|
||||
struct LessonBlock: Codable, Identifiable {
|
||||
var id: String { "\(day)-\(period)" }
|
||||
let day: String
|
||||
let period: String
|
||||
let timeStart: String
|
||||
let timeEnd: String
|
||||
let room: String
|
||||
let subject: String
|
||||
let group: String
|
||||
let teacher: String
|
||||
let color: String // "pink", "yellow", "green"
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case day, period
|
||||
case timeStart = "time_start"
|
||||
case timeEnd = "time_end"
|
||||
case room, subject, group, teacher, color
|
||||
}
|
||||
}
|
||||
|
||||
struct TimetableResponse: Codable {
|
||||
let day: String
|
||||
let lessons: [LessonBlock]
|
||||
}
|
||||
|
||||
// MARK: - ViewModel
|
||||
|
||||
class TimetableViewModel: ObservableObject {
|
||||
@Published var dayName: String = ""
|
||||
@Published var lessons: [LessonBlock] = []
|
||||
@Published var isLoading = true
|
||||
@Published var errorMessage: String?
|
||||
|
||||
func fetchTimetable() {
|
||||
isLoading = true
|
||||
|
||||
guard let url = Bundle.main.url(forResource: "mock", withExtension: "json"),
|
||||
let data = try? Data(contentsOf: url) else {
|
||||
errorMessage = "mock.json nicht gefunden"
|
||||
isLoading = false
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let decoded = try JSONDecoder().decode(TimetableResponse.self, from: data)
|
||||
self.dayName = decoded.day
|
||||
self.lessons = decoded.lessons
|
||||
} catch {
|
||||
errorMessage = "JSON Fehler: \(error.localizedDescription)"
|
||||
}
|
||||
|
||||
isLoading = false
|
||||
}
|
||||
|
||||
|
||||
func loadMockData() {
|
||||
dayName = "Montag"
|
||||
lessons = [
|
||||
LessonBlock(day: "Montag", period: "1.", timeStart: "08:00", timeEnd: "08:55",
|
||||
room: "255", subject: "D", group: "G2", teacher: "VanC", color: "pink"),
|
||||
LessonBlock(day: "Montag", period: "2. & 3.", timeStart: "08:55", timeEnd: "10:25",
|
||||
room: "255", subject: "M", group: "G2", teacher: "ScLa", color: "yellow"),
|
||||
LessonBlock(day: "Montag", period: "4.", timeStart: "10:55", timeEnd: "11:40",
|
||||
room: "254", subject: "E", group: "G4", teacher: "RadF", color: "green"),
|
||||
LessonBlock(day: "Montag", period: "5.", timeStart: "11:40", timeEnd: "12:25",
|
||||
room: "255", subject: "D", group: "G2", teacher: "VanC", color: "pink"),
|
||||
]
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Lesson Block View
|
||||
|
||||
struct LessonBlockView: View {
|
||||
let lesson: LessonBlock
|
||||
|
||||
var blockColor: Color {
|
||||
switch lesson.color {
|
||||
case "pink": return Color(red: 1.0, green: 0.85, blue: 0.88)
|
||||
case "yellow": return Color(red: 1.0, green: 1.0, blue: 0.82)
|
||||
case "green": return Color(red: 0.78, green: 0.95, blue: 0.84)
|
||||
default: return Color.gray.opacity(0.3)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
// Top row: Room | Subject Group | Teacher
|
||||
HStack {
|
||||
Text(lesson.room)
|
||||
.font(.system(size: 14, weight: .bold, design: .monospaced))
|
||||
Spacer()
|
||||
Text("\(lesson.subject) \(lesson.group)")
|
||||
.font(.system(size: 14, weight: .bold, design: .monospaced))
|
||||
Spacer()
|
||||
Text(lesson.teacher)
|
||||
.font(.system(size: 14, weight: .bold, design: .monospaced))
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.top, 6)
|
||||
|
||||
// Bottom row: Period | Time
|
||||
HStack {
|
||||
Text(lesson.period)
|
||||
.font(.system(size: 13, weight: .semibold, design: .monospaced))
|
||||
Spacer()
|
||||
Text("\(lesson.timeStart)-\(lesson.timeEnd)")
|
||||
.font(.system(size: 13, weight: .semibold, design: .monospaced))
|
||||
}
|
||||
.padding(.horizontal, 8)
|
||||
.padding(.bottom, 6)
|
||||
}
|
||||
.background(blockColor)
|
||||
.cornerRadius(4)
|
||||
.overlay(
|
||||
RoundedRectangle(cornerRadius: 4)
|
||||
.stroke(Color.black.opacity(0.3), lineWidth: 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Main Content View
|
||||
|
||||
struct ContentView: View {
|
||||
@StateObject private var viewModel = TimetableViewModel()
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if viewModel.isLoading {
|
||||
ProgressView("Laden...")
|
||||
} else if let error = viewModel.errorMessage {
|
||||
VStack {
|
||||
Text(error)
|
||||
.font(.caption)
|
||||
.foregroundColor(.red)
|
||||
Button("Erneut versuchen") {
|
||||
viewModel.fetchTimetable()
|
||||
}
|
||||
.font(.caption2)
|
||||
}
|
||||
} else {
|
||||
ScrollView {
|
||||
VStack(spacing: 4) {
|
||||
Text(viewModel.dayName)
|
||||
.font(.system(size: 16, weight: .bold))
|
||||
.foregroundColor(.white)
|
||||
.padding(.bottom, 4)
|
||||
|
||||
ForEach(viewModel.lessons) { lesson in
|
||||
LessonBlockView(lesson: lesson)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
viewModel.fetchTimetable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - App Entry Point
|
||||
|
||||
@main
|
||||
struct StundenplanApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Expected JSON format from your backend:
|
||||
|
||||
{
|
||||
"day": "Montag",
|
||||
"lessons": [
|
||||
{
|
||||
"period": "1.",
|
||||
"time_start": "08:00",
|
||||
"time_end": "08:55",
|
||||
"room": "255",
|
||||
"subject": "D",
|
||||
"group": "G2",
|
||||
"teacher": "VanC",
|
||||
"color": "pink",
|
||||
"day": "Montag"
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user