Frontend first draft

This commit is contained in:
Arseni
2025-11-13 15:06:15 +03:00
parent e47f343afb
commit ddb54ddfdc
504 changed files with 25498 additions and 1 deletions

View File

@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:pshared/provider/account.dart';
class AccountAvatar extends StatelessWidget {
const AccountAvatar({super.key});
@override
Widget build(BuildContext context) {
return Consumer<AccountProvider>(
builder: (context, provider, _) => UserAccountsDrawerHeader(
accountName: Text(provider.account?.name ?? 'John Doe'),
accountEmail: Text(provider.account?.login ?? 'john.doe@acme.com'),
currentAccountPicture: CircleAvatar(
backgroundImage: (provider.account?.avatarUrl?.isNotEmpty ?? false)
? CachedNetworkImageProvider(provider.account!.avatarUrl!)
: null,
child: (provider.account?.avatarUrl?.isNotEmpty ?? false)
? null
: const Icon(Icons.account_circle, size: 50),
),
),
);
}
}

View File

@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class DashboardTile extends StatelessWidget {
const DashboardTile({super.key});
@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.dashboard),
title: Text(AppLocalizations.of(context)!.dashboard),
onTap: () => navigate(context, Pages.dashboard),
);
}
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pshared/provider/account.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class LogoutTile extends StatelessWidget {
const LogoutTile({
super.key,
});
@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.logout),
title: Text(AppLocalizations.of(context)!.navigationLogout),
onTap: () => _logout(context),
);
}
void _logout(BuildContext context) {
Navigator.pop(context);
final accountProvider = Provider.of<AccountProvider>(context, listen: false);
accountProvider.logout();
navigateAndReplace(context, Pages.login);
}
}

View File

@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class PermissionsSettingsTile extends StatelessWidget {
const PermissionsSettingsTile({
super.key,
});
@override
Widget build(BuildContext context) => ListTile(
leading: const Icon(Icons.vpn_key),
title: Text(AppLocalizations.of(context)!.navigationPermissionsSettings),
onTap: () {// ToDo: account settings
},
);
}

View File

@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class ProfileSettingsTile extends StatelessWidget {
const ProfileSettingsTile({
super.key,
});
@override
Widget build(BuildContext context) => ListTile(
leading: const Icon(Icons.settings),
title: Text(AppLocalizations.of(context)!.navigationAccountSettings),
onTap: () => navigateNamed(context, Pages.profile),
);
}

View File

@@ -0,0 +1,19 @@
import 'package:flutter/material.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class RolesSettingsTile extends StatelessWidget {
const RolesSettingsTile({
super.key,
});
@override
Widget build(BuildContext context) => ListTile(
leading: const Icon(Icons.manage_accounts),
title: Text(AppLocalizations.of(context)!.navigationRolesSettings),
onTap: () => navigateNamed(context, Pages.roles),
);
}

View File

@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class UsersSettingsTile extends StatelessWidget {
const UsersSettingsTile({
super.key,
});
@override
Widget build(BuildContext context) {
return ListTile(
leading: const Icon(Icons.people),
title: Text(AppLocalizations.of(context)!.navigationUsersSettings),
onTap: () => navigateNamed(context, Pages.users),
);
}
}

View File

@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pshared/models/resources.dart';
import 'package:pshared/provider/permissions.dart';
import 'package:pweb/widgets/drawer/avatar.dart';
import 'package:pweb/widgets/drawer/tiles/dashboard.dart';
import 'package:pweb/widgets/drawer/tiles/logout.dart';
import 'package:pweb/widgets/drawer/tiles/settings/profile.dart';
import 'package:pweb/widgets/drawer/tiles/settings/roles.dart';
import 'package:pweb/widgets/drawer/tiles/settings/users.dart';
class AppDrawer extends StatelessWidget {
const AppDrawer({super.key});
@override
Widget build(BuildContext context) => Drawer(
child: Consumer<PermissionsProvider>(builder:(context, provider, _) =>
ListView(
padding: EdgeInsets.zero,
children: <Widget>[
// Shows user avatar / name / email, etc.
const AccountAvatar(),
const DashboardTile(),
// Profile & Settings
const Divider(),
if (provider.canAccessResource(ResourceType.accounts))
const UsersSettingsTile(),
if (provider.canAccessResource(ResourceType.roles))
const RolesSettingsTile(),
const ProfileSettingsTile(), // always available
// Logout
const Divider(),
const LogoutTile(),
],
),
),
);
}