feat: ajout de serveurs depuis l'app + charte flamme sombre
Build APK / build (push) Successful in 2m49s
Build APK / build (push) Successful in 2m49s
- backend: GET /api/containers (liste lisible), POST/DELETE /api/servers (serveurs custom persistés en /data/servers.json, mergés aux intégrés), champ custom dans le statut. - app: écran AddServer (form + sélecteur multi-conteneurs filtrable), FAB Ajouter, suppression depuis le détail (serveurs custom only). - thème: palette flamme/chaud sombre (anthracite + orange→rouge), remplace le Material violet/teal par défaut (scaffold, appbar, tabs, boutons, FAB, champs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fb4ab95f13
commit
30786f9706
@@ -45,6 +45,47 @@ class ApiService {
|
||||
return GameServer.fromJson(jsonDecode(res.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<List<DockerContainer>> containers() async {
|
||||
final base = await baseUrl;
|
||||
final res = await http.get(Uri.parse('$base/api/containers'), headers: await _headers());
|
||||
if (res.statusCode == 401) throw UnauthorizedException();
|
||||
if (res.statusCode != 200) throw ApiException('Erreur ${res.statusCode}');
|
||||
return (jsonDecode(res.body) as List)
|
||||
.map((e) => DockerContainer.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<GameServer> createServer(Map<String, dynamic> payload) async {
|
||||
final base = await baseUrl;
|
||||
final res = await http.post(
|
||||
Uri.parse('$base/api/servers'),
|
||||
headers: {...await _headers(), 'Content-Type': 'application/json'},
|
||||
body: jsonEncode(payload),
|
||||
);
|
||||
if (res.statusCode == 401) throw UnauthorizedException();
|
||||
if (res.statusCode >= 400) {
|
||||
throw ApiException(_msg(res.body) ?? 'Création refusée (${res.statusCode})');
|
||||
}
|
||||
return GameServer.fromJson(jsonDecode(res.body) as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<void> deleteServer(String id) async {
|
||||
final base = await baseUrl;
|
||||
final res = await http.delete(Uri.parse('$base/api/servers/$id'), headers: await _headers());
|
||||
if (res.statusCode == 401) throw UnauthorizedException();
|
||||
if (res.statusCode >= 400) {
|
||||
throw ApiException(_msg(res.body) ?? 'Suppression refusée (${res.statusCode})');
|
||||
}
|
||||
}
|
||||
|
||||
String? _msg(String body) {
|
||||
try {
|
||||
return (jsonDecode(body) as Map<String, dynamic>)['detail'] as String?;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> start(String id) => _action(id, 'start');
|
||||
Future<void> stop(String id) => _action(id, 'stop');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user