some small fixes

feature/fix-all
Christopher Schmitt 2024-01-13 17:07:11 +01:00
parent 64ebd1258c
commit 96d6822818
25 changed files with 683 additions and 311 deletions

View File

@ -0,0 +1,4 @@
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="5" y="5" width="16.25" height="16.25" stroke="black"/>
<path d="M9.46875 12.0417L9.83733 11.7039L9.46875 11.3018L9.10017 11.7039L9.46875 12.0417ZM12.4479 15.2917L12.0793 15.6296L12.4479 16.0317L12.8165 15.6296L12.4479 15.2917ZM17.2852 10.7546C17.4718 10.5511 17.4581 10.2348 17.2545 10.0482C17.051 9.86157 16.7347 9.87533 16.5481 10.0789L17.2852 10.7546ZM5.36858 17.2546L9.83733 12.3796L9.10017 11.7039L4.63142 16.5789L5.36858 17.2546ZM9.10017 12.3796L12.0793 15.6296L12.8165 14.9539L9.83733 11.7039L9.10017 12.3796ZM12.8165 15.6296L17.2852 10.7546L16.5481 10.0789L12.0793 14.9539L12.8165 15.6296Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 726 B

View File

@ -0,0 +1,4 @@
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.83975 8.28867L13 3.57735L21.1603 8.28867V17.7113L13 22.4227L4.83975 17.7113V8.28867Z" stroke="black"/>
<circle cx="12.9" cy="13.1001" r="4" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 272 B

View File

@ -0,0 +1,3 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="14" cy="14" r="13" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 151 B

View File

