refacto to aitoken

This commit is contained in:
Thomas Fransolet 2026-07-17 15:20:41 +02:00
parent e851929dbc
commit 8073cced5e
18 changed files with 276 additions and 133 deletions

View File

@ -7,6 +7,7 @@ class ColorPickerInputContainer extends StatefulWidget {
final String label; final String label;
final double fontSize; final double fontSize;
final ValueChanged<String> onChanged; final ValueChanged<String> onChanged;
final bool showHex;
const ColorPickerInputContainer({ const ColorPickerInputContainer({
Key? key, Key? key,
@ -14,6 +15,7 @@ class ColorPickerInputContainer extends StatefulWidget {
required this.label, required this.label,
this.fontSize = 18, this.fontSize = 18,
required this.onChanged, required this.onChanged,
this.showHex = false,
}) : super(key: key); }) : super(key: key);
@override @override
@ -70,14 +72,31 @@ class _ColorPickerInputContainerState extends State<ColorPickerInputContainer> {
widget.onChanged(colorToString(color)); widget.onChanged(colorToString(color));
}, context); }, context);
}, },
child: Container( child: Row(
width: 50, crossAxisAlignment: CrossAxisAlignment.center,
height: 50, children: [
decoration: BoxDecoration( Container(
color: colorVar, width: 50,
borderRadius: BorderRadius.circular(10), height: 50,
border: Border.all(color: Colors.black26), decoration: BoxDecoration(
), color: colorVar,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.black26),
),
),
if (widget.showHex)
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
'#${colorVar.toARGB32().toRadixString(16).substring(2).toUpperCase()}',
style: const TextStyle(
fontSize: 13,
fontFamily: 'monospace',
color: Colors.black54,
),
),
),
],
), ),
), ),
), ),

View File

@ -10,6 +10,7 @@ class GeometryInputContainer extends StatelessWidget {
final Function(GeometryDTO, String) onSave; final Function(GeometryDTO, String) onSave;
final Color color; final Color color;
final bool isSmall; final bool isSmall;
final bool showColorButton;
GeometryInputContainer({ GeometryInputContainer({
required this.label, required this.label,
@ -18,6 +19,7 @@ class GeometryInputContainer extends StatelessWidget {
required this.onSave, required this.onSave,
this.color = kPrimaryColor, this.color = kPrimaryColor,
this.isSmall = false, this.isSmall = false,
this.showColorButton = true,
}); });
@override @override
@ -58,6 +60,7 @@ class GeometryInputContainer extends StatelessWidget {
initialGeometry: initialGeometry, initialGeometry: initialGeometry,
initialColor: initialColor, initialColor: initialColor,
onSave: onSave, onSave: onSave,
showColorButton: showColorButton,
), ),
); );
}, },

View File

