mirror of
https://github.com/foss42/apidash.git
synced 2025-10-16 19:22:23 +08:00
Feat: New Dashboard
This commit is contained in:
@ -77,7 +77,7 @@ class _DashAppState extends ConsumerState<DashApp> {
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
|
||||
home: const HomePage(),
|
||||
home: const Dashboard(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final navRailIndexStateProvider = StateProvider<int?>((ref) => 0);
|
||||
final activeIdStateProvider = StateProvider<String?>((ref) => null);
|
||||
final activeIdEditStateProvider = StateProvider<String?>((ref) => null);
|
||||
final sentRequestIdStateProvider = StateProvider<String?>((ref) => null);
|
||||
|
84
lib/screens/dashboard.dart
Normal file
84
lib/screens/dashboard.dart
Normal file
@ -0,0 +1,84 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:apidash/providers/providers.dart';
|
||||
import 'home_page/home_page.dart';
|
||||
import 'intro_page.dart';
|
||||
import 'package:apidash/consts.dart';
|
||||
|
||||
class Dashboard extends ConsumerStatefulWidget {
|
||||
const Dashboard({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<Dashboard> createState() => _DashboardState();
|
||||
}
|
||||
|
||||
class _DashboardState extends ConsumerState<Dashboard> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final railIdx = ref.watch(navRailIndexStateProvider);
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
NavigationRail(
|
||||
selectedIndex: railIdx,
|
||||
groupAlignment: -1.0,
|
||||
onDestinationSelected: (int index) {
|
||||
setState(() {
|
||||
ref
|
||||
.read(navRailIndexStateProvider.notifier)
|
||||
.update((state) => index);
|
||||
});
|
||||
},
|
||||
labelType: NavigationRailLabelType.all,
|
||||
leading: SizedBox(height: kIsMacOS ? 24.0 : 8.0),
|
||||
trailing: Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
ref
|
||||
.read(navRailIndexStateProvider.notifier)
|
||||
.update((state) => null);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.settings_outlined,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
destinations: const <NavigationRailDestination>[
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.home_outlined),
|
||||
selectedIcon: Icon(Icons.home),
|
||||
label: Text('Home'),
|
||||
),
|
||||
NavigationRailDestination(
|
||||
icon: Icon(Icons.auto_awesome_mosaic_outlined),
|
||||
selectedIcon: Icon(Icons.auto_awesome_mosaic),
|
||||
label: Text('Requests'),
|
||||
),
|
||||
],
|
||||
),
|
||||
VerticalDivider(
|
||||
thickness: 1,
|
||||
width: 1,
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
),
|
||||
Expanded(
|
||||
child: <int?, Widget>{
|
||||
null: const IntroPage(),
|
||||
0: const IntroPage(),
|
||||
1: const HomePage()
|
||||
}[railIdx]!,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:apidash/providers/providers.dart';
|
||||
import 'package:apidash/widgets/widgets.dart';
|
||||
import 'package:apidash/consts.dart';
|
||||
import 'details_card/details_card.dart';
|
||||
import 'url_card.dart';
|
||||
@ -25,7 +24,7 @@ class _RequestEditorPaneState extends ConsumerState<RequestEditorPane> {
|
||||
Widget build(BuildContext context) {
|
||||
final activeId = ref.watch(activeIdStateProvider);
|
||||
if (activeId == null) {
|
||||
return const RequestEditorPaneHome();
|
||||
return const RequestEditorDefault();
|
||||
} else {
|
||||
return Padding(
|
||||
padding: kIsMacOS ? kPt24o8 : kP8,
|
||||
@ -43,24 +42,41 @@ class _RequestEditorPaneState extends ConsumerState<RequestEditorPane> {
|
||||
}
|
||||
}
|
||||
|
||||
class RequestEditorPaneHome extends ConsumerWidget {
|
||||
const RequestEditorPaneHome({super.key});
|
||||
class RequestEditorDefault extends ConsumerWidget {
|
||||
const RequestEditorDefault({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isDarkMode =
|
||||
ref.watch(settingsProvider.select((value) => value.isDark));
|
||||
|
||||
return IntroMessage(
|
||||
isDarkMode: isDarkMode,
|
||||
onNew: () {
|
||||
String newId = ref.read(collectionStateNotifierProvider.notifier).add();
|
||||
ref.read(activeIdStateProvider.notifier).update((state) => newId);
|
||||
},
|
||||
onModeToggle: () async {
|
||||
var mode = ref.read(settingsProvider).isDark;
|
||||
await ref.read(settingsProvider.notifier).update(isDark: !mode);
|
||||
},
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: "Click ",
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
ref.read(collectionStateNotifierProvider.notifier).add();
|
||||
},
|
||||
child: const Text(
|
||||
kLabelPlusNew,
|
||||
style: kTextStyleButton,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: " to start drafting a new API request.",
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,15 @@ class HomePage extends StatefulWidget {
|
||||
class HomePageState extends State<HomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const DashboardSplitView(
|
||||
sidebarWidget: CollectionPane(),
|
||||
mainWidget: RequestEditorPane(),
|
||||
return Column(
|
||||
children: const [
|
||||
Expanded(
|
||||
child: DashboardSplitView(
|
||||
sidebarWidget: CollectionPane(),
|
||||
mainWidget: RequestEditorPane(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
27
lib/screens/intro_page.dart
Normal file
27
lib/screens/intro_page.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:apidash/providers/providers.dart';
|
||||
import 'package:apidash/widgets/widgets.dart';
|
||||
|
||||
class IntroPage extends ConsumerWidget {
|
||||
const IntroPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final isDarkMode =
|
||||
ref.watch(settingsProvider.select((value) => value.isDark));
|
||||
|
||||
return Scaffold(
|
||||
body: IntroMessage(
|
||||
isDarkMode: isDarkMode,
|
||||
onNew: () {
|
||||
ref.read(collectionStateNotifierProvider.notifier).add();
|
||||
},
|
||||
onModeToggle: () async {
|
||||
var mode = ref.read(settingsProvider).isDark;
|
||||
await ref.read(settingsProvider.notifier).update(isDark: !mode);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
export "home_page/home_page.dart";
|
||||
export "dashboard.dart";
|
||||
|
@ -31,31 +31,22 @@ class DashboardSplitViewState extends State<DashboardSplitView> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
return MultiSplitViewTheme(
|
||||
data: MultiSplitViewThemeData(
|
||||
dividerThickness: 3,
|
||||
dividerPainter: DividerPainters.background(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
highlightedColor: Theme.of(context).colorScheme.outline.withOpacity(
|
||||
kHintOpacity,
|
||||
),
|
||||
animationEnabled: false,
|
||||
),
|
||||
),
|
||||
child: MultiSplitView(
|
||||
controller: _controller,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MultiSplitViewTheme(
|
||||
data: MultiSplitViewThemeData(
|
||||
dividerThickness: 3,
|
||||
dividerPainter: DividerPainters.background(
|
||||
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||
highlightedColor:
|
||||
Theme.of(context).colorScheme.outline.withOpacity(
|
||||
kHintOpacity,
|
||||
),
|
||||
animationEnabled: false,
|
||||
),
|
||||
),
|
||||
child: MultiSplitView(
|
||||
controller: _controller,
|
||||
children: [
|
||||
widget.sidebarWidget,
|
||||
widget.mainWidget,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
widget.sidebarWidget,
|
||||
widget.mainWidget,
|
||||
],
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user