Files
KC-APP/client/app/lib/main.dart
T
linusandClaude Sonnet 5 0886424526 feat(client): Flutter app (web target) — Phase 7 start
Single Flutter codebase under client/app/ with web enabled (mobile/desktop
can be added later; lib/ is platform-agnostic). Talks to the NestJS backend
via a thin REST wrapper; API_BASE is a --dart-define (defaults to the local
backend).

Screens:
- Login: Konfi/guest (invite code), local Teamer password login, Teamer
  invite redemption. Token persisted in shared_preferences, restored on
  start; GET /auth/me drives a role-aware home.
- Workshop-Wahl (guests): loads /wahl/guest/overview, ordered pick of up to
  3 workshops, submits to /wahl/:id/teilnehmer.
- Dateien: /files/:kcId list.
- Chat: channel + message list (read-only; WS send is a follow-up).

State: AppState (ChangeNotifier) exposed via an InheritedNotifier
(AppScope) — no third-party state package. flutter analyze clean,
flutter build web --release passes, one widget smoke test.

Also: interim client/web/ HTML placeholder stays as-is (per plan it is
superseded by this Flutter web build).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 08:52:36 +02:00

59 lines
1.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'api.dart';
import 'screens/home_screen.dart';
import 'screens/login_screen.dart';
void main() {
final state = AppState(Api(http.Client()))..bootstrap();
runApp(KcApp(state: state));
}
/// Minimal InheritedNotifier so screens can read `AppState.of(context)` and
/// rebuild on change — no third-party state management.
class AppScope extends InheritedNotifier<AppState> {
const AppScope({super.key, required AppState state, required super.child})
: super(notifier: state);
static AppState of(BuildContext context) {
final scope = context.dependOnInheritedWidgetOfExactType<AppScope>();
assert(scope != null, 'AppScope missing above this widget');
return scope!.notifier!;
}
}
class KcApp extends StatelessWidget {
const KcApp({super.key, required this.state});
final AppState state;
@override
Widget build(BuildContext context) {
return AppScope(
state: state,
child: MaterialApp(
title: 'KC-App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: const Color(0xFF3B5BA5),
useMaterial3: true,
),
home: const _AuthGate(),
),
);
}
}
class _AuthGate extends StatelessWidget {
const _AuthGate();
@override
Widget build(BuildContext context) {
final state = AppScope.of(context);
if (state.loading) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
}
return state.isLoggedIn ? const HomeScreen() : const LoginScreen();
}
}