Écran d'une application : nom de l'application (FR/EN/NL), case d'affichage du scan QR, et liens stores réservés au SuperAdmin. MultiStringInputContainer accepte des langues explicites, faute de configuration sélectionnée sur cet écran. Le QR d'une section pointe vers app.myinfomate.be : la page /download si l'instance a une app mobile, la section web directement sinon. web.mymuseum.be était désuet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
213 lines
6.1 KiB
Dart
213 lines
6.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:manager_api_new/api.dart';
|
|
|
|
// Colors - TO FILL WIT CORRECT COLOR
|
|
//const kBackgroundColor = Color(0xFFFFFFFF);
|
|
const kTitleTextColor = Color(0xFF303030);
|
|
const kBodyTextColor = Color(0xFF393939); // TODO
|
|
|
|
const kBackgroundColor = Color(0xFFf5f5f7);
|
|
const kPrimaryColor = Color(0xFF264863); // #264863 // 308aae
|
|
const kError = Color(0xFFCA413F);
|
|
const kTextLightColor = Color(0xFFFCFDFD);
|
|
const kSecond = Color(0xFFC2C9D6);
|
|
const kWhite = Color(0xFFFFFFFF);
|
|
const kBlack = Color(0xFF000000);
|
|
const kSuccess = Color(0xFF8bc34a);
|
|
|
|
// URL de l'API, injectee au build :
|
|
// flutter build web --dart-define=API_BASE_URL=https://api.mymuseum.be
|
|
//
|
|
// Elle etait ecrite en dur a quatre endroits, donc une image de manager-web
|
|
// etait liee a un environnement sans que rien ne le signale.
|
|
const kApiBaseUrl = String.fromEnvironment('API_BASE_URL',
|
|
defaultValue: 'http://localhost:5000');
|
|
|
|
// App visiteur web (visitapp-web). Les QR des sections pointent vers sa page
|
|
// /download, qui présente l'app mobile de l'instance.
|
|
const kVisitorWebUrl = 'https://app.myinfomate.be';
|
|
|
|
// Empreinte du build, injectee elle aussi au build :
|
|
// --dart-define=GIT_SHA=$(git rev-parse --short HEAD)
|
|
// Elle est affichee sous le titre de l'ecran de login et sert a relier un
|
|
// bundle deploye au commit exact qui l'a produit : le numero de version du
|
|
// pubspec ne suffisait pas, il ne bougeait pas d'un deploiement a l'autre.
|
|
const kGitSha = String.fromEnvironment('GIT_SHA', defaultValue: 'dev');
|
|
|
|
// Responsive
|
|
const kBreakpointMobile = 850.0;
|
|
|
|
// Shadows
|
|
const kDefaultShadow = BoxShadow(
|
|
color: kSecond,
|
|
spreadRadius: 0.5,
|
|
blurRadius: 5,
|
|
offset: Offset(0, 1.5),
|
|
);
|
|
|
|
// TextStyles for cards
|
|
const kCardTitleStyle = TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: kWhite,
|
|
);
|
|
const kCardSubtitleStyle = TextStyle(
|
|
fontSize: 11,
|
|
fontWeight: FontWeight.w300,
|
|
color: Color(0xCCFFFFFF),
|
|
);
|
|
const kSectionLabelStyle = TextStyle(
|
|
fontSize: 13,
|
|
fontWeight: FontWeight.w600,
|
|
color: kTitleTextColor,
|
|
);
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Socle visuel — l'échelle typographique et les espacements viennent du CSS des
|
|
// maquettes validées (DOCS/claude design/guide-ia-screen.html et
|
|
// statistics-screen.html, tokens identiques dans les deux).
|
|
//
|
|
// Les couleurs, elles, restent celles de l'app : un écran neuf doit se fondre
|
|
// dans manager-app, pas y ouvrir une seconde palette. Seules les valeurs sans
|
|
// équivalent existant sont reprises des maquettes — les remplissages discrets,
|
|
// les bordures, le gris atténué et l'ambre d'avertissement.
|
|
// Pas de thème sombre : l'app n'en a pas.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
const kGround = kBackgroundColor;
|
|
const kSurface = kWhite;
|
|
const kSurface2 = Color(0xFFF3F5F8);
|
|
const kSurface3 = Color(0xFFE7EBF1);
|
|
|
|
const kInk = kTitleTextColor;
|
|
const kInk2 = kBodyTextColor;
|
|
const kInk3 = Color(0xFF7C8B9A);
|
|
|
|
const kLine = Color(0xFFD6DDE5);
|
|
const kLineSoft = Color(0xFFE6EBF1);
|
|
|
|
const kBrand = kPrimaryColor;
|
|
const kBrand2 = Color(0xFF3C6C90);
|
|
const kBrandSoft = kSecond;
|
|
const kOnBrand = kWhite;
|
|
|
|
const kWarning = Color(0xFF9A6608);
|
|
const kSerious = kError;
|
|
const kGood = kSuccess;
|
|
|
|
const kMonoFamily = 'monospace';
|
|
|
|
const kSpace1 = 4.0;
|
|
const kSpace2 = 6.0;
|
|
const kSpace3 = 8.0;
|
|
const kSpace4 = 12.0;
|
|
const kSpace5 = 16.0;
|
|
const kSpace6 = 18.0;
|
|
const kSpace7 = 24.0;
|
|
const kSpace8 = 32.0;
|
|
|
|
const kRadiusInput = 5.0;
|
|
const kRadiusCard = 8.0;
|
|
const kRadiusShell = 10.0;
|
|
const kRadiusTrack = 4.0;
|
|
const kRadiusPill = 999.0;
|
|
|
|
const kCardPadding = EdgeInsets.fromLTRB(18, 17, 18, 19);
|
|
const kPagePadding = EdgeInsets.fromLTRB(28, 24, 28, 30);
|
|
|
|
const kCardShadow = [kDefaultShadow];
|
|
|
|
const kTitleScreen = TextStyle(
|
|
fontSize: 23,
|
|
fontWeight: FontWeight.w700,
|
|
letterSpacing: -0.41,
|
|
color: kInk,
|
|
);
|
|
const kTitleCard = TextStyle(
|
|
fontSize: 14.5,
|
|
fontWeight: FontWeight.w700,
|
|
color: kInk,
|
|
);
|
|
const kSubtitleCard = TextStyle(
|
|
fontSize: 12.5,
|
|
color: kInk3,
|
|
);
|
|
const kTextBody = TextStyle(
|
|
fontSize: 13.5,
|
|
color: kInk,
|
|
);
|
|
const kTextSmall = TextStyle(
|
|
fontSize: 13,
|
|
color: kInk2,
|
|
);
|
|
const kLabelField = TextStyle(
|
|
fontSize: 12.5,
|
|
fontWeight: FontWeight.w600,
|
|
color: kInk2,
|
|
);
|
|
const kTextHint = TextStyle(
|
|
fontSize: 12,
|
|
color: kInk3,
|
|
);
|
|
const kOverline = TextStyle(
|
|
fontSize: 11.5,
|
|
letterSpacing: 0.69,
|
|
color: kInk3,
|
|
);
|
|
const kOverlineMono = TextStyle(
|
|
fontFamily: kMonoFamily,
|
|
fontSize: 10.5,
|
|
letterSpacing: 0.95,
|
|
color: kInk3,
|
|
);
|
|
const kMetricLarge = TextStyle(
|
|
fontFamily: kMonoFamily,
|
|
fontSize: 29,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.73,
|
|
height: 1,
|
|
color: kInk,
|
|
fontFeatures: [FontFeature.tabularFigures()],
|
|
);
|
|
const kMetricMedium = TextStyle(
|
|
fontFamily: kMonoFamily,
|
|
fontSize: 26,
|
|
fontWeight: FontWeight.w600,
|
|
letterSpacing: -0.52,
|
|
color: kInk,
|
|
fontFeatures: [FontFeature.tabularFigures()],
|
|
);
|
|
|
|
const List<String> section_types = ["Map", "Slider", "Video", "Web", "Menu", "Quiz", "Article", "PDF", "Game", "Agenda", "Weather", "Event", "Parcours"];
|
|
const List<String> map_types = ["none", "normal", "satellite", "terrain", "hybrid"];
|
|
const List<String> languages = ["FR", "NL", "EN", "DE", "IT", "ES", "CN", "PL", "AR", "UK"];
|
|
const List<String> map_types_mapBox = ["standard", "streets", "outdoors", "light", "dark", "satellite", "satellite_streets"];
|
|
const List<String> map_providers = ["Google", "MapBox"];
|
|
|
|
/// Plafond d'utilisateurs par instance, SuperAdmin exclu.
|
|
/// ⚠️ Contrôle d'interface uniquement : `UserController` ne compte rien côté serveur,
|
|
/// un POST direct sur l'API passe toujours.
|
|
const kMaxUsersPerInstance = 5;
|
|
|
|
const kTitleMaxLength = 165;
|
|
const kDescriptionMaxLength = 2500;
|
|
|
|
/// Types de ressource proposés, dans l'ordre d'affichage. Le libellé se lit
|
|
/// avec `resourceTypeLabel` : il dépend de la langue du manager.
|
|
const List<ResourceType> resource_types = [
|
|
ResourceType.Image,
|
|
ResourceType.ImageUrl,
|
|
ResourceType.Video,
|
|
ResourceType.VideoUrl,
|
|
ResourceType.Audio,
|
|
ResourceType.Pdf,
|
|
ResourceType.Json,
|
|
ResourceType.JsonUrl,
|
|
];
|
|
|
|
/*
|
|
const kTextStyle = TextStyle(
|
|
fontSize: 23,
|
|
color: kPrimaryColor,
|
|
fontWeight: FontWeight.w600,
|
|
);*/ |