@ -2,10 +2,12 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:moody/utils/slide_direction.dart';
import 'package:moody/utils/widgets/question_slider_widget.dart';
import 'package:moody/views/about_page/about_page.dart';
import 'package:moody/views/color_page/color_page.dart';
import 'package:moody/views/entry_view/entry_page.dart';
import 'package:moody/views/first_page/first_page.dart';
import 'package:moody/views/home_page/home_page.dart';
import 'package:moody/views/imprint_page/imprint_page.dart';
import 'package:moody/views/settings_page/settings_page.dart';
import 'package:moody/views/start_page/start_page.dart';
import 'package:moody/views/statistic/statistic_page.dart';
@ -44,6 +46,14 @@ final GoRouter _router = GoRouter(
path: '/color',
pageBuilder: (context, state) => _noAnimationTransition(context, state, const ColorPage()),
),
GoRoute(
path: '/imprint',
pageBuilder: (context, state) => _noAnimationTransition(context, state, const ImprintPage()),
),
GoRoute(
path: '/about',
pageBuilder: (context, state) => _noAnimationTransition(context, state, const AboutPage()),
),
GoRoute(
path: '/write',
builder: (context, state) {

View File

@ -15,7 +15,7 @@ class CirclePainter extends CustomPainter {
..style = PaintingStyle.fill;
double radius = math.pow(((value + 5) * 500 / 100) / 1.5, 1.14).toDouble();
canvas.drawCircle(Offset(55, size.height / 4), radius, paint);
canvas.drawCircle(const Offset(10, 109), radius, paint);
}
@override

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
import 'package:moody/utils/definitions/color_pair.dart';
import 'package:moody/utils/logic/preferences_service.dart';
@ -51,16 +52,18 @@ class _CustomBottomNavigationBar extends State<CustomBottomNavigationBar> {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
// When data is loaded
Color backgroundColor = snapshot.data!.backgroundColor; // Use loaded background color
return buildNavigationBar(backgroundColor);
Color textColor = snapshot.data!.textColor; // Use loaded background color
return buildNavigationBar(backgroundColor, textColor);
} else {
// While loading or if no data, show default or loading indicator
return buildNavigationBar(Colors.white); // Default color or loading indicator
return buildNavigationBar(Colors.white, Colors.black); // Default color or loading indicator
}
},
);
}
Widget buildNavigationBar(Color backgroundColor) {
Widget buildNavigationBar(Color backgroundColor, textColor) {
return Container(
width: 175,
margin: const EdgeInsets.only(bottom: 30),
@ -90,16 +93,16 @@ class _CustomBottomNavigationBar extends State<CustomBottomNavigationBar> {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_buildNavItem(Image.asset('assets/icons/icon-analyze.png'), 0, backgroundColor),
_buildNavItem(Image.asset('assets/icons/icon-logo.png'), 1, backgroundColor),
_buildNavItem(Image.asset('assets/icons/icon-settings.png'), 2, backgroundColor),
_buildNavItem(SvgPicture.asset('assets/icons/icon-analyze.svg', color: textColor), 0, backgroundColor),
_buildNavItem(SvgPicture.asset('assets/icons/logo.svg', color: textColor, fit: BoxFit.cover), 1, backgroundColor),
_buildNavItem(SvgPicture.asset('assets/icons/icon-settings.svg', color: textColor, fit: BoxFit.contain), 2, backgroundColor),
],
),
),
);
}
Widget _buildNavItem(Image icon, int index, Color selectedColor) {
Widget _buildNavItem(SvgPicture icon, int index, Color selectedColor) {
return Container(
height: 40,
width: 40,
@ -115,7 +118,7 @@ class _CustomBottomNavigationBar extends State<CustomBottomNavigationBar> {
onPressed: () => _onItemTapped(index),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
iconSize: 30,
iconSize: 40,
),
);
}

View File

@ -0,0 +1,8 @@
import 'package:flutter/cupertino.dart';
class NoGlowScrollBehavior extends ScrollBehavior {
@override
Widget buildViewportChrome(BuildContext context, Widget child, AxisDirection axisDirection) {
return child; // this line disables the glow effect
}
}

View File

@ -56,7 +56,7 @@ class _QuestionSliderWidget extends State<QuestionSliderWidget> {
}
return Padding(
padding: const EdgeInsets.fromLTRB(0, 150, 20, 0),
padding: const EdgeInsets.fromLTRB(0, 0, 20, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[

View File

@ -39,6 +39,9 @@ class _WhyWidget extends State<WhyWidget> {
@override
Widget build(BuildContext context) {
return TextField(
cursorOpacityAnimates: true,
scrollPhysics: const BouncingScrollPhysics(decelerationRate: ScrollDecelerationRate.normal),
controller: widget.controller,
focusNode: _focusNode,
keyboardType: TextInputType.multiline,
@ -60,7 +63,7 @@ class _WhyWidget extends State<WhyWidget> {
@override
void dispose() {
widget.controller.dispose();
//widget.controller.dispose();
_focusNode.dispose();
super.dispose();
}

View File

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:moody/views/about_page/widgets/team_widget.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/widgets/custom_bottom_navigation_bar.dart';
import '../../utils/widgets/no_Glow_scroll_behavior.dart';
class AboutPage extends StatefulWidget {
const AboutPage({super.key});
@override
State<AboutPage> createState() => _AboutPage();
}
class _AboutPage extends State<AboutPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Padding(
padding: const EdgeInsets.fromLTRB(25, 75, 30, 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.topLeft,
child: GestureDetector(
onTap: () {
context.go("/settings");
},
child: const Padding(
padding: EdgeInsets.only(bottom: 50, left: 0, top: 100),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.chevron_left, color: Colors.black),
Text("settings", style: TextStyle(color: Colors.black, fontSize: 18)),
]),
),
),
),
Expanded(
child: ScrollConfiguration(
behavior: NoGlowScrollBehavior(),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 100),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("about us", style: TextStyle(fontSize: 24)),
const SizedBox(
height: 20,
),
const Text(
style: TextStyle(fontSize: 18, color: Color(0xFF868686)),
"""fulfilled is a thoughtfully crafted journaling app that originated as a dynamic student project at Mannheim University of Applied Sciences.
we Explored the possibilities of mindful journaling and believe in getting a more fulfilled life by reflecting everyday. Developed with passion and innovation, our app is designed to inspire and accompany you on your journey of self-discovery and reflection. """),
TeamWidget(imageUrl: 'https://picsum.photos/400/300', title: "chris", subtitle: """developed fulfilled.
studies computer science"""),
TeamWidget(imageUrl: 'https://picsum.photos/420/300', title: "vlad", subtitle: """developed fulfilled.
studies computer science"""),
TeamWidget(imageUrl: 'https://picsum.photos/300/300', title: "vivi", subtitle: """designed fulfilled.
studies communication design"""),
const SizedBox(
height: 30,
),
const Text("support us", style: TextStyle(fontSize: 18)),
],
),
),
),
),
)
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: const CustomBottomNavigationBar(initialSelectedIndex: 2),
);
}
}

View File

@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
class TeamWidget extends StatelessWidget {
final String imageUrl;
final String title;
final String subtitle;
TeamWidget({
Key? key,
required this.imageUrl,
required this.title,
required this.subtitle,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(0, 20, 0, 20), // Padding around the entire container
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Image.network(
imageUrl,
width: 50, // Set your desired image width
height: 50, // Set your desired image height
),
const SizedBox(width: 20), // Space between the image and the text
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
Text(
subtitle,
style: const TextStyle(
color: Colors.grey,
),
maxLines: 2, // Limit to two lines
overflow: TextOverflow.ellipsis, // Add ellipsis for overflow text
),
],
),
],
),
);
}
}