@ -11,11 +11,13 @@ class MapGeometryPicker extends StatefulWidget {
final GeometryDTO? initialGeometry; final GeometryDTO? initialGeometry;
final String? initialColor; final String? initialColor;
final Function(GeometryDTO, String) onSave; final Function(GeometryDTO, String) onSave;
final bool showColorButton;
MapGeometryPicker({ MapGeometryPicker({
this.initialGeometry, this.initialGeometry,
this.initialColor, this.initialColor,
required this.onSave, required this.onSave,
this.showColorButton = true,
}); });
@override @override
@ -143,14 +145,18 @@ class _MapGeometryPickerState extends State<MapGeometryPicker> {
fontWeight: FontWeight.bold)), fontWeight: FontWeight.bold)),
Row( Row(
children: [ children: [
IconButton( // Couleur non stockée pour toutes les entités (ex. GuidedStepDTO n'a pas
icon: Icon(Icons.palette, color: Colors.white), // de champ color) : masqué via showColorButton plutôt que supprimé, pour
onPressed: () { // ne pas casser les cas elle l'est (ex. MapAnnotationDTO.polyColor).
showColorPicker(selectedColor, (Color color) { if (widget.showColorButton)
setState(() => selectedColor = color); IconButton(
}, context); icon: Icon(Icons.palette, color: Colors.white),
}, onPressed: () {
), showColorPicker(selectedColor, (Color color) {
setState(() => selectedColor = color);
}, context);
},
),
IconButton( IconButton(
icon: Icon(Icons.delete, color: Colors.white), icon: Icon(Icons.delete, color: Colors.white),
onPressed: () => setState(() => points.clear()), onPressed: () => setState(() => points.clear()),

View File

@ -60,6 +60,12 @@ class _QuotaBarsWidgetState extends State<QuotaBarsWidget> {
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB'; return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(2)} GB';
} }
String _formatTokens(int tokens) {
if (tokens < 1000) return '$tokens';
if (tokens < 1000000) return '${(tokens / 1000).toStringAsFixed(0)}K';
return '${(tokens / 1000000).toStringAsFixed(1)}M';
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final managerContext = Provider.of<AppContext>(context).getContext() as ManagerAppContext; final managerContext = Provider.of<AppContext>(context).getContext() as ManagerAppContext;
@ -77,8 +83,8 @@ class _QuotaBarsWidgetState extends State<QuotaBarsWidget> {
final storageUsed = _quota!.storageUsedBytes ?? 0; final storageUsed = _quota!.storageUsedBytes ?? 0;
final storageQuota = _quota!.storageQuotaBytes ?? 0; final storageQuota = _quota!.storageQuotaBytes ?? 0;
final aiUsed = _quota!.aiRequestsUsed ?? 0; final aiUsed = _quota!.aiTokensUsed ?? 0;
final aiQuota = _quota!.aiRequestsPerMonth ?? 0; final aiQuota = _quota!.aiTokensPerMonth ?? 0;
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
@ -102,8 +108,8 @@ class _QuotaBarsWidgetState extends State<QuotaBarsWidget> {
value: _barValue(aiUsed, aiQuota), value: _barValue(aiUsed, aiQuota),
color: _barColor(aiUsed, aiQuota), color: _barColor(aiUsed, aiQuota),
subtitle: aiQuota == 0 subtitle: aiQuota == 0
? '$aiUsed ${l10n.requestsAbbr} · ${l10n.unlimited}' ? '${_formatTokens(aiUsed)} ${l10n.tokensAbbr} · ${l10n.unlimited}'
: '$aiUsed / $aiQuota ${l10n.requestsAbbr}.', : '${_formatTokens(aiUsed)} / ${_formatTokens(aiQuota)} ${l10n.tokensAbbr}',
), ),
], ],
], ],

View File

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import '../constants.dart';
class SwitchInputContainer extends StatefulWidget {
final bool? isChecked;
final IconData? icon;
final String label;
final String? subtitle;
final ValueChanged<bool> onChanged;
final double fontSize;
const SwitchInputContainer({
Key? key,
this.isChecked,
this.icon,
required this.label,
this.subtitle,
required this.onChanged,
this.fontSize = 18
}) : super(key: key);
@override
_SwitchInputContainerState createState() => _SwitchInputContainerState();
}
class _SwitchInputContainerState extends State<SwitchInputContainer> {
bool? isChecked;
@override
void initState() {
setState(() {
isChecked = widget.isChecked;
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Align(
alignment: AlignmentDirectional.centerStart,
child: Row(
children: [
if (widget.icon != null)
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(
widget.icon,
color: kPrimaryColor,
size: 25.0,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
widget.label,
style: TextStyle(fontSize: widget.fontSize, fontWeight: FontWeight.w300)
),
if (widget.subtitle != null)
Padding(
padding: const EdgeInsets.only(top: 2),
child: Text(
widget.subtitle!,
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
),
),
],
),
],
)
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Switch(
value: isChecked ?? false,
activeThumbColor: kPrimaryColor,
onChanged: (bool value) {
setState(() {
isChecked = value;
});
widget.onChanged(value);
},
),
),
],
),
);
}
}

View File

@ -127,6 +127,10 @@ void showNewOrUpdateGuidedStep(
label: AppLocalizations.of(context)!.stepLocationLabel, label: AppLocalizations.of(context)!.stepLocationLabel,
initialGeometry: workingStep.geometry, initialGeometry: workingStep.geometry,
initialColor: null, initialColor: null,
// GuidedStepDTO n'a pas de champ color (contrairement à
// MapAnnotationDTO.polyColor) : bouton masqué plutôt que
// supprimé, ne pas retirer comme du code mort.
showColorButton: false,
onSave: (geometry, color) { onSave: (geometry, color) {
setState(() { setState(() {
workingStep.geometry = geometry; workingStep.geometry = geometry;

View File

@ -1,11 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:manager_app/Components/check_input_container.dart';
import 'package:manager_app/Components/color_picker_input_container.dart'; import 'package:manager_app/Components/color_picker_input_container.dart';
import 'package:manager_app/Components/message_notification.dart';
import 'package:manager_app/Components/number_input_container.dart';
import 'package:manager_app/Components/rounded_button.dart'; import 'package:manager_app/Components/rounded_button.dart';
import 'package:manager_app/Components/slider_input_container.dart';
import 'package:manager_app/Components/string_input_container.dart'; import 'package:manager_app/Components/string_input_container.dart';
import 'package:manager_app/Components/switch_input_container.dart';
import 'package:manager_app/Models/managerContext.dart'; import 'package:manager_app/Models/managerContext.dart';
import 'package:manager_app/app_context.dart'; import 'package:manager_app/app_context.dart';
import 'package:manager_app/constants.dart'; import 'package:manager_app/constants.dart';
@ -38,7 +36,7 @@ showChangeInfo(String text, DeviceDTO inputDevice, AppConfigurationLinkDTO appCo
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Nom + Configuration _sectionTitle("Identité"),
Wrap( Wrap(
spacing: 16, spacing: 16,
runSpacing: 12, runSpacing: 12,
@ -85,8 +83,8 @@ showChangeInfo(String text, DeviceDTO inputDevice, AppConfigurationLinkDTO appCo
), ),
], ],
), ),
const SizedBox(height: 12), const Divider(height: 32),
// Couleurs + Loader _sectionTitle("Apparence"),
Wrap( Wrap(
spacing: 16, spacing: 16,
runSpacing: 12, runSpacing: 12,
@ -95,12 +93,14 @@ showChangeInfo(String text, DeviceDTO inputDevice, AppConfigurationLinkDTO appCo
label: "Couleur principale :", label: "Couleur principale :",
fontSize: 16, fontSize: 16,
color: appConfiguration.primaryColor, color: appConfiguration.primaryColor,
showHex: true,
onChanged: (value) => appConfiguration.primaryColor = value, onChanged: (value) => appConfiguration.primaryColor = value,
), ),
ColorPickerInputContainer( ColorPickerInputContainer(
label: AppLocalizations.of(context)!.backgroundColorLabel, label: AppLocalizations.of(context)!.backgroundColorLabel,
fontSize: 16, fontSize: 16,
color: appConfiguration.secondaryColor, color: appConfiguration.secondaryColor,
showHex: true,
onChanged: (value) => appConfiguration.secondaryColor = value, onChanged: (value) => appConfiguration.secondaryColor = value,
), ),
ResourceInputContainer( ResourceInputContainer(
@ -120,67 +120,47 @@ showChangeInfo(String text, DeviceDTO inputDevice, AppConfigurationLinkDTO appCo
), ),
], ],
), ),
const SizedBox(height: 12), const Divider(height: 32),
// Pourcentages _sectionTitle("Mise en page"),
Wrap( SliderInputContainer(
spacing: 16, label: "Place des sections (%) :",
runSpacing: 12, fontSize: 16,
children: [ initialValue: (appConfiguration.screenPercentageSectionsMainPage ?? 0).toDouble(),
SizedBox( min: 0,
height: 90, max: 100,
child: NumberInputContainer( color: kPrimaryColor,
label: "Place des sections (%) :", onChanged: (value) => appConfiguration.screenPercentageSectionsMainPage = value.round(),
initialValue: appConfiguration.screenPercentageSectionsMainPage ?? 0,
isSmall: true,
maxLength: 3,
onChanged: (value) {
try {
appConfiguration.screenPercentageSectionsMainPage = int.parse(value);
} catch (e) {
showNotification(Colors.orange, kWhite, 'Cela doit être un chiffre', context, null);
}
},
),
),
SizedBox(
height: 90,
child: NumberInputContainer(
label: "Pourcentage des arrondis (0-50) :",
initialValue: appConfiguration.roundedValue ?? 0,
isSmall: true,
maxLength: 2,
onChanged: (value) {
try {
appConfiguration.roundedValue = int.parse(value);
} catch (e) {
showNotification(Colors.orange, kWhite, 'Cela doit être un chiffre', context, null);
}
},
),
),
],
), ),
const SizedBox(height: 12), SliderInputContainer(
// Toggles label: "Pourcentage des arrondis (0-50) :",
fontSize: 16,
initialValue: (appConfiguration.roundedValue ?? 0).toDouble(),
min: 0,
max: 50,
color: kPrimaryColor,
onChanged: (value) => appConfiguration.roundedValue = value.round(),
),
const Divider(height: 32),
_sectionTitle("Options"),
Wrap( Wrap(
spacing: 16, spacing: 16,
runSpacing: 8, runSpacing: 8,
children: [ children: [
CheckInputContainer( SwitchInputContainer(
icon: Icons.image, icon: Icons.image,
label: "Fond pour les images des sections :", label: "Fond pour les images des sections :",
fontSize: 16, fontSize: 16,
isChecked: appConfiguration.isSectionImageBackground, isChecked: appConfiguration.isSectionImageBackground,
onChanged: (value) => appConfiguration.isSectionImageBackground = value, onChanged: (value) => appConfiguration.isSectionImageBackground = value,
), ),
CheckInputContainer( SwitchInputContainer(
icon: Icons.watch_later_outlined, icon: Icons.watch_later_outlined,
label: "Heure :", label: "Heure :",
fontSize: 16, fontSize: 16,
isChecked: appConfiguration.isHour, isChecked: appConfiguration.isHour,
onChanged: (value) => appConfiguration.isHour = value, onChanged: (value) => appConfiguration.isHour = value,
), ),
CheckInputContainer( SwitchInputContainer(
icon: Icons.date_range, icon: Icons.date_range,
label: "Date :", label: "Date :",
fontSize: 16, fontSize: 16,
@ -227,6 +207,13 @@ showChangeInfo(String text, DeviceDTO inputDevice, AppConfigurationLinkDTO appCo
); );
} }
Widget _sectionTitle(String title) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Text(title, style: kSectionLabelStyle),
);
}
getConfigurationsElement(DeviceDTO inputDevice, data, Function onGetResult) { getConfigurationsElement(DeviceDTO inputDevice, data, Function onGetResult) {
List<Widget> widgets = <Widget>[]; List<Widget> widgets = <Widget>[];
for (var configuration in data as List<ConfigurationDTO>) { for (var configuration in data as List<ConfigurationDTO>) {

View File

@ -118,7 +118,7 @@ class _MainScreenState extends State<MainScreen> {
...planList.map((plan) => RadioListTile<String?>( ...planList.map((plan) => RadioListTile<String?>(
title: Text(plan.name), title: Text(plan.name),
subtitle: Text( subtitle: Text(
'${_formatQuotaBytes(plan.storageQuotaBytes, unlimitedLabel: AppLocalizations.of(dialogContext)!.unlimitedStorage)} · ${plan.aiRequestsPerMonth == 0 ? AppLocalizations.of(dialogContext)!.unlimitedAI : AppLocalizations.of(dialogContext)!.aiRequestsPerMonth(plan.aiRequestsPerMonth ?? 0)}', '${_formatQuotaBytes(plan.storageQuotaBytes, unlimitedLabel: AppLocalizations.of(dialogContext)!.unlimitedStorage)} · ${plan.aiTokensPerMonth == 0 ? AppLocalizations.of(dialogContext)!.unlimitedAI : AppLocalizations.of(dialogContext)!.aiTokensPerMonth(_formatTokens(plan.aiTokensPerMonth))}',
style: const TextStyle(fontSize: 11), style: const TextStyle(fontSize: 11),
), ),
value: plan.id, value: plan.id,
@ -150,7 +150,7 @@ class _MainScreenState extends State<MainScreen> {
isWeb: instanceDetail?.isWeb, isWeb: instanceDetail?.isWeb,
isVR: instanceDetail?.isVR, isVR: instanceDetail?.isVR,
isAssistant: instanceDetail?.isAssistant, isAssistant: instanceDetail?.isAssistant,
aiRequestsThisMonth: instanceDetail?.aiRequestsThisMonth, aiTokensThisMonth: instanceDetail?.aiTokensThisMonth,
aiUsageMonthKey: instanceDetail?.aiUsageMonthKey, aiUsageMonthKey: instanceDetail?.aiUsageMonthKey,
subscriptionPlanId: selectedPlanId ?? '', subscriptionPlanId: selectedPlanId ?? '',
), ),
@ -179,6 +179,13 @@ class _MainScreenState extends State<MainScreen> {
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
} }
static String _formatTokens(int? tokens) {
if (tokens == null || tokens == 0) return '0';
if (tokens < 1000) return '$tokens';
if (tokens < 1000000) return '${(tokens / 1000).toStringAsFixed(0)}K';
return '${(tokens / 1000000).toStringAsFixed(1)}M';
}
Future<void> _showSwitchInstanceDialog(BuildContext context, ManagerAppContext managerCtx) async { Future<void> _showSwitchInstanceDialog(BuildContext context, ManagerAppContext managerCtx) async {
List<Instance>? instances; List<Instance>? instances;
try { try {

View File

@ -31,16 +31,17 @@
"noPlan": "No plan (unlimited)", "noPlan": "No plan (unlimited)",
"unlimitedStorage": "Unlimited storage", "unlimitedStorage": "Unlimited storage",
"unlimitedAI": "Unlimited AI", "unlimitedAI": "Unlimited AI",
"aiRequestsPerMonth": "{count} AI req/month", "aiTokensPerMonth": "{amount} AI tokens/month",
"@aiRequestsPerMonth": { "@aiTokensPerMonth": {
"placeholders": { "placeholders": {
"count": { "type": "int" } "amount": { "type": "String" }
} }
}, },
"storageLabel": "Storage", "storageLabel": "Storage",
"aiThisMonthLabel": "AI this month", "aiThisMonthLabel": "AI this month",
"unlimited": "Unlimited", "unlimited": "Unlimited",
"requestsAbbr": "req", "requestsAbbr": "req",
"tokensAbbr": "tokens",
"planUpdated": "Plan updated", "planUpdated": "Plan updated",
"errorMessage": "Error: {error}", "errorMessage": "Error: {error}",
"@errorMessage": { "@errorMessage": {

View File

@ -31,16 +31,17 @@
"noPlan": "Aucun plan (illimité)", "noPlan": "Aucun plan (illimité)",
"unlimitedStorage": "Stockage illimité", "unlimitedStorage": "Stockage illimité",
"unlimitedAI": "IA illimitée", "unlimitedAI": "IA illimitée",
"aiRequestsPerMonth": "{count} req IA/mois", "aiTokensPerMonth": "{amount} tokens IA/mois",
"@aiRequestsPerMonth": { "@aiTokensPerMonth": {
"placeholders": { "placeholders": {
"count": { "type": "int" } "amount": { "type": "String" }
} }
}, },
"storageLabel": "Stockage", "storageLabel": "Stockage",
"aiThisMonthLabel": "IA ce mois", "aiThisMonthLabel": "IA ce mois",
"unlimited": "Illimité", "unlimited": "Illimité",
"requestsAbbr": "req", "requestsAbbr": "req",
"tokensAbbr": "tokens",
"planUpdated": "Plan mis à jour", "planUpdated": "Plan mis à jour",
"errorMessage": "Erreur : {error}", "errorMessage": "Erreur : {error}",
"@errorMessage": { "@errorMessage": {

View File

@ -262,11 +262,11 @@ abstract class AppLocalizations {
/// **'IA illimitée'** /// **'IA illimitée'**
String get unlimitedAI; String get unlimitedAI;
/// No description provided for @aiRequestsPerMonth. /// No description provided for @aiTokensPerMonth.
/// ///
/// In fr, this message translates to: /// In fr, this message translates to:
/// **'{count} req IA/mois'** /// **'{amount} tokens IA/mois'**
String aiRequestsPerMonth(int count); String aiTokensPerMonth(String amount);
/// No description provided for @storageLabel. /// No description provided for @storageLabel.
/// ///
@ -292,6 +292,12 @@ abstract class AppLocalizations {
/// **'req'** /// **'req'**
String get requestsAbbr; String get requestsAbbr;
/// No description provided for @tokensAbbr.
///
/// In fr, this message translates to:
/// **'tokens'**
String get tokensAbbr;
/// No description provided for @planUpdated. /// No description provided for @planUpdated.
/// ///
/// In fr, this message translates to: /// In fr, this message translates to:

View File

@ -90,8 +90,8 @@ class AppLocalizationsEn extends AppLocalizations {
String get unlimitedAI => 'Unlimited AI'; String get unlimitedAI => 'Unlimited AI';
@override @override
String aiRequestsPerMonth(int count) { String aiTokensPerMonth(String amount) {
return '$count AI req/month'; return '$amount AI tokens/month';
} }
@override @override
@ -106,6 +106,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get requestsAbbr => 'req'; String get requestsAbbr => 'req';
@override
String get tokensAbbr => 'tokens';
@override @override
String get planUpdated => 'Plan updated'; String get planUpdated => 'Plan updated';

View File

@ -91,8 +91,8 @@ class AppLocalizationsFr extends AppLocalizations {
String get unlimitedAI => 'IA illimitée'; String get unlimitedAI => 'IA illimitée';
@override @override
String aiRequestsPerMonth(int count) { String aiTokensPerMonth(String amount) {
return '$count req IA/mois'; return '$amount tokens IA/mois';
} }
@override @override
@ -107,6 +107,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override @override
String get requestsAbbr => 'req'; String get requestsAbbr => 'req';
@override
String get tokensAbbr => 'tokens';
@override @override
String get planUpdated => 'Plan mis à jour'; String get planUpdated => 'Plan mis à jour';

View File

@ -91,8 +91,8 @@ class AppLocalizationsNl extends AppLocalizations {
String get unlimitedAI => 'Onbeperkte AI'; String get unlimitedAI => 'Onbeperkte AI';
@override @override
String aiRequestsPerMonth(int count) { String aiTokensPerMonth(String amount) {
return '$count AI-verz./maand'; return '$amount AI-tokens/maand';
} }
@override @override
@ -107,6 +107,9 @@ class AppLocalizationsNl extends AppLocalizations {
@override @override
String get requestsAbbr => 'verz.'; String get requestsAbbr => 'verz.';
@override
String get tokensAbbr => 'tokens';
@override @override
String get planUpdated => 'Plan bijgewerkt'; String get planUpdated => 'Plan bijgewerkt';

View File

@ -31,16 +31,17 @@
"noPlan": "Geen plan (onbeperkt)", "noPlan": "Geen plan (onbeperkt)",
"unlimitedStorage": "Onbeperkte opslag", "unlimitedStorage": "Onbeperkte opslag",
"unlimitedAI": "Onbeperkte AI", "unlimitedAI": "Onbeperkte AI",
"aiRequestsPerMonth": "{count} AI-verz./maand", "aiTokensPerMonth": "{amount} AI-tokens/maand",
"@aiRequestsPerMonth": { "@aiTokensPerMonth": {
"placeholders": { "placeholders": {
"count": { "type": "int" } "amount": { "type": "String" }
} }
}, },
"storageLabel": "Opslag", "storageLabel": "Opslag",
"aiThisMonthLabel": "AI deze maand", "aiThisMonthLabel": "AI deze maand",
"unlimited": "Onbeperkt", "unlimited": "Onbeperkt",
"requestsAbbr": "verz.", "requestsAbbr": "verz.",
"tokensAbbr": "tokens",
"planUpdated": "Plan bijgewerkt", "planUpdated": "Plan bijgewerkt",
"errorMessage": "Fout: {error}", "errorMessage": "Fout: {error}",
"@errorMessage": { "@errorMessage": {

View File

@ -25,10 +25,10 @@ class InstanceDTO {
this.isAssistant, this.isAssistant,
this.subscriptionPlanId, this.subscriptionPlanId,
this.subscriptionPlan, this.subscriptionPlan,
this.aiRequestsThisMonth, this.aiTokensThisMonth,
this.aiUsageMonthKey, this.aiUsageMonthKey,
this.storageQuotaBytes, this.storageQuotaBytes,
this.aiRequestsPerMonth, this.aiTokensPerMonth,
this.hasStats, this.hasStats,
this.statsHistoryDays, this.statsHistoryDays,
this.hasAdvancedStats, this.hasAdvancedStats,
@ -98,13 +98,13 @@ class InstanceDTO {
SubscriptionPlanDTO? subscriptionPlan; SubscriptionPlanDTO? subscriptionPlan;
int? aiRequestsThisMonth; int? aiTokensThisMonth;
String? aiUsageMonthKey; String? aiUsageMonthKey;
int? storageQuotaBytes; int? storageQuotaBytes;
int? aiRequestsPerMonth; int? aiTokensPerMonth;
bool? hasStats; bool? hasStats;
@ -134,10 +134,10 @@ class InstanceDTO {
other.isAssistant == isAssistant && other.isAssistant == isAssistant &&
other.subscriptionPlanId == subscriptionPlanId && other.subscriptionPlanId == subscriptionPlanId &&
other.subscriptionPlan == subscriptionPlan && other.subscriptionPlan == subscriptionPlan &&
other.aiRequestsThisMonth == aiRequestsThisMonth && other.aiTokensThisMonth == aiTokensThisMonth &&
other.aiUsageMonthKey == aiUsageMonthKey && other.aiUsageMonthKey == aiUsageMonthKey &&
other.storageQuotaBytes == storageQuotaBytes && other.storageQuotaBytes == storageQuotaBytes &&
other.aiRequestsPerMonth == aiRequestsPerMonth && other.aiTokensPerMonth == aiTokensPerMonth &&
other.hasStats == hasStats && other.hasStats == hasStats &&
other.statsHistoryDays == statsHistoryDays && other.statsHistoryDays == statsHistoryDays &&
other.hasAdvancedStats == hasAdvancedStats && other.hasAdvancedStats == hasAdvancedStats &&
@ -159,13 +159,13 @@ class InstanceDTO {
(isAssistant == null ? 0 : isAssistant!.hashCode) + (isAssistant == null ? 0 : isAssistant!.hashCode) +
(subscriptionPlanId == null ? 0 : subscriptionPlanId!.hashCode) + (subscriptionPlanId == null ? 0 : subscriptionPlanId!.hashCode) +
(subscriptionPlan == null ? 0 : subscriptionPlan!.hashCode) + (subscriptionPlan == null ? 0 : subscriptionPlan!.hashCode) +
(aiRequestsThisMonth == null ? 0 : aiRequestsThisMonth!.hashCode) + (aiTokensThisMonth == null ? 0 : aiTokensThisMonth!.hashCode) +
(aiUsageMonthKey == null ? 0 : aiUsageMonthKey!.hashCode) + (aiUsageMonthKey == null ? 0 : aiUsageMonthKey!.hashCode) +
(applicationInstanceDTOs == null ? 0 : applicationInstanceDTOs!.hashCode); (applicationInstanceDTOs == null ? 0 : applicationInstanceDTOs!.hashCode);
@override @override
String toString() => String toString() =>
'InstanceDTO[id=$id, name=$name, dateCreation=$dateCreation, pinCode=$pinCode, isPushNotification=$isPushNotification, isMobile=$isMobile, isTablet=$isTablet, isWeb=$isWeb, isVR=$isVR, isAssistant=$isAssistant, subscriptionPlanId=$subscriptionPlanId, subscriptionPlan=$subscriptionPlan, aiRequestsThisMonth=$aiRequestsThisMonth, aiUsageMonthKey=$aiUsageMonthKey, applicationInstanceDTOs=$applicationInstanceDTOs]'; 'InstanceDTO[id=$id, name=$name, dateCreation=$dateCreation, pinCode=$pinCode, isPushNotification=$isPushNotification, isMobile=$isMobile, isTablet=$isTablet, isWeb=$isWeb, isVR=$isVR, isAssistant=$isAssistant, subscriptionPlanId=$subscriptionPlanId, subscriptionPlan=$subscriptionPlan, aiTokensThisMonth=$aiTokensThisMonth, aiUsageMonthKey=$aiUsageMonthKey, applicationInstanceDTOs=$applicationInstanceDTOs]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -229,10 +229,10 @@ class InstanceDTO {
} else { } else {
json[r'subscriptionPlan'] = null; json[r'subscriptionPlan'] = null;
} }
if (this.aiRequestsThisMonth != null) { if (this.aiTokensThisMonth != null) {
json[r'aiRequestsThisMonth'] = this.aiRequestsThisMonth; json[r'aiTokensThisMonth'] = this.aiTokensThisMonth;
} else { } else {
json[r'aiRequestsThisMonth'] = null; json[r'aiTokensThisMonth'] = null;
} }
if (this.aiUsageMonthKey != null) { if (this.aiUsageMonthKey != null) {
json[r'aiUsageMonthKey'] = this.aiUsageMonthKey; json[r'aiUsageMonthKey'] = this.aiUsageMonthKey;
@ -244,10 +244,10 @@ class InstanceDTO {
} else { } else {
json[r'storageQuotaBytes'] = null; json[r'storageQuotaBytes'] = null;
} }
if (this.aiRequestsPerMonth != null) { if (this.aiTokensPerMonth != null) {
json[r'aiRequestsPerMonth'] = this.aiRequestsPerMonth; json[r'aiTokensPerMonth'] = this.aiTokensPerMonth;
} else { } else {
json[r'aiRequestsPerMonth'] = null; json[r'aiTokensPerMonth'] = null;
} }
if (this.hasStats != null) { if (this.hasStats != null) {
json[r'hasStats'] = this.hasStats; json[r'hasStats'] = this.hasStats;
@ -315,10 +315,10 @@ class InstanceDTO {
isAssistant: mapValueOfType<bool>(json, r'isAssistant'), isAssistant: mapValueOfType<bool>(json, r'isAssistant'),
subscriptionPlanId: mapValueOfType<String>(json, r'subscriptionPlanId'), subscriptionPlanId: mapValueOfType<String>(json, r'subscriptionPlanId'),
subscriptionPlan: SubscriptionPlanDTO.fromJson(json[r'subscriptionPlan']), subscriptionPlan: SubscriptionPlanDTO.fromJson(json[r'subscriptionPlan']),
aiRequestsThisMonth: mapValueOfType<int>(json, r'aiRequestsThisMonth'), aiTokensThisMonth: mapValueOfType<int>(json, r'aiTokensThisMonth'),
aiUsageMonthKey: mapValueOfType<String>(json, r'aiUsageMonthKey'), aiUsageMonthKey: mapValueOfType<String>(json, r'aiUsageMonthKey'),
storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'), storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'),
aiRequestsPerMonth: mapValueOfType<int>(json, r'aiRequestsPerMonth'), aiTokensPerMonth: mapValueOfType<int>(json, r'aiTokensPerMonth'),
hasStats: mapValueOfType<bool>(json, r'hasStats'), hasStats: mapValueOfType<bool>(json, r'hasStats'),
statsHistoryDays: mapValueOfType<int>(json, r'statsHistoryDays'), statsHistoryDays: mapValueOfType<int>(json, r'statsHistoryDays'),
hasAdvancedStats: mapValueOfType<bool>(json, r'hasAdvancedStats'), hasAdvancedStats: mapValueOfType<bool>(json, r'hasAdvancedStats'),

View File

@ -15,17 +15,17 @@ class InstanceQuotaDTO {
InstanceQuotaDTO({ InstanceQuotaDTO({
this.storageUsedBytes, this.storageUsedBytes,
this.storageQuotaBytes, this.storageQuotaBytes,
this.aiRequestsUsed, this.aiTokensUsed,
this.aiRequestsPerMonth, this.aiTokensPerMonth,
}); });
int? storageUsedBytes; int? storageUsedBytes;
int? storageQuotaBytes; int? storageQuotaBytes;
int? aiRequestsUsed; int? aiTokensUsed;
int? aiRequestsPerMonth; int? aiTokensPerMonth;
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@ -33,19 +33,19 @@ class InstanceQuotaDTO {
other is InstanceQuotaDTO && other is InstanceQuotaDTO &&
other.storageUsedBytes == storageUsedBytes && other.storageUsedBytes == storageUsedBytes &&
other.storageQuotaBytes == storageQuotaBytes && other.storageQuotaBytes == storageQuotaBytes &&
other.aiRequestsUsed == aiRequestsUsed && other.aiTokensUsed == aiTokensUsed &&
other.aiRequestsPerMonth == aiRequestsPerMonth; other.aiTokensPerMonth == aiTokensPerMonth;
@override @override
int get hashCode => int get hashCode =>
(storageUsedBytes == null ? 0 : storageUsedBytes!.hashCode) + (storageUsedBytes == null ? 0 : storageUsedBytes!.hashCode) +
(storageQuotaBytes == null ? 0 : storageQuotaBytes!.hashCode) + (storageQuotaBytes == null ? 0 : storageQuotaBytes!.hashCode) +
(aiRequestsUsed == null ? 0 : aiRequestsUsed!.hashCode) + (aiTokensUsed == null ? 0 : aiTokensUsed!.hashCode) +
(aiRequestsPerMonth == null ? 0 : aiRequestsPerMonth!.hashCode); (aiTokensPerMonth == null ? 0 : aiTokensPerMonth!.hashCode);
@override @override
String toString() => String toString() =>
'InstanceQuotaDTO[storageUsedBytes=$storageUsedBytes, storageQuotaBytes=$storageQuotaBytes, aiRequestsUsed=$aiRequestsUsed, aiRequestsPerMonth=$aiRequestsPerMonth]'; 'InstanceQuotaDTO[storageUsedBytes=$storageUsedBytes, storageQuotaBytes=$storageQuotaBytes, aiTokensUsed=$aiTokensUsed, aiTokensPerMonth=$aiTokensPerMonth]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -59,15 +59,15 @@ class InstanceQuotaDTO {
} else { } else {
json[r'storageQuotaBytes'] = null; json[r'storageQuotaBytes'] = null;
} }
if (this.aiRequestsUsed != null) { if (this.aiTokensUsed != null) {
json[r'aiRequestsUsed'] = this.aiRequestsUsed; json[r'aiTokensUsed'] = this.aiTokensUsed;
} else { } else {
json[r'aiRequestsUsed'] = null; json[r'aiTokensUsed'] = null;
} }
if (this.aiRequestsPerMonth != null) { if (this.aiTokensPerMonth != null) {
json[r'aiRequestsPerMonth'] = this.aiRequestsPerMonth; json[r'aiTokensPerMonth'] = this.aiTokensPerMonth;
} else { } else {
json[r'aiRequestsPerMonth'] = null; json[r'aiTokensPerMonth'] = null;
} }
return json; return json;
} }
@ -79,8 +79,8 @@ class InstanceQuotaDTO {
return InstanceQuotaDTO( return InstanceQuotaDTO(
storageUsedBytes: mapValueOfType<int>(json, r'storageUsedBytes'), storageUsedBytes: mapValueOfType<int>(json, r'storageUsedBytes'),
storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'), storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'),
aiRequestsUsed: mapValueOfType<int>(json, r'aiRequestsUsed'), aiTokensUsed: mapValueOfType<int>(json, r'aiTokensUsed'),
aiRequestsPerMonth: mapValueOfType<int>(json, r'aiRequestsPerMonth'), aiTokensPerMonth: mapValueOfType<int>(json, r'aiTokensPerMonth'),
); );
} }
return null; return null;

View File

@ -16,7 +16,7 @@ class SubscriptionPlanDTO {
this.id, this.id,
required this.name, required this.name,
this.storageQuotaBytes, this.storageQuotaBytes,
this.aiRequestsPerMonth, this.aiTokensPerMonth,
this.statsHistoryDays, this.statsHistoryDays,
this.hasAdvancedStats, this.hasAdvancedStats,
}); });
@ -27,7 +27,7 @@ class SubscriptionPlanDTO {
int? storageQuotaBytes; int? storageQuotaBytes;
int? aiRequestsPerMonth; int? aiTokensPerMonth;
int? statsHistoryDays; int? statsHistoryDays;
@ -40,7 +40,7 @@ class SubscriptionPlanDTO {
other.id == id && other.id == id &&
other.name == name && other.name == name &&
other.storageQuotaBytes == storageQuotaBytes && other.storageQuotaBytes == storageQuotaBytes &&
other.aiRequestsPerMonth == aiRequestsPerMonth && other.aiTokensPerMonth == aiTokensPerMonth &&
other.statsHistoryDays == statsHistoryDays && other.statsHistoryDays == statsHistoryDays &&
other.hasAdvancedStats == hasAdvancedStats; other.hasAdvancedStats == hasAdvancedStats;
@ -49,13 +49,13 @@ class SubscriptionPlanDTO {
(id == null ? 0 : id!.hashCode) + (id == null ? 0 : id!.hashCode) +
(name.hashCode) + (name.hashCode) +
(storageQuotaBytes == null ? 0 : storageQuotaBytes!.hashCode) + (storageQuotaBytes == null ? 0 : storageQuotaBytes!.hashCode) +
(aiRequestsPerMonth == null ? 0 : aiRequestsPerMonth!.hashCode) + (aiTokensPerMonth == null ? 0 : aiTokensPerMonth!.hashCode) +
(statsHistoryDays == null ? 0 : statsHistoryDays!.hashCode) + (statsHistoryDays == null ? 0 : statsHistoryDays!.hashCode) +
(hasAdvancedStats == null ? 0 : hasAdvancedStats!.hashCode); (hasAdvancedStats == null ? 0 : hasAdvancedStats!.hashCode);
@override @override
String toString() => String toString() =>
'SubscriptionPlanDTO[id=$id, name=$name, storageQuotaBytes=$storageQuotaBytes, aiRequestsPerMonth=$aiRequestsPerMonth, statsHistoryDays=$statsHistoryDays, hasAdvancedStats=$hasAdvancedStats]'; 'SubscriptionPlanDTO[id=$id, name=$name, storageQuotaBytes=$storageQuotaBytes, aiTokensPerMonth=$aiTokensPerMonth, statsHistoryDays=$statsHistoryDays, hasAdvancedStats=$hasAdvancedStats]';
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final json = <String, dynamic>{}; final json = <String, dynamic>{};
@ -70,10 +70,10 @@ class SubscriptionPlanDTO {
} else { } else {
json[r'storageQuotaBytes'] = null; json[r'storageQuotaBytes'] = null;
} }
if (this.aiRequestsPerMonth != null) { if (this.aiTokensPerMonth != null) {
json[r'aiRequestsPerMonth'] = this.aiRequestsPerMonth; json[r'aiTokensPerMonth'] = this.aiTokensPerMonth;
} else { } else {
json[r'aiRequestsPerMonth'] = null; json[r'aiTokensPerMonth'] = null;
} }
if (this.statsHistoryDays != null) { if (this.statsHistoryDays != null) {
json[r'statsHistoryDays'] = this.statsHistoryDays; json[r'statsHistoryDays'] = this.statsHistoryDays;
@ -96,7 +96,7 @@ class SubscriptionPlanDTO {
id: mapValueOfType<String>(json, r'id'), id: mapValueOfType<String>(json, r'id'),
name: mapValueOfType<String>(json, r'name') ?? '', name: mapValueOfType<String>(json, r'name') ?? '',
storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'), storageQuotaBytes: mapValueOfType<int>(json, r'storageQuotaBytes'),
aiRequestsPerMonth: mapValueOfType<int>(json, r'aiRequestsPerMonth'), aiTokensPerMonth: mapValueOfType<int>(json, r'aiTokensPerMonth'),
statsHistoryDays: mapValueOfType<int>(json, r'statsHistoryDays'), statsHistoryDays: mapValueOfType<int>(json, r'statsHistoryDays'),
hasAdvancedStats: mapValueOfType<bool>(json, r'hasAdvancedStats'), hasAdvancedStats: mapValueOfType<bool>(json, r'hasAdvancedStats'),
); );