mirror of
https://github.com/foss42/apidash.git
synced 2025-10-18 20:22:15 +08:00
Feat: New Dashboard
This commit is contained in:
@ -77,7 +77,7 @@ class _DashAppState extends ConsumerState<DashApp> {
|
|||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
),
|
),
|
||||||
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
|
themeMode: isDarkMode ? ThemeMode.dark : ThemeMode.light,
|
||||||
home: const HomePage(),
|
home: const Dashboard(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
|
||||||
|
final navRailIndexStateProvider = StateProvider<int?>((ref) => 0);
|
||||||
final activeIdStateProvider = StateProvider<String?>((ref) => null);
|
final activeIdStateProvider = StateProvider<String?>((ref) => null);
|
||||||
final activeIdEditStateProvider = StateProvider<String?>((ref) => null);
|
final activeIdEditStateProvider = StateProvider<String?>((ref) => null);
|
||||||
final sentRequestIdStateProvider = 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/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:apidash/providers/providers.dart';
|
import 'package:apidash/providers/providers.dart';
|
||||||
import 'package:apidash/widgets/widgets.dart';
|
|
||||||
import 'package:apidash/consts.dart';
|
import 'package:apidash/consts.dart';
|
||||||
import 'details_card/details_card.dart';
|
import 'details_card/details_card.dart';
|
||||||
import 'url_card.dart';
|
import 'url_card.dart';
|
||||||
@ -25,7 +24,7 @@ class _RequestEditorPaneState extends ConsumerState<RequestEditorPane> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final activeId = ref.watch(activeIdStateProvider);
|
final activeId = ref.watch(activeIdStateProvider);
|
||||||
if (activeId == null) {
|
if (activeId == null) {
|
||||||
return const RequestEditorPaneHome();
|
return const RequestEditorDefault();
|
||||||
} else {
|
} else {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: kIsMacOS ? kPt24o8 : kP8,
|
padding: kIsMacOS ? kPt24o8 : kP8,
|
||||||
@ -43,24 +42,41 @@ class _RequestEditorPaneState extends ConsumerState<RequestEditorPane> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequestEditorPaneHome extends ConsumerWidget {
|
class RequestEditorDefault extends ConsumerWidget {
|
||||||
const RequestEditorPaneHome({super.key});
|
const RequestEditorDefault({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final isDarkMode =
|
return Column(
|
||||||
ref.watch(settingsProvider.select((value) => value.isDark));
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
return IntroMessage(
|
Text.rich(
|
||||||
isDarkMode: isDarkMode,
|
TextSpan(
|
||||||
onNew: () {
|
children: [
|
||||||
String newId = ref.read(collectionStateNotifierProvider.notifier).add();
|
TextSpan(
|
||||||
ref.read(activeIdStateProvider.notifier).update((state) => newId);
|
text: "Click ",
|
||||||
},
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
onModeToggle: () async {
|
),
|
||||||
var mode = ref.read(settingsProvider).isDark;
|
WidgetSpan(
|
||||||
await ref.read(settingsProvider.notifier).update(isDark: !mode);
|
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> {
|
class HomePageState extends State<HomePage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return const DashboardSplitView(
|
return Column(
|
||||||
sidebarWidget: CollectionPane(),
|
children: const [
|
||||||
mainWidget: RequestEditorPane(),
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return MultiSplitViewTheme(
|
||||||
body: Column(
|
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: [
|
children: [
|
||||||
Expanded(
|
widget.sidebarWidget,
|
||||||
child: MultiSplitViewTheme(
|
widget.mainWidget,
|
||||||
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,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user