🌐 Localized files
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
@@ -33,7 +34,7 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'File Actions',
|
||||
'fileActions'.tr(),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -45,10 +46,8 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
Symbols.delete_forever,
|
||||
color: theme.colorScheme.error,
|
||||
),
|
||||
title: const Text('Purge Files'),
|
||||
subtitle: const Text(
|
||||
'Remove all uploaded files from the site',
|
||||
),
|
||||
title: Text('purgeFiles'.tr()),
|
||||
subtitle: Text('purgeFilesDescription'.tr()),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
onTap: () => _purgeFiles(context, ref),
|
||||
),
|
||||
@@ -58,10 +57,8 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
Symbols.upload,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
title: const Text('Deploy Site'),
|
||||
subtitle: const Text(
|
||||
'Upload and deploy a new version from ZIP archive',
|
||||
),
|
||||
title: Text('deploySite'.tr()),
|
||||
subtitle: Text('deploySiteDescription'.tr()),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
onTap: () => _deploySite(context, ref),
|
||||
),
|
||||
@@ -79,21 +76,19 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
context: context,
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: const Text('Confirm Purge'),
|
||||
content: const Text(
|
||||
'This will permanently delete all files uploaded to this site. This action cannot be undone. Are you sure you want to continue?',
|
||||
),
|
||||
title: Text('confirmPurge'.tr()),
|
||||
content: Text('purgeFilesConfirm'.tr()),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: const Text('Cancel'),
|
||||
child: Text('cancel'.tr()),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
child: const Text('Purge All Files'),
|
||||
child: Text('purgeAllFiles'.tr()),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -105,13 +100,13 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
final apiClient = ref.read(apiClientProvider);
|
||||
await apiClient.delete('/zone/sites/${site.id}/files/purge');
|
||||
if (context.mounted) {
|
||||
showSnackBar('All files purged successfully');
|
||||
showSnackBar('allFilesPurgedSuccess'.tr());
|
||||
// Refresh the file management section
|
||||
ref.invalidate(siteFilesProvider(siteId: site.id));
|
||||
}
|
||||
} catch (e) {
|
||||
if (context.mounted) {
|
||||
showSnackBar('Failed to purge files: $e');
|
||||
showSnackBar('failedToPurgeFiles'.tr(args: [e.toString()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,13 +142,13 @@ class FileManagementActionSection extends HookConsumerWidget {
|
||||
);
|
||||
|
||||
if (context.mounted) {
|
||||
showSnackBar('Site deployed successfully');
|
||||
showSnackBar('siteDeployedSuccess'.tr());
|
||||
// Refresh the file management section
|
||||
ref.invalidate(siteFilesProvider(siteId: site.id));
|
||||
}
|
||||
} catch (e) {
|
||||
if (context.mounted) {
|
||||
showSnackBar('Failed to deploy site: $e');
|
||||
showSnackBar('failedToDeploySite'.tr(args: [e.toString()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
@@ -42,7 +43,7 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
Icon(Symbols.folder, size: 20),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'File Management',
|
||||
'fileManagement'.tr(),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -75,9 +76,7 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
files =
|
||||
results.map((m) => m['file'] as File).toList();
|
||||
if (files.isEmpty) {
|
||||
showSnackBar(
|
||||
'No files found in the selected folder',
|
||||
);
|
||||
showSnackBar('noFilesFoundInFolder'.tr());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -112,23 +111,23 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
},
|
||||
itemBuilder:
|
||||
(BuildContext context) => [
|
||||
const PopupMenuItem<String>(
|
||||
PopupMenuItem<String>(
|
||||
value: 'files',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Symbols.file_copy),
|
||||
Gap(12),
|
||||
Text('Files'),
|
||||
Text('siteFiles'.tr()),
|
||||
],
|
||||
),
|
||||
),
|
||||
const PopupMenuItem<String>(
|
||||
PopupMenuItem<String>(
|
||||
value: 'folder',
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Symbols.folder),
|
||||
Gap(12),
|
||||
Text('Folder'),
|
||||
Text('siteFolder'.tr()),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -182,7 +181,7 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: () => currentPath.value = null,
|
||||
child: const Text('Root'),
|
||||
child: Text('siteRoot'.tr()),
|
||||
),
|
||||
...() {
|
||||
final parts =
|
||||
@@ -230,12 +229,12 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
),
|
||||
const Gap(16),
|
||||
Text(
|
||||
'No files uploaded yet',
|
||||
'noFilesUploadedYet'.tr(),
|
||||
style: theme.textTheme.bodyLarge,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Upload your first file to get started',
|
||||
'uploadFirstFile'.tr(),
|
||||
style: theme.textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
@@ -265,7 +264,7 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
(error, stack) => Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text('Failed to load files'),
|
||||
Text('failedToLoadFiles'.tr()),
|
||||
const Gap(8),
|
||||
ElevatedButton(
|
||||
onPressed:
|
||||
@@ -275,7 +274,7 @@ class FileManagementSection extends HookConsumerWidget {
|
||||
path: currentPath.value,
|
||||
),
|
||||
),
|
||||
child: const Text('Retry'),
|
||||
child: Text('retry'.tr()),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -29,7 +30,7 @@ class PagesSection extends HookConsumerWidget {
|
||||
const Icon(Symbols.article, size: 20),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Pages',
|
||||
'sitePages'.tr(),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -72,12 +73,12 @@ class PagesSection extends HookConsumerWidget {
|
||||
),
|
||||
const Gap(16),
|
||||
Text(
|
||||
'No pages yet',
|
||||
'noPagesYet'.tr(),
|
||||
style: theme.textTheme.bodyLarge,
|
||||
),
|
||||
const Gap(8),
|
||||
Text(
|
||||
'Create your first page to get started',
|
||||
'createFirstPage'.tr(),
|
||||
style: theme.textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
@@ -101,14 +102,14 @@ class PagesSection extends HookConsumerWidget {
|
||||
(error, stack) => Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Text('Failed to load pages'),
|
||||
Text('failedToLoadPages'.tr()),
|
||||
const Gap(8),
|
||||
ElevatedButton(
|
||||
onPressed:
|
||||
() => ref.invalidate(
|
||||
sitePagesProvider(pubName, site.slug),
|
||||
),
|
||||
child: const Text('Retry'),
|
||||
child: Text('retry'.tr()),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -64,18 +64,16 @@ class SiteActionMenu extends HookConsumerWidget {
|
||||
context: context,
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: const Text('Delete Site'),
|
||||
content: const Text(
|
||||
'Are you sure you want to delete this publication site? This action cannot be undone.',
|
||||
),
|
||||
title: Text('deleteSite'.tr()),
|
||||
content: Text('publicationSiteDeleteConfirm'.tr()),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(false),
|
||||
child: const Text('Cancel'),
|
||||
child: Text('cancel'.tr()),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.of(context).pop(true),
|
||||
child: const Text('Delete'),
|
||||
child: Text('delete'.tr()),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -86,7 +84,7 @@ class SiteActionMenu extends HookConsumerWidget {
|
||||
final client = ref.read(apiClientProvider);
|
||||
await client.delete('/zone/sites/${site.id}');
|
||||
if (context.mounted) {
|
||||
showSnackBar('Site deleted successfully');
|
||||
showSnackBar('siteDeletedSuccess'.tr());
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
@@ -42,20 +43,20 @@ class SiteDetailContent extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Site Information',
|
||||
'siteInformation'.tr(),
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const Gap(16),
|
||||
InfoRow(
|
||||
label: 'Name',
|
||||
label: 'name'.tr(),
|
||||
value: site.name,
|
||||
icon: Symbols.title,
|
||||
),
|
||||
const Gap(8),
|
||||
InfoRow(
|
||||
label: 'Slug',
|
||||
label: 'slug'.tr(),
|
||||
value: site.slug,
|
||||
icon: Symbols.tag,
|
||||
monospace: true,
|
||||
@@ -63,27 +64,30 @@ class SiteDetailContent extends HookConsumerWidget {
|
||||
const Gap(8),
|
||||
InfoRow(
|
||||
label: 'Mode',
|
||||
value: site.mode == 0 ? 'Fully Managed' : 'Self-Managed',
|
||||
value:
|
||||
site.mode == 0
|
||||
? 'siteModeFullyManaged'.tr()
|
||||
: 'siteModeSelfManaged'.tr(),
|
||||
icon: Symbols.settings,
|
||||
),
|
||||
if (site.description != null &&
|
||||
site.description!.isNotEmpty) ...[
|
||||
const Gap(8),
|
||||
InfoRow(
|
||||
label: 'Description',
|
||||
label: 'description'.tr(),
|
||||
value: site.description!,
|
||||
icon: Symbols.description,
|
||||
),
|
||||
],
|
||||
const Gap(8),
|
||||
InfoRow(
|
||||
label: 'Created',
|
||||
label: 'siteCreated'.tr(),
|
||||
value: site.createdAt.formatSystem(),
|
||||
icon: Symbols.calendar_add_on,
|
||||
),
|
||||
const Gap(8),
|
||||
InfoRow(
|
||||
label: 'Updated',
|
||||
label: 'siteUpdated'.tr(),
|
||||
value: site.updatedAt.formatSystem(),
|
||||
icon: Symbols.update,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user