View File

@ -43,7 +43,7 @@ class _ColorPage extends State<ColorPage> {
return Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Padding(
padding: const EdgeInsets.fromLTRB(30, 75, 30, 30),
padding: const EdgeInsets.fromLTRB(25, 75, 30, 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -54,7 +54,7 @@ class _ColorPage extends State<ColorPage> {
context.go("/settings");
},
child: const Padding(
padding: EdgeInsets.only(bottom: 50, left: 10, top: 100),
padding: EdgeInsets.only(bottom: 50, left: 0, top: 100),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.chevron_left, color: Colors.black),
Text("settings", style: TextStyle(color: Colors.black, fontSize: 18)),
@ -62,23 +62,31 @@ class _ColorPage extends State<ColorPage> {
),
),
),
const Text("change color", style: TextStyle(fontSize: 24)),
const SizedBox(height: 30),
Wrap(
spacing: 15, // space between circles horizontally
runSpacing: 15, // space between circles vertically
children: List.generate(colorPairs.length, (index) => buildColorCircle(index)),
Padding(
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("change color", style: TextStyle(fontSize: 24)),
const SizedBox(height: 30),
Wrap(
spacing: 15, // space between circles horizontally
runSpacing: 15, // space between circles vertically
children: List.generate(colorPairs.length, (index) => buildColorCircle(index)),
),
const Padding(
padding: EdgeInsets.only(top: 50.0),
child: Text("Can't find your favorite color?", style: TextStyle(color: Colors.grey)),
),
const Text("Wish you a color!", style: TextStyle(color: Colors.grey)),
],
),
),
const Padding(
padding: EdgeInsets.only(top: 50.0),
child: Text("Can't find your favorite color?", style: TextStyle(color: Colors.grey)),
),
const Text("Wish you a color!", style: TextStyle(color: Colors.grey)),
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: const CustomBottomNavigationBar(initialSelectedIndex: 2),
floatingActionButton: CustomBottomNavigationBar(initialSelectedIndex: 2),
);
}
@ -87,11 +95,12 @@ class _ColorPage extends State<ColorPage> {
double bubbleWidth = (MediaQuery.of(context).size.width / 3) - 30;
return GestureDetector(
onTap: () async {
onTap: () {
setState(() {
selectedColorIndex = index; // Set selected color
PreferencesService().saveColorPair(colorPairs[index]);
});
await PreferencesService().saveColorPair(colorPairs[index]);
setState(() {});
},
child: Container(
width: bubbleWidth,
@ -103,7 +112,7 @@ class _ColorPage extends State<ColorPage> {
),
child: Container(
decoration: BoxDecoration(
border: selectedColorIndex == index ? Border.all(color: Colors.black, width: 1) : null,
border: selectedColorIndex == index ? Border.all(color: colorPairs[index].textColor, width: 2) : null,
shape: BoxShape.circle,
),
child: Center(

View File

@ -95,6 +95,7 @@ class _EntryPage extends State<EntryPage> {
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () {
@ -104,6 +105,8 @@ class _EntryPage extends State<EntryPage> {
padding: EdgeInsets.only(left: 25, top: 80),
child: Row(children: [
Icon(size: 25, Icons.chevron_left, color: Colors.black), // "<" icon
Text("analytics", style: TextStyle(color: Colors.black, fontSize: 18)),
SizedBox(
height: 140,
)
@ -113,6 +116,8 @@ class _EntryPage extends State<EntryPage> {
Padding(
padding: const EdgeInsets.only(left: 30),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${sliderData.value}%",

View File

@ -69,6 +69,8 @@ class _FirstPage extends State<FirstPage> {
@override
Widget build(BuildContext context) {
double topPadding = MediaQuery.of(context).size.height / 5;
return backgroundColor == Colors.lightGreenAccent
? const CircularProgressIndicator() // Show loading indicator while color is null
: MaterialApp(
@ -79,52 +81,56 @@ class _FirstPage extends State<FirstPage> {
children: [
// Background circle
Positioned.fill(
top: 63,
left: sliderData.position - 50,
top: topPadding,
left: sliderData.position,
child: CustomPaint(
painter: CirclePainter(sliderData.value, backgroundColor),
),
),
// Main content
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// Date
Stack(
children: [
QuestionSliderWidget(
onSliderPositionChanged: (value) {
//print("slider Moved");
},
sliderColor: textColor,
date: DateTime.now(),
questionText: "",
initialSliderValue: 0,
isSliderEnabled: true,
onSliderChanged: (value) {
setState(() {
sliderData = value;
if (!_sliderChanged) _sliderChanged = true;
});
}),
],
),
// Why? button
_sliderChanged
? TextButton(
onPressed: () {
context.go('/write', extra: sliderData);
},
child: const Padding(
padding: EdgeInsets.only(left: 25),
child: Text(
"warum?",
style: TextStyle(color: Colors.black, fontSize: 18),
Padding(
padding: EdgeInsets.only(top: topPadding), // Apply the top padding
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// Date
Stack(
children: [
QuestionSliderWidget(
onSliderPositionChanged: (value) {
//print("slider Moved");
},
sliderColor: textColor,
date: DateTime.now(),
questionText: "",
initialSliderValue: 0,
isSliderEnabled: true,
onSliderChanged: (value) {
setState(() {
sliderData = value;
if (!_sliderChanged) _sliderChanged = true;
});
}),
],
),
// Why? button
_sliderChanged
? TextButton(
onPressed: () {
context.go('/write', extra: sliderData);
},
child: const Padding(
padding: EdgeInsets.only(left: 25),
child: Text(
"warum?",
style: TextStyle(color: Colors.black, fontSize: 18),
),
),
),
)
: const SizedBox.shrink(),
],
)
: const SizedBox.shrink(),
],
),
),
// Skip/Save button
Positioned(

View File

@ -7,6 +7,7 @@ import '../../utils/circle_painter.dart';
import '../../utils/definitions/color_pair.dart';
import '../../utils/logic/preferences_service.dart';
import '../../utils/widgets/custom_bottom_navigation_bar.dart';
import '../../utils/widgets/no_Glow_scroll_behavior.dart';
import '../../utils/widgets/question_slider_widget.dart';
import '../../utils/widgets/why_widget.dart';
@ -85,6 +86,8 @@ class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
double topPadding = MediaQuery.of(context).size.height / 5;
return noData
? const Scaffold(
body: FirstPage(showSkipText: false),
@ -94,74 +97,94 @@ class _HomePageState extends State<HomePage> {
: Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
children: [
// Background circle
Positioned.fill(
top: 25,
left: sliderData.position,
child: CustomPaint(
painter: CirclePainter(sliderData.value, backgroundColor),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
QuestionSliderWidget(
onSliderPositionChanged: (value) {
//print("Slider moved");
},
sliderColor: textColor,
date: DateTime.now(),
questionText: 'today',
initialSliderValue: sliderData.value.toDouble(),
isSliderEnabled: _isTextAreaEditable,
onSliderChanged: (value) {
setState(() {
sliderData.value = value.value;
});
},
child: ScrollConfiguration(
behavior: NoGlowScrollBehavior(),
child: SingleChildScrollView(
child: Stack(
children: [
// Background circle
Positioned.fill(
top: topPadding + 8,
left: sliderData.position + 40,
child: CustomPaint(
painter: CirclePainter(sliderData.value, backgroundColor),
),
Padding(
padding: const EdgeInsets.only(left: 30.0),
),
GestureDetector(
onTap: () {
if (!_isTextAreaEditable) {
setState(() {
if (_isTextAreaEditable) {
_saveEntry();
}
_isTextAreaEditable = !_isTextAreaEditable;
});
}
},
child: Padding(
padding: EdgeInsets.only(top: topPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*MoodTextAreaWidget(
controller: _textController,
initialText: _moodText,
isDisabled: !_isTextAreaEditable,
hasPrefix: false,
autoFocus: _isTextAreaEditable,
forceBlinkingCursor: _isTextAreaEditable,
),*/
_isTextAreaEditable
? WhyWidget(
QuestionSliderWidget(
onSliderPositionChanged: (value) {
//print("Slider moved");
},
sliderColor: textColor,
date: DateTime.now(),
questionText: 'today',
initialSliderValue: sliderData.value.toDouble(),
isSliderEnabled: _isTextAreaEditable,
onSliderChanged: (value) {
setState(() {
sliderData.value = value.value;
});
},
),
Padding(
padding: const EdgeInsets.only(left: 30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*MoodTextAreaWidget(
controller: _textController,
prependWhy: false,
)
: Column(
children: [
const SizedBox(height: 10),
Text(_textController.text, style: TextStyle(color: textColor, fontSize: 18)),
],
initialText: _moodText,
isDisabled: !_isTextAreaEditable,
hasPrefix: false,
autoFocus: _isTextAreaEditable,
forceBlinkingCursor: _isTextAreaEditable,
),*/
_isTextAreaEditable
? WhyWidget(
controller: _textController,
prependWhy: false,
)
: Column(
children: [
const SizedBox(height: 10),
Text(_textController.text, style: TextStyle(color: textColor, fontSize: 18)),
],
),
const SizedBox(height: 20),
GestureDetector(
onTap: _toggleTextAreaEditability,
child: _isTextAreaEditable
? Text(
"- Save",
style: TextStyle(color: textColor, fontSize: 18),
)
: const SizedBox(),
),
const SizedBox(height: 20),
GestureDetector(
onTap: _toggleTextAreaEditability,
child: Text(
_isTextAreaEditable ? "- Save" : "+ Edit",
style: TextStyle(color: textColor, fontSize: 18),
const SizedBox(height: 600),
],
),
),
const SizedBox(height: 600),
],
),
),
],
),
],
),
],
),
),
),
),

View File

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/widgets/custom_bottom_navigation_bar.dart';
import '../../utils/widgets/no_Glow_scroll_behavior.dart';
// ...Include PreferencesService and other necessary imports
class ImprintPage extends StatefulWidget {
const ImprintPage({super.key});
@override
State<ImprintPage> createState() => _ImprintPage();
}
class _ImprintPage extends State<ImprintPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Padding(
padding: const EdgeInsets.fromLTRB(25, 75, 30, 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.topLeft,
child: GestureDetector(
onTap: () {
context.go("/settings");
},
child: const Padding(
padding: EdgeInsets.only(bottom: 50, left: 0, top: 100),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.chevron_left, color: Colors.black),
Text("settings", style: TextStyle(color: Colors.black, fontSize: 18)),
]),
),
),
),
Expanded(
child: ScrollConfiguration(
// Apply the NoGlowScrollBehavior here
behavior: NoGlowScrollBehavior(),
child: const SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 100),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Imprint & privacy policy", style: TextStyle(fontSize: 24, color: Color(0xFF868686))),
SizedBox(
height: 20,
),
Text(style: TextStyle(fontSize: 18, color: Color(0xFF868686)), """vivian gölz
bgm. siegler str.38
68642 bürstadt
kontakt
telefon: +4915730094595
e-mail: post@viviangoelz.com
streitschlichtung
die europäische kommission stellt eine plattform zur online-streitbeilegung (os) bereit: https://ec.europa.eu/consumers/odr unsere e-mail-adresse finden sie oben im impressum. wir sind nicht bereit oder verpflichtet, an streitbeilegungsverfahren vor einer verbraucherschlichtungsstelle teilzunehmen.
haftung für inhalte als diensteanbieter sind wir gemäß § 7 abs.1 tmg für eigene inhalte auf diesen seiten nach den allgemeinen gesetzen verantwortlich. nach §§ 8 bis 10 tmg sind wir als diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde informationen zu überwachen oder nach umständen zu forschen, die auf eine rechtswidrige tätigkeit hinweisen. verpflichtungen zur entfernung oder sperrung der nutzung von informationen nach den allgemeinen gesetzen bleiben hiervon unberührt. eine diesbezügliche haftung ist jedoch erst ab dem zeitpunkt der kenntnis einer konkreten rechtsverletzung möglich. bei bekanntwerden von entsprechenden rechtsverletzungen werden wir diese inhalte umgehend entfernen. haftung für links unser angebot enthält links zu externen websites dritter, auf deren inhalte wir keinen einfluss haben. deshalb können wir für diese fremden inhalte auch keine gewähr übernehmen. für die inhalte der verlinkten seiten ist stets der jeweilige anbieter oder betreiber der seiten verantwortlich. die verlinkten seiten wurden zum zeitpunkt der verlinkung auf mögliche rechtsverstöße überprüft. rechtswidrige inhalte waren zum zeitpunkt der verlinkung nicht erkennbar. eine permanente inhaltliche kontrolle der verlinkten seiten ist jedoch ohne konkrete anhaltspunkte einer rechtsverletzung nicht zumutbar. bei bekanntwerden von rechtsverletzungen werden wir derartige links umgehend entfernen. urheberrechtdie durch die seitenbetreiber erstellten inhalte und werke auf diesen seiten unterliegen dem deutschen urheberrecht. die vervielfältigung, bearbeitung, verbreitung und jede art der verwertung außerhalb der grenzen des urheberrechtes bedürfen der schriftlichen zustimmung des jeweiligen autors bzw. erstellers. downloads und kopien dieser seite sind nur für den privaten, nicht kommerziellen gebrauch gestattet. soweit die inhalte auf dieser seite nicht vom betreiber erstellt wurden, werden die urheberrechte dritter beachtet. insbesondere werden inhalte dritter als solche gekennzeichnet. sollten sie trotzdem auf eine urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden hinweis. bei bekanntwerden von rechtsverletzungen werden wir derartige inhalte umgehend entfernen."""),
],
),
),
),
),
)
],
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: const CustomBottomNavigationBar(initialSelectedIndex: 2),
);
}
}

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:go_router/go_router.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../utils/definitions/style_guide.dart';
import '../../utils/logic/preferences_service.dart';
import '../../utils/widgets/custom_bottom_navigation_bar.dart';
import '../../utils/widgets/no_Glow_scroll_behavior.dart';
import 'widgets/custom_divider_widget.dart';
import 'widgets/set_pin_popup_widget.dart';
import 'widgets/text_switch_container_widget.dart';
@ -30,11 +31,11 @@ class _SettingsPage extends State<SettingsPage> {
setState(() {});
}
Future<void> _launchUrl(Uri url) async {
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
Future<void> _launchUrl(Uri url) async {
if (!await launchUrl(url)) {
throw Exception('Could not launch $url');
}
}
}
@override
Widget build(BuildContext context) {
@ -43,113 +44,114 @@ Future<void> _launchUrl(Uri url) async {
body: Container(
padding: const EdgeInsets.only(bottom: 0),
margin: const EdgeInsets.fromLTRB(30, 30, 30, 0),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
const SizedBox(
height: 100,
),
child: ScrollConfiguration(
behavior: NoGlowScrollBehavior(),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(
height: 100,
),
// Settings section
Container(
margin: const EdgeInsets.only(bottom: 10),
alignment: Alignment.topLeft,
child: const Text('settings', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
TextSwitchContainer(
leftText: "change color",
onTap: () => context.go("/color"),
),
const CustomDivider(),
FutureBuilder<bool>(
future: PreferencesService().isPinEnabled(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator(); // or some other placeholder
}
bool pinEnabled = snapshot.data ?? false; // Default to false if null
return TextSwitchContainer(
leftText: "pin",
hasSwitch: true,
onTap: () => {showSetPinPopup(context)},
onSwitchToggle: (value) {
if (value) {
PreferencesService().enablePin();
} else {
PreferencesService().disablePin();
}
// Consider updating the state here or using other state management
},
switchDefaultValue: pinEnabled,
);
},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "your data",
onTap: () => {},
),
// Community section
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
child: Container(
alignment: Alignment.topLeft,
// Settings section
Container(
margin: const EdgeInsets.only(bottom: 10),
child: const Text('community', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
leftText: "join our discord",
rightText: "fullfilled",
onTap: () async => {
await _launchUrl(Uri.parse("https://discord.gg/qaVjyqHW5s"))
}, // Implement your logic
),
const CustomDivider(),
TextSwitchContainer(
leftText: "our instagram",
rightText: "@get.fulfilled",
onTap: () async => {
await _launchUrl(Uri.parse("http://instagram.com/get.fulfilled"))
}, // Implement your logic
),
const CustomDivider(),
TextSwitchContainer(
leftText: "share fulfilled with your loved ones",
onTap: () => {},
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
child: Container(
alignment: Alignment.topLeft,
child: const Text('humans behind fulfilled', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
child: const Text('settings', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
leftText: "about us",
onTap: () => {},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "support us",
onTap: () => {},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "give feedback",
onTap: () => {},
),
//
ListTile(
title: const Text('imprint & privacy policy', style: TextStyle(color: Colors.grey, fontSize: 15)),
onTap: () => {}, // Implement your logic
),
const SizedBox(
height: 150,
)
],
TextSwitchContainer(
leftText: "change color",
onTap: () => context.go("/color"),
),
const CustomDivider(),
FutureBuilder<bool>(
future: PreferencesService().isPinEnabled(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator(); // or some other placeholder
}
bool pinEnabled = snapshot.data ?? false; // Default to false if null
return TextSwitchContainer(
leftText: "pin",
hasSwitch: true,
onTap: () => {showSetPinPopup(context)},
onSwitchToggle: (value) {
if (value) {
PreferencesService().enablePin();
} else {
PreferencesService().disablePin();
}
// Consider updating the state here or using other state management
},
switchDefaultValue: pinEnabled,
);
},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "your data",
onTap: () => {},
),
// Community section
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
child: Container(
alignment: Alignment.topLeft,
margin: const EdgeInsets.only(bottom: 10),
child: const Text('community', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
leftText: "join our discord",
rightText: "fulfilled",
onTap: () async => {await _launchUrl(Uri.parse("https://discord.gg/qaVjyqHW5s"))}, // Implement your logic
),
const CustomDivider(),
TextSwitchContainer(
leftText: "our instagram",
rightText: "@get.fulfilled",
onTap: () async => {await _launchUrl(Uri.parse("http://instagram.com/get.fulfilled"))}, // Implement your logic
),
const CustomDivider(),
TextSwitchContainer(
leftText: "share fulfilled with your loved ones",
onTap: () => {},
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 10),
child: Container(
alignment: Alignment.topLeft,
child: const Text('humans behind fulfilled', style: TextStyle(fontWeight: FontWeight.w500, fontSize: 24)),
),
),
TextSwitchContainer(
leftText: "about us",
onTap: () => {context.go("/about")},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "support us",
onTap: () => {},
),
const CustomDivider(),
TextSwitchContainer(
leftText: "give feedback",
onTap: () => {},
),
//
SizedBox(
+ height: 30,
),
GestureDetector(
child: const Text('imprint & privacy policy', style: TextStyle(color: Colors.grey, fontSize: 15)),
onTap: () => {context.go("/imprint")}, // Implement your logic
),
const SizedBox(
height: 150,
)
],
),
),
),
),

View File

@ -110,9 +110,10 @@ class _SetPinPopup extends State<SetPinPopup> {
@override
Widget build(BuildContext context) {
return Dialog(
shadowColor: Colors.white,
backgroundColor: Colors.transparent,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 15, tileMode: TileMode.repeated),
child: Container(
height: 600,
width: 400,
@ -130,8 +131,8 @@ class _SetPinPopup extends State<SetPinPopup> {
width: 15,
height: 15,
decoration: BoxDecoration(
color: (_isSettingPin ? _pin.length : _confirmedPin.length) > index ? Colors.black : Colors.transparent,
border: Border.all(color: Colors.grey),
color: (_isSettingPin ? _pin.length : _confirmedPin.length) > index ? const Color(0xffD9D9D9) : Colors.transparent,
border: Border.all(color: const Color(0xffD9D9D9)),
borderRadius: BorderRadius.circular(15),
),
);

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -28,6 +30,7 @@ class PinInputScreen extends StatefulWidget {
class _PinInputScreen extends State<PinInputScreen> {
String _pin = '';
static const int pinLength = 4;
String _displayedText = "welcome back!";
@override
void initState() {
@ -60,7 +63,9 @@ class _PinInputScreen extends State<PinInputScreen> {
});
if (_pin.length == pinLength) {
_validatePin();
Timer(const Duration(milliseconds: 200), () {
_validatePin();
});
}
}
}
@ -76,6 +81,9 @@ class _PinInputScreen extends State<PinInputScreen> {
// Handle wrong pin entry, e.g., reset pin, show error, etc.
if (kDebugMode) {
print("Wrong PIN");
setState(() {
_displayedText = "oops! try again.";
});
}
}
@ -89,43 +97,34 @@ class _PinInputScreen extends State<PinInputScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppStyle.backgroundColor,
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.grey, Colors.red.shade100],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Center(
child: Container(
height: 600,
width: 400,
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Welcome Back!', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(pinLength, (index) {
return Container(
margin: const EdgeInsets.all(4),
width: 15,
height: 15,
decoration: BoxDecoration(
color: _pin.length > index ? Colors.black : Colors.transparent,
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(15),
),
);
}),
),
const SizedBox(height: 20),
..._buildNumberPad(),
],
),
body: Center(
child: Container(
height: 550,
width: 380,
decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_displayedText, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(pinLength, (index) {
return Container(
margin: const EdgeInsets.all(4),
width: 15,
height: 15,
decoration: BoxDecoration(
color: _pin.length > index ? const Color(0xffD9D9D9) : Colors.transparent,
border: Border.all(color: const Color(0xffD9D9D9)),
borderRadius: BorderRadius.circular(15),
),
);
}),
),
const SizedBox(height: 20),
..._buildNumberPad(),
],
),
),
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:moody/utils/widgets/no_Glow_scroll_behavior.dart';
import 'package:moody/views/statistic/widget/calendar_widget.dart';
import 'package:moody/views/statistic/widget/streak_widget.dart';
@ -74,18 +75,21 @@ class _StatisticPage extends State<StatisticPage> {
],
),
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 50),
CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 2, 1)),
CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 1, 1)),
CalendarWidget(currentDate: DateTime.now()),
const SizedBox(
height: 50,
)
],
child: ScrollConfiguration(
behavior: NoGlowScrollBehavior(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 50),
CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 2, 1)),
CalendarWidget(currentDate: DateTime(DateTime.now().year, DateTime.now().month - 1, 1)),
CalendarWidget(currentDate: DateTime.now()),
const SizedBox(
height: 50,
)
],
),
),
),
),

View File

@ -65,9 +65,11 @@ class _CalendarWidget extends State<CalendarWidget> {
list.add(current);
}
// Adjust list to end with a complete week
while (list.length % 7 != 0) {
list.add(list.last.add(const Duration(days: 1)));
// Add dates of the next month to complete the week, if necessary
DateTime firstOfNextMonth = DateTime(date.year, date.month + 1, 1);
while (list.length % 7 != 0 && !firstOfNextMonth.isAfter(DateTime.now())) {
list.add(firstOfNextMonth);
firstOfNextMonth = firstOfNextMonth.add(const Duration(days: 1));
}
return list;
@ -89,9 +91,10 @@ class _CalendarWidget extends State<CalendarWidget> {
return SizedBox(
height: 360 + addon,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30),
child: Text(monthName, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), // Month Header
),
Expanded(
@ -131,7 +134,7 @@ class _CalendarWidget extends State<CalendarWidget> {
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.black, width: 2),
border: Border.all(color: Colors.black, width: 1),
color: DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year
? Colors.transparent // Setting background color for current day
: isCurrentMonth
@ -147,7 +150,7 @@ class _CalendarWidget extends State<CalendarWidget> {
DateTime.now().day == date.day && DateTime.now().month == date.month && DateTime.now().year == date.year
? "today"
: DateFormat("d").format(date),
style: const TextStyle(color: Colors.black),
style: const TextStyle(color: Colors.black, fontSize: 16),
),
],
),

View File

@ -42,7 +42,7 @@ class StreakWidget extends StatelessWidget {
"$dayCount days",
style: const TextStyle(
color: Colors.black,
fontSize: 26,
fontSize: 20,
),
),
),

View File

@ -63,6 +63,8 @@ class _WritePage extends State<WritePage> {
@override
Widget build(BuildContext context) {
double topPadding = MediaQuery.of(context).size.height / 5;
return MaterialApp(
home: Scaffold(
backgroundColor: AppStyle.backgroundColor,
@ -71,7 +73,7 @@ class _WritePage extends State<WritePage> {
children: [
// Background circle
Positioned.fill(
top: 15,
top: topPadding,
left: _sliderData.position - 40,
child: CustomPaint(
painter: CirclePainter(_sliderData.value, backgroundColor),

View File

@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.17.2"
convert:
dependency: transitive
description:
@ -179,6 +179,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
url: "https://pub.dev"
source: hosted
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
@ -259,10 +267,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.9.1"
mockito:
dependency: "direct dev"
description:
@ -287,6 +295,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted
version: "1.0.1"
path_provider_linux:
dependency: transitive
description:
@ -311,14 +327,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.4.0"
platform:
dependency: transitive
description:
name: platform
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
@ -424,18 +448,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.1"
string_scanner:
dependency: transitive
description:
@ -464,10 +488,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
version: "0.6.1"
version: "0.6.0"
typed_data:
dependency: transitive
description:
@ -540,6 +564,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.1"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_math:
dependency: transitive
description:
@ -552,10 +600,10 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583
sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f
url: "https://pub.dev"
source: hosted
version: "11.10.0"
version: "11.7.1"
watcher:
dependency: transitive
description:
@ -568,10 +616,10 @@ packages:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
version: "0.3.0"
version: "0.1.4-beta"
webdriver:
dependency: transitive
description:
@ -596,6 +644,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
description:
@ -605,5 +661,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.2.0-194.0.dev <4.0.0"
dart: ">=3.1.5 <4.0.0"
flutter: ">=3.13.0"

View File

@ -20,6 +20,7 @@ dependencies:
intl: ^0.18.1
url_launcher: ^6.2.2
shared_preferences: ^2.2.2
flutter_svg: ^2.0.9
dev_dependencies:
flutter_test:
@ -50,6 +51,9 @@ flutter:
- assets/icons/icon-analyze.png
- assets/icons/icon-logo.png
- assets/icons/icon-settings.png
- assets/icons/icon-analyze.svg
- assets/icons/logo.svg
- assets/icons/icon-settings.svg
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg