diff --git a/frontend/assets/icons/tile/Frame.svg b/frontend/assets/icons/tile/Frame.svg
new file mode 100644
index 0000000..ff41e24
--- /dev/null
+++ b/frontend/assets/icons/tile/Frame.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/assets/icons/tile/clock.svg b/frontend/assets/icons/tile/clock.svg
new file mode 100644
index 0000000..129e33a
--- /dev/null
+++ b/frontend/assets/icons/tile/clock.svg
@@ -0,0 +1,8 @@
+
diff --git a/frontend/assets/icons/tile/folder.svg b/frontend/assets/icons/tile/folder.svg
new file mode 100644
index 0000000..74fb4ec
--- /dev/null
+++ b/frontend/assets/icons/tile/folder.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/assets/icons/tile/graph.svg b/frontend/assets/icons/tile/graph.svg
new file mode 100644
index 0000000..8c1a34b
--- /dev/null
+++ b/frontend/assets/icons/tile/graph.svg
@@ -0,0 +1,6 @@
+
diff --git a/frontend/lib/components/activity_log.dart b/frontend/lib/components/activity_log.dart
new file mode 100644
index 0000000..8f002fd
--- /dev/null
+++ b/frontend/lib/components/activity_log.dart
@@ -0,0 +1,99 @@
+import 'package:aurcache/components/dashboard/header.dart';
+import 'package:aurcache/utils/responsive.dart';
+import 'package:flutter/material.dart';
+
+class ActivityLog extends StatefulWidget {
+ const ActivityLog({super.key});
+
+ @override
+ State createState() => _ActivityLogState();
+}
+
+class _ActivityLogState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ children: [
+ ActivityLogItem(
+ text: "added Package \"Power\"",
+ timestamp: DateTime.timestamp(),
+ user: "Lukas Heiligenbrunner",
+ ),
+ ActivityLogItem(
+ text: "added Package \"Naps\"",
+ timestamp: DateTime.timestamp(),
+ user: "Evin Arslan",
+ ),
+ ActivityLogItem(
+ text: "added Package \"Not\"",
+ timestamp: DateTime.timestamp(),
+ user: "Sophie Francz",
+ ),
+ ActivityLogItem(
+ text: "added Package \"Powerapps\"",
+ timestamp: DateTime.timestamp(),
+ user: "Lukas Kessler",
+ )
+ ],
+ );
+ }
+}
+
+class ActivityLogItem extends StatelessWidget {
+ const ActivityLogItem(
+ {super.key, this.user, required this.text, required this.timestamp});
+
+ final String? user;
+ final String text;
+ final DateTime timestamp;
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Row(
+ children: [
+ Icon(
+ Icons.circle_outlined,
+ size: 16,
+ color: Color(0xff393C42),
+ ),
+ SizedBox(
+ width: 10,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Text(
+ user ?? "Unknown User",
+ style: TextStyle(fontWeight: FontWeight.bold, fontSize: 19),
+ ),
+ if (context.desktop)
+ SizedBox(
+ width: 5,
+ ),
+ if (context.desktop)
+ Text(
+ text,
+ style: TextStyle(fontSize: 16),
+ )
+ ],
+ ),
+ context.desktop
+ ? Text(
+ timestamp.toString(),
+ style: TextStyle(fontSize: 15),
+ )
+ : Text(
+ text,
+ style: TextStyle(fontSize: 16),
+ )
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/frontend/lib/components/api/ApiBuilder.dart b/frontend/lib/components/api/api_builder.dart
similarity index 100%
rename from frontend/lib/components/api/ApiBuilder.dart
rename to frontend/lib/components/api/api_builder.dart
diff --git a/frontend/lib/components/build_line_chart.dart b/frontend/lib/components/build_line_chart.dart
new file mode 100644
index 0000000..26471a8
--- /dev/null
+++ b/frontend/lib/components/build_line_chart.dart
@@ -0,0 +1,182 @@
+import 'package:aurcache/constants/color_constants.dart';
+import 'package:fl_chart/fl_chart.dart';
+import 'package:flutter/material.dart';
+
+class BuildLineChart extends StatefulWidget {
+ const BuildLineChart({super.key});
+
+ @override
+ State createState() => _BuildLineChartState();
+}
+
+class _BuildLineChartState extends State {
+ List gradientColors = [
+ Colors.purple,
+ Colors.deepPurpleAccent,
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return AspectRatio(
+ aspectRatio: 2,
+ child: LineChart(
+ mainData(),
+ ),
+ );
+ }
+
+ Widget bottomTitleWidgets(double value, TitleMeta meta) {
+ const style = TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ );
+ Widget text;
+ switch (value.toInt()) {
+ case 2:
+ text = const Text('Aug', style: style);
+ break;
+ case 4:
+ text = const Text('Sep', style: style);
+ break;
+ case 6:
+ text = const Text('Oct', style: style);
+ break;
+ case 8:
+ text = const Text('Nov', style: style);
+ break;
+ case 10:
+ text = const Text('Dec', style: style);
+ break;
+ default:
+ text = const Text('', style: style);
+ break;
+ }
+
+ return SideTitleWidget(
+ axisSide: meta.axisSide,
+ child: text,
+ );
+ }
+
+ Widget leftTitleWidgets(double value, TitleMeta meta) {
+ const style = TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 15,
+ );
+ String text;
+ switch (value.toInt()) {
+ case 0:
+ text = '10K';
+ break;
+ case 3:
+ text = '30k';
+ break;
+ case 5:
+ text = '50k';
+ break;
+ default:
+ return Container();
+ }
+
+ return Text(text, style: style, textAlign: TextAlign.left);
+ }
+
+ LineChartData mainData() {
+ return LineChartData(
+ gridData: FlGridData(
+ show: true,
+ drawVerticalLine: false,
+ horizontalInterval: 1,
+ verticalInterval: 1,
+ getDrawingHorizontalLine: (value) {
+ return const FlLine(
+ color: Colors.grey, strokeWidth: 1, dashArray: [5, 5]);
+ },
+ ),
+ titlesData: FlTitlesData(
+ show: true,
+ rightTitles: const AxisTitles(
+ sideTitles: SideTitles(showTitles: false),
+ ),
+ topTitles: const AxisTitles(
+ sideTitles: SideTitles(showTitles: false),
+ ),
+ bottomTitles: AxisTitles(
+ sideTitles: SideTitles(
+ showTitles: true,
+ reservedSize: 30,
+ interval: 1,
+ getTitlesWidget: bottomTitleWidgets,
+ ),
+ ),
+ leftTitles: AxisTitles(
+ sideTitles: SideTitles(
+ showTitles: true,
+ interval: 1,
+ getTitlesWidget: leftTitleWidgets,
+ reservedSize: 42,
+ ),
+ ),
+ ),
+ borderData: FlBorderData(
+ show: false,
+ ),
+ minX: 0,
+ maxX: 10,
+ minY: 0,
+ maxY: 6,
+ lineBarsData: [
+ LineChartBarData(
+ spots: const [
+ FlSpot(0, 3),
+ FlSpot(1, 1),
+ FlSpot(2, 2),
+ FlSpot(3, 1),
+ FlSpot(4, 4),
+ FlSpot(5, 2.5),
+ FlSpot(6, 1.7),
+ FlSpot(7, 2.1),
+ FlSpot(8, 3),
+ FlSpot(9, 4),
+ FlSpot(10, 3),
+ ],
+ isCurved: true,
+ gradient: LinearGradient(
+ colors: gradientColors,
+ ),
+ barWidth: 5,
+ isStrokeCapRound: true,
+ dotData: FlDotData(
+ show: true,
+ getDotPainter: (spot, percent, barData, index) {
+ Color dotColor = Color.lerp(
+ barData.gradient!.colors.first,
+ barData.gradient!.colors.last,
+ percent / 100,
+ )!;
+
+ return FlDotCirclePainter(
+ radius: 6,
+ color: Colors.white,
+ strokeWidth: 3,
+ strokeColor: dotColor,
+ );
+ },
+ checkToShowDot: (spot, barData) {
+ // limitate which dot to sho
+ return true;
+ },
+ ),
+ belowBarData: BarAreaData(
+ show: true,
+ gradient: LinearGradient(
+ colors: gradientColors
+ .map((color) => color.withOpacity(0.3))
+ .toList(),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/frontend/lib/components/dashboard/builds_chart.dart b/frontend/lib/components/dashboard/builds_chart.dart
deleted file mode 100644
index fad5c9b..0000000
--- a/frontend/lib/components/dashboard/builds_chart.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-import 'package:fl_chart/fl_chart.dart';
-import 'package:flutter/material.dart';
-
-class BuildsChart extends StatefulWidget {
- const BuildsChart({
- super.key,
- required this.nrBuilds,
- required this.nrSuccessfulBuilds,
- required this.nrfailedbuilds,
- required this.nrEnqueuedBuilds,
- });
-
- final int nrBuilds;
- final int nrSuccessfulBuilds;
- final int nrfailedbuilds;
- final int nrEnqueuedBuilds;
-
- @override
- _BuildsChartState createState() => _BuildsChartState();
-}
-
-class _BuildsChartState extends State {
- int touchedIndex = -1;
- @override
- Widget build(BuildContext context) {
- return SizedBox(
- height: 300,
- child: AspectRatio(
- aspectRatio: 1.3,
- child: Row(
- children: [
- const SizedBox(
- height: 18,
- ),
- Expanded(
- child: AspectRatio(
- aspectRatio: 1,
- child: PieChart(
- PieChartData(
- pieTouchData: PieTouchData(
- touchCallback: (pieTouchResponse, touchresponse) {
- setState(() {
- // todo hover gesture not working properly
- if (touchresponse?.touchedSection != null) {
- touchedIndex = touchresponse!
- .touchedSection!.touchedSectionIndex;
- } else {
- touchedIndex = -1;
- }
- });
- }),
- borderData: FlBorderData(
- show: false,
- ),
- sectionsSpace: 0,
- centerSpaceRadius: 40,
- sections: showingSections()),
- ),
- ),
- ),
- const SizedBox(
- width: 28,
- ),
- ],
- ),
- ),
- );
- }
-
- List showingSections() {
- return List.generate(3, (i) {
- final isTouched = i == touchedIndex;
- final fontSize = isTouched ? 25.0 : 16.0;
- final radius = isTouched ? 60.0 : 50.0;
- switch (i) {
- case 0:
- return PieChartSectionData(
- color: const Color(0xff760707),
- value: widget.nrfailedbuilds.toDouble(),
- title:
- "${(widget.nrfailedbuilds * 100 / widget.nrBuilds).toStringAsFixed(2)}%",
- radius: radius,
- titleStyle: TextStyle(
- fontSize: fontSize,
- fontWeight: FontWeight.bold,
- color: const Color(0xffffffff)),
- );
- case 1:
- return PieChartSectionData(
- color: const Color(0xff0a7005),
- value: (widget.nrSuccessfulBuilds).toDouble(),
- title:
- "${((widget.nrSuccessfulBuilds) * 100 / widget.nrBuilds).toStringAsFixed(2)}%",
- radius: radius,
- titleStyle: TextStyle(
- fontSize: fontSize,
- fontWeight: FontWeight.bold,
- color: const Color(0xffffffff)),
- );
- case 2:
- return PieChartSectionData(
- color: const Color(0xFF0044AA),
- value: (widget.nrEnqueuedBuilds).toDouble(),
- title:
- "${((widget.nrEnqueuedBuilds) * 100 / widget.nrBuilds).toStringAsFixed(2)}%",
- radius: radius,
- titleStyle: TextStyle(
- fontSize: fontSize,
- fontWeight: FontWeight.bold,
- color: const Color(0xffffffff)),
- );
- default:
- throw Error();
- }
- });
- }
-}
diff --git a/frontend/lib/components/dashboard/quick_info_banner.dart b/frontend/lib/components/dashboard/quick_info_banner.dart
index c8bb226..33ef163 100644
--- a/frontend/lib/components/dashboard/quick_info_banner.dart
+++ b/frontend/lib/components/dashboard/quick_info_banner.dart
@@ -2,9 +2,9 @@ import 'package:aurcache/components/dashboard/quick_info_tile.dart';
import 'package:aurcache/utils/file_formatter.dart';
import 'package:aurcache/utils/time_formatter.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
import '../../constants/color_constants.dart';
-import '../../models/quick_info_data.dart';
import '../../utils/responsive.dart';
import '../../models/stats.dart';
@@ -18,65 +18,119 @@ class QuickInfoBanner extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final Size _size = MediaQuery.of(context).size;
- return Column(
- children: [
- const SizedBox(height: defaultPadding),
- Responsive(
- mobileChild: _buildBanner(
- crossAxisCount: _size.width < 650 ? 2 : 4,
- childAspectRatio: _size.width < 650 ? 1.2 : 1,
- ),
- desktopChild: _buildBanner(
- childAspectRatio: _size.width < 1400 ? 2.75 : 2.75,
- ))
- ],
- );
- }
+ final double iconSize = context.desktop ? 64 : 42;
- List buildQuickInfoData() {
- return [
- QuickInfoData(
- color: primaryColor,
- icon: Icons.widgets,
- title: "Total Packages",
- subtitle: stats.total_packages.toString()),
- QuickInfoData(
- color: const Color(0xFFFFA113),
- icon: Icons.hourglass_top,
- title: "Enqueued Builds",
- subtitle: stats.enqueued_builds.toString()),
- QuickInfoData(
- color: const Color(0xFFA4CDFF),
- icon: Icons.build,
- title: "Total Builds",
- subtitle: stats.total_builds.toString()),
- QuickInfoData(
- color: const Color(0xFFd50000),
- icon: Icons.storage,
- title: "Repo Size",
- subtitle: stats.repo_storage_size.readableFileSize()),
- QuickInfoData(
- color: const Color(0xFF00F260),
- icon: Icons.timelapse,
- title: "Average Build Time",
- subtitle: stats.avg_build_time.readableDuration()),
+ final items = [
+ QuickInfoTile(
+ icon: SvgPicture.asset("assets/icons/tile/Frame.svg",
+ colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
+ width: iconSize),
+ title: "Total Packages",
+ value: stats.total_packages.toString(),
+ positive: false,
+ trend: '10%',
+ ),
+ QuickInfoTile(
+ icon: SvgPicture.asset("assets/icons/tile/graph.svg",
+ colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
+ width: iconSize),
+ title: "Total Builds",
+ value: stats.total_builds.toString(),
+ positive: true,
+ trend: '10%',
+ ),
+ QuickInfoTile(
+ icon: SvgPicture.asset("assets/icons/tile/clock.svg",
+ colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
+ width: iconSize),
+ title: "Repo Size",
+ value: stats.repo_storage_size.readableFileSize(),
+ positive: true,
+ trend: '10%',
+ ),
+ QuickInfoTile(
+ icon: SvgPicture.asset("assets/icons/tile/folder.svg",
+ colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
+ width: iconSize),
+ title: "Average Build Time",
+ value: stats.avg_build_time.readableDuration(),
+ positive: true,
+ trend: '10%',
+ ),
+ QuickInfoTile(
+ icon: AspectRatio(
+ aspectRatio: 1,
+ child: RotatedBox(
+ quarterTurns: 1,
+ child: CircularProgressIndicator(
+ value: 0.85,
+ strokeWidth: 8,
+ color: Colors.green,
+ backgroundColor: Color(0xff292e35),
+ ))),
+ title: "Build Success",
+ value:
+ "${(stats.total_builds != 0 ? (stats.successful_builds * 100 / stats.total_builds) : 0).toInt()}%",
+ positive: false,
+ trend: '10%',
+ ),
];
- }
- Widget _buildBanner({int crossAxisCount = 5, double childAspectRatio = 1}) {
- final quickInfo = buildQuickInfoData();
- return GridView.builder(
- physics: const NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: quickInfo.length,
- gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: crossAxisCount,
- crossAxisSpacing: defaultPadding,
- mainAxisSpacing: defaultPadding,
- childAspectRatio: childAspectRatio,
- ),
- itemBuilder: (context, idx) => QuickInfoTile(data: quickInfo[idx]),
+ return ResponsiveBuilder(
+ mobile: () {
+ return Column(
+ children: [
+ items[0],
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ items[1],
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ items[2],
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ items[3],
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ items[4],
+ ],
+ );
+ },
+ desktop: () {
+ return Row(
+ children: [
+ Expanded(child: items[0]),
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ Expanded(child: items[1]),
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ Expanded(child: items[2]),
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ Expanded(child: items[3]),
+ SizedBox(
+ width: defaultPadding,
+ height: defaultPadding,
+ ),
+ Expanded(child: items[4]),
+ ],
+ );
+ },
);
}
}
diff --git a/frontend/lib/components/dashboard/quick_info_tile.dart b/frontend/lib/components/dashboard/quick_info_tile.dart
index f5b66b5..28a58fb 100644
--- a/frontend/lib/components/dashboard/quick_info_tile.dart
+++ b/frontend/lib/components/dashboard/quick_info_tile.dart
@@ -1,12 +1,22 @@
-import 'package:aurcache/models/quick_info_data.dart';
+import 'package:aurcache/components/dashboard/header.dart';
+import 'package:aurcache/utils/responsive.dart';
import 'package:flutter/material.dart';
import '../../constants/color_constants.dart';
class QuickInfoTile extends StatefulWidget {
- const QuickInfoTile({Key? key, required this.data}) : super(key: key);
+ const QuickInfoTile(
+ {super.key,
+ required this.icon,
+ required this.title,
+ required this.value,
+ required this.positive,
+ required this.trend});
- final QuickInfoData data;
+ final Widget icon;
+ final String title, value;
+ final bool positive;
+ final String trend;
@override
_QuickInfoTileState createState() => _QuickInfoTileState();
@@ -16,50 +26,79 @@ class _QuickInfoTileState extends State {
@override
Widget build(BuildContext context) {
return Container(
- padding: const EdgeInsets.all(defaultPadding),
- decoration: const BoxDecoration(
- color: secondaryColor,
- borderRadius: BorderRadius.all(Radius.circular(10)),
- ),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Container(
- padding: const EdgeInsets.all(defaultPadding * 0.75),
- height: 64,
- width: 64,
- decoration: BoxDecoration(
- color: widget.data.color.withOpacity(0.1),
- borderRadius: const BorderRadius.all(Radius.circular(10)),
- ),
- child: Icon(
- widget.data.icon,
- color: widget.data.color,
- size: 32,
+ padding: const EdgeInsets.all(defaultPadding),
+ decoration: const BoxDecoration(
+ color: secondaryColor,
+ borderRadius: BorderRadius.all(Radius.circular(10)),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ widget.title,
+ style: TextStyle(fontSize: 18),
),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(left: 0),
+ child: Text(
+ widget.value,
+ style: TextStyle(
+ fontSize: context.desktop ? 36 : 24,
+ fontWeight: FontWeight.bold,
+ color: Colors.white),
+ ),
+ ),
+ if (context.desktop)
+ SizedBox(
+ height: 10,
+ ),
+ _buildTrend(),
+ ],
+ ),
+ SizedBox(
+ height: context.desktop ? 64 : 42,
+ child: widget.icon,
+ )
+ ],
+ )
+ ],
+ ));
+ }
+
+ Widget _buildTrend() {
+ if (widget.positive) {
+ return Row(
+ children: [
+ Icon(
+ Icons.keyboard_double_arrow_up_outlined,
+ color: Colors.lightGreen,
),
- Column(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Text(
- widget.data.title,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: Theme.of(context).textTheme.titleSmall,
- ),
- Text(
- widget.data.subtitle,
- style: Theme.of(context)
- .textTheme
- .titleLarge!
- .copyWith(color: Colors.white70),
- ),
- ],
+ Text(
+ widget.trend,
+ style: TextStyle(color: Colors.lightGreen),
+ )
+ ],
+ );
+ } else {
+ return Row(
+ children: [
+ Icon(
+ Icons.keyboard_double_arrow_down_outlined,
+ color: Colors.red,
),
+ Text(
+ widget.trend,
+ style: TextStyle(color: Colors.red),
+ )
],
- ),
- );
+ );
+ }
}
}
diff --git a/frontend/lib/components/dashboard/recent_builds.dart b/frontend/lib/components/dashboard/recent_builds.dart
index c15f8cd..01060e7 100644
--- a/frontend/lib/components/dashboard/recent_builds.dart
+++ b/frontend/lib/components/dashboard/recent_builds.dart
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
import '../../api/API.dart';
import '../../constants/color_constants.dart';
import '../../models/build.dart';
-import '../api/ApiBuilder.dart';
+import '../api/api_builder.dart';
import '../table_info.dart';
class RecentBuilds extends StatelessWidget {
diff --git a/frontend/lib/components/dashboard/side_panel.dart b/frontend/lib/components/dashboard/side_panel.dart
index 99d3c14..5e44fcd 100644
--- a/frontend/lib/components/dashboard/side_panel.dart
+++ b/frontend/lib/components/dashboard/side_panel.dart
@@ -1,8 +1,9 @@
-import 'package:aurcache/components/dashboard/chart_card.dart';
+import 'package:aurcache/components/build_line_chart.dart';
+import 'package:aurcache/components/activity_log.dart';
+import 'package:aurcache/utils/responsive.dart';
import 'package:flutter/material.dart';
import '../../constants/color_constants.dart';
-import 'builds_chart.dart';
class SidePanel extends StatelessWidget {
const SidePanel({
@@ -18,9 +19,7 @@ class SidePanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final nrBuilds = nrSuccessfulBuilds + nrfailedbuilds + nrEnqueuedBuilds;
-
- return Container(
+ final activityWidget = Container(
padding: const EdgeInsets.all(defaultPadding),
decoration: const BoxDecoration(
color: secondaryColor,
@@ -30,65 +29,49 @@ class SidePanel extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
- "Package build success",
+ "Recent Activity",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: defaultPadding),
- nrBuilds > 0
- ? BuildsChart(
- nrBuilds: nrBuilds,
- nrSuccessfulBuilds: nrSuccessfulBuilds,
- nrfailedbuilds: nrfailedbuilds,
- nrEnqueuedBuilds: nrEnqueuedBuilds)
- : const SizedBox(
- width: double.infinity,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SizedBox(
- height: 15,
- ),
- Icon(
- Icons.info_outline_rounded,
- size: 42,
- ),
- SizedBox(
- height: 15,
- ),
- Text("Add Packages to view Graph"),
- SizedBox(
- height: 30,
- )
- ],
- ),
- ),
- SideCard(
- color: const Color(0xff0a7005),
- title: "Successful Builds",
- textRight:
- "${(nrBuilds != 0 ? (nrSuccessfulBuilds * 100 / nrBuilds) : 0).toStringAsFixed(2)}%",
- subtitle: (nrSuccessfulBuilds).toString(),
- ),
- SideCard(
- color: const Color(0xff760707),
- title: "Failed Builds",
- textRight:
- "${(nrBuilds != 0 ? (nrfailedbuilds * 100 / nrBuilds) : 0).toStringAsFixed(2)}%",
- subtitle: nrfailedbuilds.toString(),
- ),
- SideCard(
- color: const Color(0xFF0044AA),
- title: "Enqueued Builds",
- textRight:
- "${(nrBuilds != 0 ? (nrEnqueuedBuilds * 100 / nrBuilds) : 0).toStringAsFixed(2)}%",
- subtitle: nrEnqueuedBuilds.toString(),
- ),
+ ActivityLog()
],
),
);
+
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ padding: const EdgeInsets.all(defaultPadding),
+ decoration: const BoxDecoration(
+ color: secondaryColor,
+ borderRadius: BorderRadius.all(Radius.circular(10)),
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text(
+ "Builds Per Month",
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ const SizedBox(height: defaultPadding),
+ BuildLineChart()
+ ],
+ ),
+ ),
+ SizedBox(
+ height: defaultPadding,
+ ),
+ Responsive(
+ mobileChild: activityWidget,
+ desktopChild: Expanded(child: activityWidget))
+ ],
+ );
}
}
diff --git a/frontend/lib/components/dashboard/your_packages.dart b/frontend/lib/components/dashboard/your_packages.dart
index 752671d..f16f588 100644
--- a/frontend/lib/components/dashboard/your_packages.dart
+++ b/frontend/lib/components/dashboard/your_packages.dart
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
import '../../api/API.dart';
import '../../constants/color_constants.dart';
import '../../models/simple_packge.dart';
-import '../api/ApiBuilder.dart';
+import '../api/api_builder.dart';
import '../table_info.dart';
class YourPackages extends StatelessWidget {
diff --git a/frontend/lib/components/packages_table.dart b/frontend/lib/components/packages_table.dart
index 265ce1f..09cc085 100644
--- a/frontend/lib/components/packages_table.dart
+++ b/frontend/lib/components/packages_table.dart
@@ -1,5 +1,5 @@
import 'package:aurcache/api/packages.dart';
-import 'package:aurcache/components/api/ApiBuilder.dart';
+import 'package:aurcache/components/api/api_builder.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
diff --git a/frontend/lib/models/quick_info_data.dart b/frontend/lib/models/quick_info_data.dart
deleted file mode 100644
index 25c80e4..0000000
--- a/frontend/lib/models/quick_info_data.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-import 'package:flutter/material.dart';
-
-class QuickInfoData {
- const QuickInfoData({
- Key? key,
- required this.color,
- required this.icon,
- required this.title,
- required this.subtitle,
- });
-
- final Color color;
- final IconData icon;
- final String title, subtitle;
-}
diff --git a/frontend/lib/screens/Package_settings_screen.dart b/frontend/lib/screens/Package_settings_screen.dart
index 7eb6d3a..41f1a9d 100644
--- a/frontend/lib/screens/Package_settings_screen.dart
+++ b/frontend/lib/screens/Package_settings_screen.dart
@@ -7,7 +7,7 @@ import 'package:provider/provider.dart';
import 'package:toastification/toastification.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../models/extended_package.dart';
class Packagesettingsscreen extends StatefulWidget {
diff --git a/frontend/lib/screens/aur_screen.dart b/frontend/lib/screens/aur_screen.dart
index d710a7e..d21ee80 100644
--- a/frontend/lib/screens/aur_screen.dart
+++ b/frontend/lib/screens/aur_screen.dart
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../constants/color_constants.dart';
class AurScreen extends StatefulWidget {
diff --git a/frontend/lib/screens/build_screen.dart b/frontend/lib/screens/build_screen.dart
index 3acd950..80f2ce7 100644
--- a/frontend/lib/screens/build_screen.dart
+++ b/frontend/lib/screens/build_screen.dart
@@ -10,7 +10,7 @@ import 'package:provider/provider.dart';
import 'package:toastification/toastification.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../components/confirm_popup.dart';
import '../components/dashboard/chart_card.dart';
import '../constants/color_constants.dart';
diff --git a/frontend/lib/screens/builds_screen.dart b/frontend/lib/screens/builds_screen.dart
index 8833a2c..0568d76 100644
--- a/frontend/lib/screens/builds_screen.dart
+++ b/frontend/lib/screens/builds_screen.dart
@@ -3,7 +3,7 @@ import 'package:aurcache/components/builds_table.dart';
import 'package:aurcache/components/table_info.dart';
import 'package:flutter/material.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../constants/color_constants.dart';
import '../models/build.dart';
diff --git a/frontend/lib/screens/dashboard_screen.dart b/frontend/lib/screens/dashboard_screen.dart
index 360015e..c3cc77e 100644
--- a/frontend/lib/screens/dashboard_screen.dart
+++ b/frontend/lib/screens/dashboard_screen.dart
@@ -1,5 +1,5 @@
import 'package:aurcache/api/statistics.dart';
-import 'package:aurcache/components/api/ApiBuilder.dart';
+import 'package:aurcache/components/api/api_builder.dart';
import 'package:aurcache/models/simple_packge.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -26,10 +26,55 @@ class _DashboardScreenState extends State {
interval: const Duration(seconds: 10),
onData: (stats) {
return SafeArea(
- child: SingleChildScrollView(
- child: Container(
+ child: Builder(builder: (context) {
+ final body = MultiProvider(
+ providers: [
+ ChangeNotifierProvider(
+ create: (context) => APIController>(),
+ ),
+ ChangeNotifierProvider(
+ create: (context) => APIController>(),
+ ),
+ ],
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Expanded(
+ flex: 3,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ YourPackages(),
+ const SizedBox(height: defaultPadding),
+ const RecentBuilds(),
+ if (context.mobile)
+ const SizedBox(height: defaultPadding),
+ if (context.mobile)
+ SidePanel(
+ nrSuccessfulBuilds: stats.successful_builds,
+ nrfailedbuilds: stats.failed_builds,
+ nrEnqueuedBuilds: stats.enqueued_builds),
+ ],
+ ),
+ ),
+ if (!context.mobile) const SizedBox(width: defaultPadding),
+ // On Mobile means if the screen is less than 850 we dont want to show it
+ if (!context.mobile)
+ Expanded(
+ flex: 2,
+ child: SidePanel(
+ nrSuccessfulBuilds: stats.successful_builds,
+ nrfailedbuilds: stats.failed_builds,
+ nrEnqueuedBuilds: stats.enqueued_builds),
+ ),
+ ],
+ ),
+ );
+
+ final allScreen = Container(
padding: const EdgeInsets.all(defaultPadding),
child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
children: [
const Header(),
const SizedBox(height: defaultPadding),
@@ -37,54 +82,20 @@ class _DashboardScreenState extends State {
stats: stats,
),
const SizedBox(height: defaultPadding),
- MultiProvider(
- providers: [
- ChangeNotifierProvider(
- create: (context) =>
- APIController>(),
- ),
- ChangeNotifierProvider(
- create: (context) => APIController>(),
- ),
- ],
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Expanded(
- flex: 5,
- child: Column(
- children: [
- YourPackages(),
- const SizedBox(height: defaultPadding),
- const RecentBuilds(),
- if (context.mobile)
- const SizedBox(height: defaultPadding),
- if (context.mobile)
- SidePanel(
- nrSuccessfulBuilds: stats.successful_builds,
- nrfailedbuilds: stats.failed_builds,
- nrEnqueuedBuilds: stats.enqueued_builds),
- ],
- ),
- ),
- if (!context.mobile)
- const SizedBox(width: defaultPadding),
- // On Mobile means if the screen is less than 850 we dont want to show it
- if (!context.mobile)
- Expanded(
- flex: 2,
- child: SidePanel(
- nrSuccessfulBuilds: stats.successful_builds,
- nrfailedbuilds: stats.failed_builds,
- nrEnqueuedBuilds: stats.enqueued_builds),
- ),
- ],
- ),
- )
+ Responsive(
+ mobileChild: body, desktopChild: Expanded(child: body))
],
),
- ),
- ),
+ );
+
+ if (context.mobile) {
+ return SingleChildScrollView(
+ child: allScreen,
+ );
+ } else {
+ return allScreen;
+ }
+ }),
);
},
onLoad: () {
diff --git a/frontend/lib/screens/package_screen.dart b/frontend/lib/screens/package_screen.dart
index c66c5e6..c00751b 100644
--- a/frontend/lib/screens/package_screen.dart
+++ b/frontend/lib/screens/package_screen.dart
@@ -8,7 +8,7 @@ import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../components/builds_table.dart';
import '../components/confirm_popup.dart';
import '../constants/color_constants.dart';
diff --git a/frontend/lib/screens/packages_screen.dart b/frontend/lib/screens/packages_screen.dart
index 6188b23..dc85632 100644
--- a/frontend/lib/screens/packages_screen.dart
+++ b/frontend/lib/screens/packages_screen.dart
@@ -3,7 +3,7 @@ import 'package:aurcache/components/packages_table.dart';
import 'package:flutter/material.dart';
import '../api/API.dart';
-import '../components/api/ApiBuilder.dart';
+import '../components/api/api_builder.dart';
import '../constants/color_constants.dart';
class PackagesScreen extends StatelessWidget {
diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml
index 7b977d1..0abeb8e 100644
--- a/frontend/pubspec.yaml
+++ b/frontend/pubspec.yaml
@@ -70,6 +70,7 @@ flutter:
uses-material-design: true
assets:
- assets/icons/
+ - assets/icons/tile/
# To add assets to your application, add an assets section, like this:
# assets: