Compare commits

...

19 Commits

Author SHA1 Message Date
Niklas cdf1cdec71 Kurze Änderung der Datenbank 2025-04-08 23:40:02 +02:00
Niklas f73d535281 Datenabruf anhand von Kategorie und Datum 2025-01-14 20:56:06 +01:00
Niklas b2a752879b Optimised the loading from the database by lowering the amount of loads. 2024-12-30 02:26:34 +01:00
Niklas 20b6bc5146 Solved the Update problem für die Hoime Seite 2024-12-30 02:19:47 +01:00
Niklas 4acf6fcb41 Kleines Cleaning und Beim zurückwechseln zur Hauptseite wir ddiese auch wieder aktualisiert. 2024-12-30 02:07:30 +01:00
Niklas 7f4449ea4c Wish down and update funktioniert nun auf beiden Screens !!! Yeah 2024-12-29 21:02:10 +01:00
Niklas 5c94a129b4 Small changes done. 2024-12-27 21:44:52 +01:00
Niklas 9c0124fc18 New but no real change, oder? 2024-12-22 23:46:25 +01:00
Niklas b234ae8207 New Icon's and not completely cleaned up but it works. 2024-12-04 22:42:30 +01:00
Niklas e069ec90a4 Auto stash before merge of "HEAD" and "clippath_picture" 2024-12-01 19:21:25 +01:00
Niklas ffe05a385c Auto stash before merge of "HEAD" and "clippath_picture" 2024-12-01 19:21:16 +01:00
Niklas 5421e4abc8 Auto stash before merge of "HEAD" and "clippath_picture" 2024-12-01 19:19:09 +01:00
Niklas 9406654a4c Auto stash before merge of "origin/master" and "6c82c322da5103700554a01cec358c90c6ab7994" 2024-12-01 19:18:41 +01:00
Niklas 86f6304826 Merge branch 'master' into clippath_picture 2024-11-30 18:56:57 +01:00
Niklas 781a903e11 shorten title to 24 2024-11-30 17:44:10 +01:00
Niklas 6dfb3dfb7d gitignore updated 2024-11-30 17:42:19 +01:00
Niklas 0e990437ef Merge branch 'clippath_picture' into HEAD + flutter version 3.24.5 2024-11-30 17:41:47 +01:00
Niklas 880e45746c images entfernt. 2024-11-30 15:47:47 +01:00
Niklas 315ee45015 Optimierungen durch dart fix --apply und Ein bild wurde mal herausgenommen ahtte probleme bereitet 2024-11-30 12:17:48 +01:00
82 changed files with 1504 additions and 725 deletions

1
.gitignore vendored
View File

@ -140,3 +140,4 @@ app.*.symbols
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock
!.vscode/settings.json
pubspec.lock

View File

@ -25,7 +25,9 @@ if (flutterVersionName == null) {
android {
namespace "com.example.learn_project"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
//ndkVersion flutter.ndkVersion
ndkVersion = "26.1.10909125"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8

View File

@ -29,6 +29,9 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="true" />
</application>
<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.7.10'
ext.kotlin_version = '2.1.0'
repositories {
google()
mavenCentral()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 76 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 KiB

After

Width:  |  Height:  |  Size: 593 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 KiB

After

Width:  |  Height:  |  Size: 831 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 569 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M19.5,3.8c-.4,0-.8.3-.8.8v4.5c0,1.5-2,2.3-2,2.3-.3.1-.5.4-.5.7v8c0,.4.3.8.8.8s.8-.3.8-.8v-7.5c.8-.5,2.5-1.6,2.5-3.5v-4.5c0-.4-.3-.8-.8-.8Z"/>
<path d="M17,9.2c.4,0,.8-.3.8-.8v-4c0-.4-.3-.8-.8-.8s-.8.3-.8.8v4c0,.4.3.8.8.8Z"/>
<path d="M13.5,3.8H4.5c-.3,0-.6.2-.7.6,0,.2-1.2,4.5,0,7,.9,1.9,3.4,3.5,4.4,4.1v3.8h-2.2c-.4,0-.8.3-.8.8s.3.8.8.8h6c.4,0,.8-.3.8-.8s-.3-.8-.8-.8h-2.2v-3.8c1-.6,3.5-2.2,4.4-4.1,1.2-2.5,0-6.8,0-7,0-.3-.4-.6-.7-.6ZM12.8,10.7c-.7,1.4-2.7,2.8-3.8,3.5-1.1-.7-3.2-2.1-3.8-3.5,0,0,0,0,0,0-.7-1.4-.4-4,0-5.4h7.8c.3,1.4.6,4,0,5.4Z"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M22.5,8.8h-2.5c-.4,0-.8.3-.8.8v1.8h-7V3c0-.4-.3-.8-.8-.8C6.4,2.2,2.2,6.4,2.2,11.5s.2,3.9,1,4.5c.1.1.3.2.4.4.1.2.4.4.6.4s.3,0,.4-.1c.4-.2.5-.7.2-1-.3-.5-.6-.7-.8-.9-.1-.1-.3-.2-.4-2h15.4c-.2,1-.5,2-1.1,2.9-.2.4-.1.8.2,1,.1,0,.3.1.4.1.3,0,.5-.1.6-.4.9-1.5,1.4-3.2,1.4-4.9v-1.2h1.8c.4,0,.8-.3.8-.8s-.3-.8-.8-.8ZM10.8,3.8v7.5H3.8c.1-3.9,3.1-7.1,7-7.5Z"/>
<path d="M8,16.2c-1.5,0-2.8,1.2-2.8,2.8s1.2,2.8,2.8,2.8,2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8ZM8,20.2c-.7,0-1.2-.6-1.2-1.2s.6-1.2,1.2-1.2,1.2.6,1.2,1.2-.6,1.2-1.2,1.2Z"/>
<path d="M15,16.2c-1.5,0-2.8,1.2-2.8,2.8s1.2,2.8,2.8,2.8,2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8ZM15,20.2c-.7,0-1.2-.6-1.2-1.2s.6-1.2,1.2-1.2,1.2.6,1.2,1.2-.6,1.2-1.2,1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M16,16.1l-.7-1.5c-.2-.4-.6-.5-1-.3-.4.2-.5.6-.3,1l.9,1.8c.1.2.3.4.5.4,1,.2,3.3,1,3.3,2.1s0,.6-.2.7c-.1,0-.4,0-.5,0,0,0-.2,0-.2,0h-4.4l-1-.6,1.6-1.1c.3-.2.4-.7.2-1-.2-.3-.7-.5-1-.2l-2.7,1.8-2.1,1.1h-1.9c0,0-.2,0-.2,0,0,0-.4,0-.5,0,0,0-.2-.3-.2-.7,0-1,2.2-1.8,3.3-2.1.2,0,.4-.2.5-.4l.9-1.8c.2-.4,0-.8-.3-1-.4-.2-.8,0-1,.3l-.7,1.5c-1.1.3-4.1,1.3-4.1,3.5s.4,1.6.8,1.9c.4.3.8.3,1.1.3s.5,0,.6,0h2c.1,0,.2,0,.3,0l2-1.1,1.9,1.1c.1,0,.2,0,.4,0h4.5c.1,0,.4,0,.6,0s.7,0,1.1-.3c.4-.3.8-.8.8-1.9,0-2.2-3-3.2-4.1-3.5Z"/>
<path d="M21.1,15.2s-1.7-.3-2.9-.7c-.9-4.1-3.1-6.3-6.2-6.2h-.1c-3-.1-5.2,2.1-6.2,6.2-1.3.4-2.9.8-2.9.8-.4,0-.7.5-.6.9,0,.3.4.6.7.6s.1,0,.2,0c0,0,2.1-.5,3.4-.9.3,0,.5-.3.5-.6.5-2.5,1.7-5.5,4.7-5.4h.1s.1,0,.1,0c3-.1,4.2,2.9,4.7,5.4,0,.3.2.5.5.6,1.3.5,3.4.9,3.5.9.4,0,.8-.2.9-.6,0-.4-.2-.8-.6-.9Z"/>
<path d="M12,7.8c1.5,0,2.8-1.2,2.8-2.8s-1.2-2.8-2.8-2.8-2.8,1.2-2.8,2.8,1.2,2.8,2.8,2.8ZM12,3.8c.7,0,1.2.6,1.2,1.2s-.6,1.2-1.2,1.2-1.2-.6-1.2-1.2.6-1.2,1.2-1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M23,2.2h-1.6c-.7,0-1.4.6-1.4,1.4v2.9c-.9,0-1.8.7-1.8,1.6s.7,1.6,1.7,1.6,1.6-.7,1.6-1.6V3.8h1.5c.4,0,.8-.3.8-.8s-.3-.8-.8-.8Z"/>
<path d="M13.2,15c0,1.5,1.2,2.8,2.8,2.8s2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8-2.8,1.2-2.8,2.8ZM16,13.8c.7,0,1.2.6,1.2,1.2s-.6,1.2-1.2,1.2-1.2-.6-1.2-1.2.6-1.2,1.2-1.2Z"/>
<path d="M22.1,12.3c-.4,0-.8.3-.8.7-.5,4.7-4.4,8.3-9.3,8.3S2.8,16.9,2.8,12,6.9,2.8,12,2.8s4.8,1,4.9,1c0,0,0,0,0,0,.3.3.8.3,1.1,0s.3-.7,0-1c-.4-.5-1.7-1.6-6-1.6S1.2,6.1,1.2,12s5,10.8,10.8,10.8,10.2-4.2,10.7-9.7c0-.4-.3-.8-.7-.8Z"/>
<path d="M7.2,8.5c0,.7.5,1.2,1.2,1.2s1.2-.5,1.2-1.2-.5-1.2-1.2-1.2-1.2.5-1.2,1.2Z"/>
<path d="M16.8,8.5c0-.7-.5-1.2-1.2-1.2s-1.2.5-1.2,1.2.5,1.2,1.2,1.2,1.2-.5,1.2-1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 948 B

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M12.5,21.8c-5.7,0-10.2-4.6-10.2-10.2S4.4,4.2,8,2.3c.2-.1.5-.1.7,0,.2.1.4.4.4.6,0,8,3.9,12,12,12s.5.1.6.3.2.5,0,.7c-1.7,3.5-3.8,5.7-9.2,5.7ZM7.6,4.3c-2.4,1.7-3.8,4.3-3.8,7.2,0,4.8,3.9,8.8,8.8,8.8s5.9-1.3,7.3-3.8c-7.7-.4-11.8-4.4-12.2-12.1Z"/>
<path d="M17.5,11.8c-1.2,0-2.2-1-2.2-2.2s1-2.2,2.2-2.2.5,0,.8.1v-3.8c0-.7.6-1.4,1.3-1.4h1.4c.4,0,.8.3.8.8s-.3.8-.8.8h-1.2v5.8c0,1.2-1,2.2-2.2,2.2ZM17.5,8.8c-.4,0-.8.4-.8.8s.4.8.8.8.8-.4.8-.8-.4-.8-.8-.8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 695 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M15.8,8.5c.6-.5.9-1.2,1-2,0,0,0,0,0,0h0c0-.1,0-.2,0-.2,0-.7-.4-1.4-.9-1.8-.5-.6-1.3-1-2.2-1s-1.2.2-1.7.6c-1.2-.8-2.8-.7-3.8.4s-.9,1.3-.9,2.1.3,1.6.9,2.1l2.9,2.9c.2.2.6.4.9.4s.7-.1.9-.4c.5-.5,1-1,1.5-1.5.5-.5.9-1,1.4-1.4ZM12,10.2l-2.8-2.8c-.3-.3-.5-.7-.5-1.1s.2-.8.5-1.1.7-.5,1.1-.5.8.2,1.1.5.2.2.3.2c0,0,0,0,0,0,.3.1.7,0,.9-.2s.7-.5,1.1-.5.7,0,1.1.5c.3.3.5.7.5,1,0,.3,0,.7-.5,1-.5.5-1,1-1.5,1.5-.4.5-.9.9-1.3,1.4Z"/>
<path d="M20.5,8.2c-1.2,0-2.2,1-2.2,2.2v2.9c-1-.3-2,0-2.8.7l-.9.9c-.5.5-.8,1.2-.8,1.9v3.2c0,.4.3.8.8.8s.8-.3.8-.8v-3.2c0-.3.1-.6.4-.9l.9-.9c.4-.4,1-.5,1.4-.3h0s-.6.6-.6.6c-.3.3-.3.8,0,1.1s.8.3,1.1,0l.9-.9s0,0,0,0c.2-.1.3-.3.3-.6v-4.5c0-.4.4-.8.8-.8s.8.4.8.8v5.2l-3.8,3.8c-.3.3-.3.8,0,1.1s.3.2.5.2.4,0,.5-.2l3.8-3.8c.2-.2.4-.6.4-.9v-5.3c0-1.2-1-2.2-2.2-2.2Z"/>
<path d="M8.5,14.1c-.8-.8-1.8-1-2.8-.7v-2.9c0-1.2-1-2.2-2.2-2.2s-2.2,1-2.2,2.2v5.3c0,.3.2.7.4.9l3.8,3.8c.1.1.3.2.5.2s.4,0,.5-.2c.3-.3.3-.8,0-1.1l-3.8-3.8v-5.2c0-.4.4-.8.8-.8s.8.4.8.8v4.5c0,.2.1.4.3.6,0,0,0,0,0,0l.9.9c.3.3.8.3,1.1,0s.3-.8,0-1.1l-.6-.6h0c.5-.3,1-.2,1.4.2l.9.9c.2.2.4.6.4.9v3.2c0,.4.3.8.8.8s.8-.3.8-.8v-3.2c0-.7-.3-1.4-.8-1.9l-.9-.9Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M14,7.8c-1.5,0-2.8-1.2-2.8-2.8s1.2-2.8,2.8-2.8,2.8,1.2,2.8,2.8-1.2,2.8-2.8,2.8ZM14,3.8c-.7,0-1.2.6-1.2,1.2s.6,1.2,1.2,1.2,1.2-.6,1.2-1.2-.6-1.2-1.2-1.2Z"/>
<path d="M18,21.8c-2.1,0-3.8-1.6-3.8-3.8s1.6-3.8,3.8-3.8,3.8,1.6,3.8,3.8-1.6,3.8-3.8,3.8ZM18,15.8c-1.3,0-2.2,1-2.2,2.2s1,2.2,2.2,2.2,2.2-1,2.2-2.2-1-2.2-2.2-2.2Z"/>
<path d="M6,21.8c-2.1,0-3.8-1.6-3.8-3.8s1.6-3.8,3.8-3.8,3.8,1.6,3.8,3.8-1.6,3.8-3.8,3.8ZM6,15.8c-1.3,0-2.2,1-2.2,2.2s1,2.2,2.2,2.2,2.2-1,2.2-2.2-1-2.2-2.2-2.2Z"/>
<path d="M11.5,18.8c0,0-.2,0-.3,0-.4-.1-.6-.6-.4-1l1.2-3.3-4.2-1.7c-.2,0-.4-.3-.4-.5s0-.5.2-.7l3-3.5c.3-.3.7-.4,1,0l2.8,2.3h3.2c.4,0,.8.3.8.8s-.3.8-.8.8h-3.5c-.2,0-.3,0-.5-.2l-2.4-2-1.8,2.1,3.9,1.6c.4.2.6.6.4,1l-1.5,4c-.1.3-.4.5-.7.5Z"/>
</svg>

After

Width:  |  Height:  |  Size: 972 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M19.5,3.8c-.4,0-.8.3-.8.8v4.5c0,1.5-2,2.3-2,2.3-.3.1-.5.4-.5.7v8c0,.4.3.8.8.8s.8-.3.8-.8v-7.5c.8-.5,2.5-1.6,2.5-3.5v-4.5c0-.4-.3-.8-.8-.8Z"/>
<path d="M17,9.2c.4,0,.8-.3.8-.8v-4c0-.4-.3-.8-.8-.8s-.8.3-.8.8v4c0,.4.3.8.8.8Z"/>
<path d="M13.5,3.8H4.5c-.3,0-.6.2-.7.6,0,.2-1.2,4.5,0,7,.9,1.9,3.4,3.5,4.4,4.1v3.8h-2.2c-.4,0-.8.3-.8.8s.3.8.8.8h6c.4,0,.8-.3.8-.8s-.3-.8-.8-.8h-2.2v-3.8c1-.6,3.5-2.2,4.4-4.1,1.2-2.5,0-6.8,0-7,0-.3-.4-.6-.7-.6ZM12.8,10.7c-.7,1.4-2.7,2.8-3.8,3.5-1.1-.7-3.2-2.1-3.8-3.5,0,0,0,0,0,0-.7-1.4-.4-4,0-5.4h7.8c.3,1.4.6,4,0,5.4Z"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M22.5,8.8h-2.5c-.4,0-.8.3-.8.8v1.8h-7V3c0-.4-.3-.8-.8-.8C6.4,2.2,2.2,6.4,2.2,11.5s.2,3.9,1,4.5c.1.1.3.2.4.4.1.2.4.4.6.4s.3,0,.4-.1c.4-.2.5-.7.2-1-.3-.5-.6-.7-.8-.9-.1-.1-.3-.2-.4-2h15.4c-.2,1-.5,2-1.1,2.9-.2.4-.1.8.2,1,.1,0,.3.1.4.1.3,0,.5-.1.6-.4.9-1.5,1.4-3.2,1.4-4.9v-1.2h1.8c.4,0,.8-.3.8-.8s-.3-.8-.8-.8ZM10.8,3.8v7.5H3.8c.1-3.9,3.1-7.1,7-7.5Z"/>
<path d="M8,16.2c-1.5,0-2.8,1.2-2.8,2.8s1.2,2.8,2.8,2.8,2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8ZM8,20.2c-.7,0-1.2-.6-1.2-1.2s.6-1.2,1.2-1.2,1.2.6,1.2,1.2-.6,1.2-1.2,1.2Z"/>
<path d="M15,16.2c-1.5,0-2.8,1.2-2.8,2.8s1.2,2.8,2.8,2.8,2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8ZM15,20.2c-.7,0-1.2-.6-1.2-1.2s.6-1.2,1.2-1.2,1.2.6,1.2,1.2-.6,1.2-1.2,1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 931 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M16,16.1l-.7-1.5c-.2-.4-.6-.5-1-.3-.4.2-.5.6-.3,1l.9,1.8c.1.2.3.4.5.4,1,.2,3.3,1,3.3,2.1s0,.6-.2.7c-.1,0-.4,0-.5,0,0,0-.2,0-.2,0h-4.4l-1-.6,1.6-1.1c.3-.2.4-.7.2-1-.2-.3-.7-.5-1-.2l-2.7,1.8-2.1,1.1h-1.9c0,0-.2,0-.2,0,0,0-.4,0-.5,0,0,0-.2-.3-.2-.7,0-1,2.2-1.8,3.3-2.1.2,0,.4-.2.5-.4l.9-1.8c.2-.4,0-.8-.3-1-.4-.2-.8,0-1,.3l-.7,1.5c-1.1.3-4.1,1.3-4.1,3.5s.4,1.6.8,1.9c.4.3.8.3,1.1.3s.5,0,.6,0h2c.1,0,.2,0,.3,0l2-1.1,1.9,1.1c.1,0,.2,0,.4,0h4.5c.1,0,.4,0,.6,0s.7,0,1.1-.3c.4-.3.8-.8.8-1.9,0-2.2-3-3.2-4.1-3.5Z"/>
<path d="M21.1,15.2s-1.7-.3-2.9-.7c-.9-4.1-3.1-6.3-6.2-6.2h-.1c-3-.1-5.2,2.1-6.2,6.2-1.3.4-2.9.8-2.9.8-.4,0-.7.5-.6.9,0,.3.4.6.7.6s.1,0,.2,0c0,0,2.1-.5,3.4-.9.3,0,.5-.3.5-.6.5-2.5,1.7-5.5,4.7-5.4h.1s.1,0,.1,0c3-.1,4.2,2.9,4.7,5.4,0,.3.2.5.5.6,1.3.5,3.4.9,3.5.9.4,0,.8-.2.9-.6,0-.4-.2-.8-.6-.9Z"/>
<path d="M12,7.8c1.5,0,2.8-1.2,2.8-2.8s-1.2-2.8-2.8-2.8-2.8,1.2-2.8,2.8,1.2,2.8,2.8,2.8ZM12,3.8c.7,0,1.2.6,1.2,1.2s-.6,1.2-1.2,1.2-1.2-.6-1.2-1.2.6-1.2,1.2-1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M12.1,23.5c-.6,0-1-.3-1.2-.8l-2.9-6s0,0,0,0l-6-2.9c-.5-.2-.8-.7-.8-1.2s.3-1,.8-1.2l6-2.9s0,0,0,0l2.8-6c.2-.5.7-.8,1.2-.8s1,.3,1.2.8l2.9,6s0,0,0,0l6,2.9c.5.2.8.7.8,1.2s-.3,1-.8,1.2l-6,2.9s0,0,0,0l-2.9,6c-.2.5-.7.8-1.2.8ZM11.9,22.1s0,0,0,0h0ZM9.3,16.1l2.7,5.8,2.8-5.8c0,0,0-.1.1-.2.1-.2.3-.4.6-.5l5.8-2.7-5.8-2.8c0,0-.1,0-.2-.1-.2-.1-.4-.3-.5-.6l-2.7-5.8-2.8,5.8c0,0,0,.1-.1.2-.1.2-.3.4-.6.5l-5.8,2.7,5.8,2.8c0,0,.1,0,.2.1.2.1.4.3.5.6ZM15.8,16.8h0,0ZM15.8,16.8h0ZM7.9,16.3h0ZM7.9,16.3h0s0,0,0,0ZM21.6,12.7s0,0,0,0h0ZM2.5,12.4h0s0,0,0,0ZM16.2,8.8h0s0,0,0,0ZM16.2,8.8h0ZM8.3,8.4h0ZM8.3,8.4h0,0ZM11.5,2.7h0,0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 852 B

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M23,2.2h-1.6c-.7,0-1.4.6-1.4,1.4v2.9c-.9,0-1.8.7-1.8,1.6s.7,1.6,1.7,1.6,1.6-.7,1.6-1.6V3.8h1.5c.4,0,.8-.3.8-.8s-.3-.8-.8-.8Z"/>
<path d="M13.2,15c0,1.5,1.2,2.8,2.8,2.8s2.8-1.2,2.8-2.8-1.2-2.8-2.8-2.8-2.8,1.2-2.8,2.8ZM16,13.8c.7,0,1.2.6,1.2,1.2s-.6,1.2-1.2,1.2-1.2-.6-1.2-1.2.6-1.2,1.2-1.2Z"/>
<path d="M22.1,12.3c-.4,0-.8.3-.8.7-.5,4.7-4.4,8.3-9.3,8.3S2.8,16.9,2.8,12,6.9,2.8,12,2.8s4.8,1,4.9,1c0,0,0,0,0,0,.3.3.8.3,1.1,0s.3-.7,0-1c-.4-.5-1.7-1.6-6-1.6S1.2,6.1,1.2,12s5,10.8,10.8,10.8,10.2-4.2,10.7-9.7c0-.4-.3-.8-.7-.8Z"/>
<path d="M7.2,8.5c0,.7.5,1.2,1.2,1.2s1.2-.5,1.2-1.2-.5-1.2-1.2-1.2-1.2.5-1.2,1.2Z"/>
<path d="M16.8,8.5c0-.7-.5-1.2-1.2-1.2s-1.2.5-1.2,1.2.5,1.2,1.2,1.2,1.2-.5,1.2-1.2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 948 B

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M12.5,21.8c-5.7,0-10.2-4.6-10.2-10.2S4.4,4.2,8,2.3c.2-.1.5-.1.7,0,.2.1.4.4.4.6,0,8,3.9,12,12,12s.5.1.6.3.2.5,0,.7c-1.7,3.5-3.8,5.7-9.2,5.7ZM7.6,4.3c-2.4,1.7-3.8,4.3-3.8,7.2,0,4.8,3.9,8.8,8.8,8.8s5.9-1.3,7.3-3.8c-7.7-.4-11.8-4.4-12.2-12.1Z"/>
<path d="M17.5,11.8c-1.2,0-2.2-1-2.2-2.2s1-2.2,2.2-2.2.5,0,.8.1v-3.8c0-.7.6-1.4,1.3-1.4h1.4c.4,0,.8.3.8.8s-.3.8-.8.8h-1.2v5.8c0,1.2-1,2.2-2.2,2.2ZM17.5,8.8c-.4,0-.8.4-.8.8s.4.8.8.8.8-.4.8-.8-.4-.8-.8-.8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 695 B

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M15.8,8.5c.6-.5.9-1.2,1-2,0,0,0,0,0,0h0c0-.1,0-.2,0-.2,0-.7-.4-1.4-.9-1.8-.5-.6-1.3-1-2.2-1s-1.2.2-1.7.6c-1.2-.8-2.8-.7-3.8.4s-.9,1.3-.9,2.1.3,1.6.9,2.1l2.9,2.9c.2.2.6.4.9.4s.7-.1.9-.4c.5-.5,1-1,1.5-1.5.5-.5.9-1,1.4-1.4ZM12,10.2l-2.8-2.8c-.3-.3-.5-.7-.5-1.1s.2-.8.5-1.1.7-.5,1.1-.5.8.2,1.1.5.2.2.3.2c0,0,0,0,0,0,.3.1.7,0,.9-.2s.7-.5,1.1-.5.7,0,1.1.5c.3.3.5.7.5,1,0,.3,0,.7-.5,1-.5.5-1,1-1.5,1.5-.4.5-.9.9-1.3,1.4Z"/>
<path d="M20.5,8.2c-1.2,0-2.2,1-2.2,2.2v2.9c-1-.3-2,0-2.8.7l-.9.9c-.5.5-.8,1.2-.8,1.9v3.2c0,.4.3.8.8.8s.8-.3.8-.8v-3.2c0-.3.1-.6.4-.9l.9-.9c.4-.4,1-.5,1.4-.3h0s-.6.6-.6.6c-.3.3-.3.8,0,1.1s.8.3,1.1,0l.9-.9s0,0,0,0c.2-.1.3-.3.3-.6v-4.5c0-.4.4-.8.8-.8s.8.4.8.8v5.2l-3.8,3.8c-.3.3-.3.8,0,1.1s.3.2.5.2.4,0,.5-.2l3.8-3.8c.2-.2.4-.6.4-.9v-5.3c0-1.2-1-2.2-2.2-2.2Z"/>
<path d="M8.5,14.1c-.8-.8-1.8-1-2.8-.7v-2.9c0-1.2-1-2.2-2.2-2.2s-2.2,1-2.2,2.2v5.3c0,.3.2.7.4.9l3.8,3.8c.1.1.3.2.5.2s.4,0,.5-.2c.3-.3.3-.8,0-1.1l-3.8-3.8v-5.2c0-.4.4-.8.8-.8s.8.4.8.8v4.5c0,.2.1.4.3.6,0,0,0,0,0,0l.9.9c.3.3.8.3,1.1,0s.3-.8,0-1.1l-.6-.6h0c.5-.3,1-.2,1.4.2l.9.9c.2.2.4.6.4.9v3.2c0,.4.3.8.8.8s.8-.3.8-.8v-3.2c0-.7-.3-1.4-.8-1.9l-.9-.9Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<path d="M14,7.8c-1.5,0-2.8-1.2-2.8-2.8s1.2-2.8,2.8-2.8,2.8,1.2,2.8,2.8-1.2,2.8-2.8,2.8ZM14,3.8c-.7,0-1.2.6-1.2,1.2s.6,1.2,1.2,1.2,1.2-.6,1.2-1.2-.6-1.2-1.2-1.2Z"/>
<path d="M18,21.8c-2.1,0-3.8-1.6-3.8-3.8s1.6-3.8,3.8-3.8,3.8,1.6,3.8,3.8-1.6,3.8-3.8,3.8ZM18,15.8c-1.3,0-2.2,1-2.2,2.2s1,2.2,2.2,2.2,2.2-1,2.2-2.2-1-2.2-2.2-2.2Z"/>
<path d="M6,21.8c-2.1,0-3.8-1.6-3.8-3.8s1.6-3.8,3.8-3.8,3.8,1.6,3.8,3.8-1.6,3.8-3.8,3.8ZM6,15.8c-1.3,0-2.2,1-2.2,2.2s1,2.2,2.2,2.2,2.2-1,2.2-2.2-1-2.2-2.2-2.2Z"/>
<path d="M11.5,18.8c0,0-.2,0-.3,0-.4-.1-.6-.6-.4-1l1.2-3.3-4.2-1.7c-.2,0-.4-.3-.4-.5s0-.5.2-.7l3-3.5c.3-.3.7-.4,1,0l2.8,2.3h3.2c.4,0,.8.3.8.8s-.3.8-.8.8h-3.5c-.2,0-.3,0-.5-.2l-2.4-2-1.8,2.1,3.9,1.6c.4.2.6.6.4,1l-1.5,4c-.1.3-.4.5-.7.5Z"/>
</svg>

After

Width:  |  Height:  |  Size: 972 B

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M11.5,3C6.8,3,3,6.8,3,11.5s.5,3.2,1.3,4.5"/>
<path class="st0" d="M18.7,16c.8-1.3,1.3-2.8,1.3-4.5v-2h2.5"/>
<path class="st0" d="M8,21c-1.1,0-2-.9-2-2s.9-2,2-2,2,.9,2,2-.9,2-2,2Z"/>
<path class="st0" d="M15,21c-1.1,0-2-.9-2-2s.9-2,2-2,2,.9,2,2-.9,2-2,2Z"/>
<path class="st0" d="M11.5,3v9"/>
<path class="st0" d="M3.5,12h16"/>
</svg>

After

Width:  |  Height:  |  Size: 791 B

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M14.6,15l.9,1.8s3.9.8,3.9,2.8-1.7,1.4-1.7,1.4h-4.6l-2.2-1.2"/>
<path class="st0" d="M9.4,15l-.9,1.8s-3.9.8-3.9,2.8,1.7,1.4,1.7,1.4h2.1l2.3-1.2,2.8-1.8"/>
<path class="st0" d="M3,15.9s2.1-.5,3.4-.9c1.3-6.5,5.1-6,5.6-6s4.3-.5,5.6,6c1.3.5,3.4.9,3.4.9"/>
<path class="st0" d="M12,7c1.1,0,2-.9,2-2s-.9-2-2-2-2,.9-2,2,.9,2,2,2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 786 B

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M6,20h3M12,20h-3M9,20v-5"/>
<path class="st0" d="M17,20v-8s2.5-1,2.5-3v-4.5"/>
<path class="st0" d="M17,8.5v-4"/>
<path class="st0" d="M4.5,11c1,2.1,4.5,4,4.5,4,0,0,3.5-1.9,4.5-4,1.1-2.3,0-6.5,0-6.5H4.5s-1.1,4.2,0,6.5Z"/>
</svg>

After

Width:  |  Height:  |  Size: 683 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M11.5,2.7c.2-.5.9-.5,1.1,0l2.9,6.1c0,.1.2.2.3.3l6.1,2.9c.5.2.5.9,0,1.1l-6.1,2.9c-.1,0-.2.2-.3.3l-2.9,6.1c-.2.5-.9.5-1.1,0l-2.9-6.1c0-.1-.2-.2-.3-.3l-6.1-2.9c-.5-.2-.5-.9,0-1.1l6.1-2.9c.1,0,.2-.2.3-.3l2.9-6.1Z"/>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M11.5,2.7c.2-.5.9-.5,1.1,0l2.9,6.1c0,.1.2.2.3.3l6.1,2.9c.5.2.5.9,0,1.1l-6.1,2.9c-.1,0-.2.2-.3.3l-2.9,6.1c-.2.5-.9.5-1.1,0l-2.9-6.1c0-.1-.2-.2-.3-.3l-6.1-2.9c-.5-.2-.5-.9,0-1.1l6.1-2.9c.1,0,.2-.2.3-.3l2.9-6.1Z"/>
</svg>

After

Width:  |  Height:  |  Size: 667 B

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0, .st1 {
stroke-linejoin: round;
}
.st0, .st1, .st2 {
stroke: #000;
stroke-linecap: round;
stroke-width: 1.5px;
}
.st1, .st2 {
fill: none;
}
</style>
</defs>
<path d="M20.8,8.1c0,.5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9Z"/>
<path class="st2" d="M20.8,8.1c0,.5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9ZM20.8,8.1V3.6c0-.3.3-.6.6-.6h1.6"/>
<path class="st1" d="M16,17c-1.1,0-2-.9-2-2s.9-2,2-2,2,.9,2,2-.9,2-2,2Z"/>
<path class="st1" d="M22,13c-.5,5.1-4.8,9-10,9S2,17.5,2,12,6.5,2,12,2s2.8.3,4,.8"/>
<path class="st0" d="M8.5,9c-.3,0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5Z"/>
<path class="st0" d="M15.5,9c-.3,0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1012 B

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
stroke-linejoin: round;
}
.st0, .st1 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M3,11.5c0,5.2,4.3,9.5,9.5,9.5s7-2.1,8.5-5.3c-8.5,0-12.7-4.2-12.7-12.7-3.1,1.6-5.3,4.8-5.3,8.5Z"/>
<path class="st1" d="M19,9.5c0,.8-.7,1.5-1.5,1.5s-1.5-.7-1.5-1.5.7-1.5,1.5-1.5,1.5.7,1.5,1.5ZM19,9.5V3.6c0-.3.3-.6.6-.6h1.4"/>
</svg>

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0, .st1 {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-width: 1.5px;
}
.st1 {
stroke-linecap: round;
}
</style>
</defs>
<path class="st0" d="M16,6.3c0,.6-.2,1.2-.7,1.6-1,1-1.9,2-2.9,3-.2.2-.6.2-.8,0l-2.9-2.9c-.9-.9-.9-2.3,0-3.2.9-.9,2.3-.9,3.2,0h.1c0,.1.1,0,.1,0,.4-.4,1-.7,1.6-.7s1.2.2,1.6.7c.4.4.7,1,.7,1.6Z"/>
<path class="st1" d="M18,20l3.8-3.8c.1-.1.2-.3.2-.4v-5.3c0-.8-.7-1.5-1.5-1.5h0c-.8,0-1.5.7-1.5,1.5v4.5"/>
<path class="st1" d="M18,16l.9-.9c0,0,.1-.2.1-.3h0c0-.2-.1-.4-.3-.4l-.4-.2c-.8-.4-1.7-.2-2.3.4l-.9.9c-.4.4-.6.9-.6,1.4v3.2"/>
<path class="st1" d="M6,20l-3.8-3.8c-.1-.1-.2-.3-.2-.4v-5.3c0-.8.7-1.5,1.5-1.5h0c.8,0,1.5.7,1.5,1.5v4.5"/>
<path class="st1" d="M6,16l-.9-.9c0,0-.1-.2-.1-.3h0c0-.2.1-.4.3-.4l.4-.2c.8-.4,1.7-.2,2.3.4l.9.9c.4.4.6.9.6,1.4v3.2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24">
<!-- Generator: Adobe Illustrator 29.0.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 192) -->
<defs>
<style>
.st0 {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
</defs>
<path class="st0" d="M14,7c1.1,0,2-.9,2-2s-.9-2-2-2-2,.9-2,2,.9,2,2,2Z"/>
<path class="st0" d="M18,21c1.7,0,3-1.3,3-3s-1.3-3-3-3-3,1.3-3,3,1.3,3,3,3Z"/>
<path class="st0" d="M6,21c1.7,0,3-1.3,3-3s-1.3-3-3-3-3,1.3-3,3,1.3,3,3,3Z"/>
<path class="st0" d="M11.5,18l1.5-4-4.9-2,3-3.5,3,2.5h3.5"/>
</svg>

After

Width:  |  Height:  |  Size: 732 B

View File

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

View File

@ -1,5 +1,5 @@
PODS:
- app_links (0.0.1):
- app_links (0.0.2):
- Flutter
- Flutter (1.0.0)
- image_picker_ios (0.0.1):
@ -36,7 +36,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"
SPEC CHECKSUMS:
app_links: e70ca16b4b0f88253b3b3660200d4a10b4ea9795
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
@ -45,4 +45,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796
COCOAPODS: 1.15.2
COCOAPODS: 1.16.2

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:Emma_home/screens/home.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'screens/MainScreen.dart';
import 'utils/data.dart';
import 'package:provider/provider.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
@ -19,8 +18,8 @@ Future<void> main() async {
throw Exception('Error loading .env file: $e'); // Print error if any
}
await Supabase.initialize(
url: dotenv.env['NEXT_PUBLIC_SUPABASE_URL'] ?? 'default_url',
anonKey: dotenv.env['NEXT_PUBLIC_SUPABASE_ANON_KEY'] ?? 'default_key',
url: dotenv.env['NEXT_PRODUCTIVE_SUPABASE_URL'] ?? 'default_url',
anonKey: dotenv.env['NEXT_PRODUCTIVE_SUPABASE_ANON_KEY'] ?? 'default_key',
);
await autoLogin();
var singleCategories = Categories.instance;
@ -44,11 +43,7 @@ Future<void> autoLogin() async {
email: dotenv.env['NEXT_PRIVATE_SUPABASE_APPUSER'] ?? 'default_url',
password: dotenv.env['NEXT_PRIVATE_SUPABASE_APPPWD'] ?? 'default_url',
);
if (error != null) {
print('Login fehlgeschlagen: ${error!}');
} else {
print('AppUser erfolgreich eingeloggt');
}
print('Login fehlgeschlagen: $error');
}
class MyApp extends StatelessWidget {
@ -70,7 +65,7 @@ class MyApp extends StatelessWidget {
secondary: const Color(0xff8DB646), // Your accent color
),
),
home: HomePage(),
home: const HomePage(),
//home: MainScreen(),
);
}

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'subheader_Datepicker.dart';
class MainScreen extends StatefulWidget {
const MainScreen({super.key});
@ -9,7 +8,7 @@ class MainScreen extends StatefulWidget {
}
class _MainScreenState extends State<MainScreen> with SingleTickerProviderStateMixin {
Widget _currentBody = HomeBody();
Widget _currentBody = const HomeBody();
void _changeBody(Widget newBody) {
setState(() {
@ -105,11 +104,11 @@ const SizedBox(
children: <Widget>[
IconButton(
icon: const Icon(Icons.home),
onPressed: () => _changeBody(HomeBody()),
onPressed: () => _changeBody(const HomeBody()),
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () => _changeBody(SettingsBody()),
onPressed: () => _changeBody(const SettingsBody()),
),
// Add more buttons as needed
],

View File

@ -1,231 +0,0 @@
import 'package:Emma_home/utils/class.dart';
import 'package:flutter/material.dart';
import 'package:Emma_home/screens/subheader_Datepicker.dart';
//import 'package:learn_project/main.dart';
import 'package:intl/intl.dart';
import 'package:Emma_home/utils/data.dart';
//import 'package:supabase_flutter/supabase_flutter.dart';
class Event_Card_small extends StatelessWidget {
//final List<Map<String, dynamic>> events;
final List<Map<String, dynamic>> event_grouped;
final Color color;
final MediaQueryData screen_size;
final Category category;
const Event_Card_small(
{super.key,
required this.event_grouped,
required this.color,
required this.screen_size,
required this.category});
void toggleExpanded() {}
/* void initState() {
super.initState();
_loadData();
} */
/* */
@override
Widget build(BuildContext context) {
var appBar = AppBar(
leading: SizedBox(
height: 60,
width: 63,
child: IconButton(
icon: Image.asset('assets/images/logo.png'),
onPressed: () {
// Open drawer or perform action
},
),
),
title: Row(
children: [
const SizedBox(
height: 10, //height of button
width: 20, //width of button
child: Icon(Icons.keyboard_arrow_down),
),
const SizedBox(
//width of button
width: 10,
),
SizedBox(
width: 100.0,
child: TextField(
controller: TextEditingController(text: "Ingolstadt"),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
),
),
),
],
),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// Perform search action
},
),
const SizedBox(
height: 40,
child: VerticalDivider(
thickness: 1,
width: 20,
color: Colors.black,
),
),
SizedBox(
height: 50, //height of button
//width of button
child: IconButton(
icon: Image.asset('assets/images/Login.png'),
onPressed: () {},
),
),
],
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1.0),
child: Container(
color: Colors.black,
height: 1.0,
),
),
flexibleSpace: Container(),
);
//_loadData();
var body = CustomScrollView(slivers: [
SliverSafeArea(
//minimum: EdgeInsets.zero,
bottom: false,
sliver: SliverToBoxAdapter(
child: Container(
alignment: Alignment.center,
child: Column(children: <Widget>[
Container(height: 10),
Container(
height: 35,
padding: const EdgeInsets.all(0),
child: TimeButtonSection(
onToggle: toggleExpanded), // Dein Button-Bereich
),
Container(
height: 10,
),
SizedBox(
height: 35,
child:
MusikHeader(name: category.title, icon: category.iconUrl),
),
//Container(),
])),
),
),
// Gruppierte Events mit SliverMainAxisGroup
...event_grouped.map((group) {
final String startDate = group['start_date'];
final List<Map<String, dynamic>> events = group['events'];
return SliverMainAxisGroup(
slivers: [
// Gruppierungs-Header
SliverToBoxAdapter(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TODO: muss noch angepasst werden jedes mal wenn ein neuer Tag ist wieder diesen Text anzeigen
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(
left: 20.0), // Abstand von 16 Pixeln zum linken Rand
child: Text(
DateFormat('dd.MM.yyyy').format(DateTime.parse(startDate))
as String,
style: const TextStyle(
color: Color(0xFF171717),
fontSize: 12,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
height: 0,
),
),
),
//Kurze Zwischenbereich zum trennen
const SizedBox(height: 4),
],
),
),
// Liste der Events
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final event = events[index];
return EventCard2Section(
title: event['name'],
description: event['description'],
location: event['location_name'] ?? '',
start_time: extractTime24h(event['start']),
color: event['main_category_id'] != null
? extractColor(event['main_category_id'])
: color,
//extractColor(events[index]['main_category_id']),
// oder ein beliebiger Standardwert
screen_size: screen_size,
);
},
childCount: events.length,
),
),
],
);
}).toList(),
SliverToBoxAdapter(
child: Column(children: [
LostEvents(),
Container(height: 20),
Footer(),
]),
),
]);
return Scaffold(
backgroundColor: Colors.white,
appBar: appBar,
body: body,
);
}
}
String extractTime24h(String timestamp) {
try {
DateTime dateTime = DateTime.parse(timestamp);
String hours = dateTime.hour.toString().padLeft(2, '0');
String minutes = dateTime.minute.toString().padLeft(2, '0');
return '$hours:$minutes';
} catch (e) {
print('Error parsing timestamp: $e');
return '--:--'; // or some other error indicator
}
}
//TODO: Color muss anhand der Categorie entschieden werden
// Also herauslesen welche Category das Event hat
// Dann den richtigen Eintrag in Data identifizieren udn die Farbe auswählen
Color extractColor(String categoryID) {
var singleCategories = Categories.instance;
final result = singleCategories.categories
.where((recipe) => recipe.category == categoryID)
.firstOrNull;
Color categorieColor = const Color.fromARGB(255, 255, 255, 255);
if (result != null) {
categorieColor = result.color;
}
return categorieColor;
}

254
lib/screens/event_list.dart Normal file
View File

@ -0,0 +1,254 @@
import 'package:Emma_home/utils/class.dart';
import 'package:flutter/material.dart';
import 'package:Emma_home/screens/subheader_Datepicker.dart';
//import 'package:learn_project/main.dart';
import 'package:intl/intl.dart';
import 'package:Emma_home/utils/data.dart';
import 'package:Emma_home/utils/helper_functions.dart';
//import 'package:supabase_flutter/supabase_flutter.dart';
class Event_Card_small extends StatefulWidget {
@override
_Event_Card_small createState() => _Event_Card_small();
final List<Map<String, dynamic>> event_grouped;
final Color color;
final MediaQueryData screen_size;
final Category category;
const Event_Card_small(
{super.key,
required this.event_grouped,
required this.color,
required this.screen_size,
required this.category});
}
class _Event_Card_small extends State<Event_Card_small> {
//final List<Map<String, dynamic>> events;
void toggleExpanded() {}
/* void initState() {
super.initState();
_loadData();
} */
late List<Map<String, dynamic>> _event_grouped;
@override
void initState() {
super.initState();
_event_grouped =
widget.event_grouped; // Initialisiere die Variable mit dem Parameter
}
/* */
Future<void> _refresh() async {
//void replaceList(List<String> newList) {
List<Map<String, dynamic>> temp =
await fetchGroupedEvents(widget.category.category);
setState(() {
//_event_grouped.clear();
_event_grouped = temp;
//_event_grouped = await fetchGroupedEvents(widget.category.category);
});
}
//setState(() {
// Aktualisiere die Liste (Beispiel: Einfügen neuer Daten)
//_fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt');
//});
@override
Widget build(BuildContext context) {
var appBar = AppBar(
leading: SizedBox(
height: 60,
width: 63,
child: IconButton(
icon: Image.asset('assets/images/logo.png'),
onPressed: () {
// Open drawer or perform action
},
),
),
title: Row(
children: [
const SizedBox(
height: 10, //height of button
width: 20, //width of button
child: Icon(Icons.keyboard_arrow_down),
),
const SizedBox(
//width of button
width: 10,
),
SizedBox(
width: 100.0,
child: TextField(
controller: TextEditingController(text: "Ingolstadt"),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
),
),
),
],
),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// Perform search action
},
),
const SizedBox(
height: 40,
child: VerticalDivider(
thickness: 1,
width: 20,
color: Colors.black,
),
),
SizedBox(
height: 50, //height of button
//width of button
child: IconButton(
icon: Image.asset('assets/images/Login.png'),
onPressed: () {},
),
),
],
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1.0),
child: Container(
color: Colors.black,
height: 1.0,
),
),
flexibleSpace: Container(),
);
//_loadData();
var body = RefreshIndicator(
onRefresh: _refresh,
child: CustomScrollView(slivers: [
SliverSafeArea(
//minimum: EdgeInsets.zero,
bottom: false,
sliver: SliverToBoxAdapter(
child: Container(
alignment: Alignment.center,
child: Column(children: <Widget>[
Container(height: 10),
Container(
height: 35,
padding: const EdgeInsets.all(0),
child: TimeButtonSection(
onToggle: toggleExpanded), // Dein Button-Bereich
),
Container(
height: 10,
),
SizedBox(
height: 35,
child: Cat_Sub_Header(
name: widget.category.title,
icon: widget.category.iconUrl),
),
//Container(),
])),
),
),
// Gruppierte Events mit SliverMainAxisGroup
..._event_grouped.map((group) {
print('Gruppe: ${group['start_date']}, Events: ${group['events']}');
final String startDate = group['start_date'];
final List<Map<String, dynamic>> events = group['events'];
return SliverMainAxisGroup(
slivers: [
// Gruppierungs-Header
SliverToBoxAdapter(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// TODO: muss noch angepasst werden jedes mal wenn ein neuer Tag ist wieder diesen Text anzeigen
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(
left:
20.0), // Abstand von 16 Pixeln zum linken Rand
child: Text(
DateFormat('dd.MM.yyyy')
.format(DateTime.parse(startDate)),
style: const TextStyle(
color: Color(0xFF171717),
fontSize: 12,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
height: 0,
),
),
),
//Kurze Zwischenbereich zum trennen
const SizedBox(height: 4),
],
),
),
// Liste der Events
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final event = events[index];
return EventCard2Section(
title: event['name'],
description: event['description'],
location: event['location_name'] ?? '',
start_time: extractTime24h(event['start']),
color: event['main_category_id'] != null
? extractColor(event['main_category_id'])
: widget.color,
//extractColor(events[index]['main_category_id']),
// oder ein beliebiger Standardwert
screen_size: widget.screen_size,
);
},
childCount: events.length,
),
),
],
);
}),
SliverToBoxAdapter(
child: Column(children: [
const LostEvents(),
Container(height: 20),
const Footer(),
]),
),
]));
return Scaffold(
backgroundColor: Colors.white,
appBar: appBar,
body: body,
);
}
}
//fetchGroupedEvents
/* Future<List<Map<String, dynamic>>> fetchGroupedEvents(String category) async {
try {
final response = await supabase.rpc('get_events_grouped_by_date_today',
params: {'cat_id': category});
// Cast auf die gewünschte Struktur
return (response as List)
.map((entry) => {
'start_date': entry['start_date'], // Das Gruppierungsdatum
'events': (entry['events'] as List)
.cast<Map<String, dynamic>>() // Event-Details
})
.toList();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
*/

View File

@ -1,13 +1,10 @@
import 'package:flutter/material.dart';
import 'package:Emma_home/screens/details_db.dart';
import 'package:Emma_home/utils/data.dart';
import 'package:Emma_home/screens/subheader_Datepicker.dart';
import 'package:Emma_home/screens/detail_widget.dart';
import 'package:Emma_home/screens/event_list.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:Emma_home/main.dart';
import 'package:Emma_home/utils/data.dart';
import 'dart:math';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@ -16,119 +13,60 @@ class HomePage extends StatefulWidget {
_HomePage createState() => _HomePage();
}
class _HomePage extends State<HomePage> {
class _HomePage extends State<HomePage> with RouteAware {
late RouteObserver<PageRoute> routeObserver;
late Future<void> _fetchDataFuture;
bool isScrollable = false;
bool _isFirstLoad = true;
void toggleExpanded() {
setState(() {
isScrollable = !isScrollable;
});
}
// TODO: Ok nun ist es etwas optimiert. Fühlt sich aber sehr gefaked an.
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver = RouteObserver<PageRoute>();
routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
if (_isFirstLoad) {
_isFirstLoad = false;
return;
}
_updateData();
_isFirstLoad = true;
}
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
@override
void initState() {
super.initState();
_updateData();
}
_updateData() {
_fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt');
}
Future<List<Map<String, dynamic>>> _loadData() async {
final data = await supabase.from('events').select();
//get the id of the event
return data;
//Create a date entry and connect it with the event
// Überprüfe, ob der Insert erfolgreich war
}
//fetchGroupedEvents
Future<List<Map<String, dynamic>>> fetchGroupedEvents(String category) async {
try {
final response = await supabase
.rpc('get_events_grouped_by_date', params: {'cat_id': category});
// Cast auf die gewünschte Struktur
return (response as List)
.map((entry) => {
'start_date': entry['start_date'], // Das Gruppierungsdatum
'events': (entry['events'] as List)
.cast<Map<String, dynamic>>() // Event-Details
})
.toList();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
Future<List<Map<String, dynamic>>> fetchEvents(String category) async {
try {
//final today = DateTime.now().toUtc().toString().split(' ')[0];
final response = await supabase
.from("events")
//.innerJoin('event_category', 'events.id = event_category.event_id')
.select(
'id,name,description,detail,subheader,main_category_id,location(name),time!inner(*),event_category!inner(event_id)')
.eq('event_category.category_id', category);
//.gte('time.start_date', DateTime.now().toIso8601String().split('T')[0]) // Beginn des heutigen Tages
//.lt('time.start_date', DateTime.now().add(Duration(days: 1)).toIso8601String().split('T')[0]); // Morgen;
//select('id, name, cities(id, name)')
//find all events mit Ort und zusatzinfos die die Kathegorie haben welche ausgewählt wurde am heutigen Tag dann kommender Tag usw.
//final test = response[0]['time'][0]['start_date'];
return (response as List).cast<Map<String, dynamic>>();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
Future<List<Map<String, dynamic>>> fetchEventsToday(String category) async {
try {
final today = DateTime.now().toUtc().toString().split(' ')[0];
final response = await supabase
.from("events")
//.innerJoin('event_category', 'events.id = event_category.event_id')
.select(
'id,name,description,detail,subheader,main_category_id,location(name),time!inner(*),event_category!inner(event_id)')
.eq('event_category.category_id', category) //;
.eq('time.start_date', today);
//.gte('time.start_date', DateTime.now().toIso8601String().split('T')[0]) // Beginn des heutigen Tages
//.lt('time.start_date', DateTime.now().add(Duration(days: 1)).toIso8601String().split('T')[0]); // Morgen;
//select('id, name, cities(id, name)')
//find all events mit Ort und zusatzinfos die die Kathegorie haben welche ausgewählt wurde am heutigen Tag dann kommender Tag usw.
//final test = response[0]['time'][0]['start_date'];
return (response as List).cast<Map<String, dynamic>>();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
Future<List<Map<String, dynamic>>> fetchEventsTomorrow(
String category) async {
try {
final today = DateTime.now().toUtc().toString().split(' ')[0];
final response = await supabase
.from("events")
//.innerJoin('event_category', 'events.id = event_category.event_id')
.select(
'id,name,description,detail,subheader,location(name),time!inner(*),event_category!inner(event_id)')
.eq('event_category.category_id', category) //;
.eq('time.start_date', today);
//.gte('time.start_date', DateTime.now().toIso8601String().split('T')[0]) // Beginn des heutigen Tages
//.lt('time.start_date', DateTime.now().add(Duration(days: 1)).toIso8601String().split('T')[0]); // Morgen;
//select('id, name, cities(id, name)')
//find all events mit Ort und zusatzinfos die die Kathegorie haben welche ausgewählt wurde am heutigen Tag dann kommender Tag usw.
//final test = response[0]['time'][0]['start_date'];
return (response as List).cast<Map<String, dynamic>>();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
Future<void> _refresh() async {
setState(() {
// Aktualisiere die Liste (Beispiel: Einfügen neuer Daten)
_fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt');
});
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
/*24 is for notification bar on Android*/
// ScrollController und Status-Variable
ScrollController _scrollController = ScrollController();
ScrollController scrollController = ScrollController();
// Verfügbarer Bereich auf dem Bildschirm
final screenWidth = MediaQuery.of(context).size.width;
@ -225,171 +163,171 @@ class _HomePage extends State<HomePage> {
),
flexibleSpace: Container(),
);
var body = SafeArea(child:
Consumer<Categories>(builder: (context, singleCategories, child) {
return SingleChildScrollView(
physics: isScrollable
? AlwaysScrollableScrollPhysics()
: NeverScrollableScrollPhysics(),
child: Column(
children: <Widget>[
//Header Container
//HeaderSection(),
Container(height: 14),
Container(
height: 35,
padding: const EdgeInsets.all(0),
child: TimeButtonSection(
onToggle: toggleExpanded), // Dein Button-Bereich
),
GridView.builder(
controller: _scrollController,
physics: NeverScrollableScrollPhysics(),
shrinkWrap:
true, // Damit der GridView korrekt in die Column passt
//physics: NeverScrollableScrollPhysics(), // Deaktiviert das Scrolling des GridView
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // Anzahl der Spalten im Grid
//crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: (itemWidth / itemHeight),
),
itemCount: singleCategories
.categories.length, // Anzahl der Elemente im Grid
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(6.0),
child: InkWell(
onTap: () async {
/* List<Map<String, dynamic>> events =
await _loadData();
List<Map<String, dynamic>> events2 = await fetchEvents(
singleCategories.categories[index].category);*/
final events = await fetchGroupedEvents(
singleCategories.categories[index].category);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Event_Card_small(
event_grouped: events,
color: singleCategories
.categories[index].color,
screen_size: queryData,
category:
singleCategories.categories[index],
)));
},
child: SizedBox(
width: itemWidth,
height: itemHeight.toDouble(),
child: Stack(
children: [
Positioned(
left: 0,
top: 0,
child: Container(
width: itemWidth,
height: itemHeight.toDouble(),
decoration: ShapeDecoration(
image: DecorationImage(
image: AssetImage(singleCategories
.categories[index].imageUrl),
fit: BoxFit.cover,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
shadows: [
BoxShadow(
color: singleCategories
.categories[index].color,
blurRadius: 0,
offset: const Offset(0, 10),
spreadRadius: 0,
)
],
),
),
),
Positioned(
left: 16,
top: 15,
child: Text(
singleCategories.categories[index].amount
.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w500,
height: 0,
),
),
),
Positioned(
left: 13,
top: singleCategories.categories[index]
.textheight, //86, //TODO Bootom?
child: SizedBox(
width: itemWidth -
20, // Set a fixed width or use constraints
child: Wrap(
children: [
Text(
singleCategories.categories[index].title,
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontFamily: 'Inter',
fontWeight: FontWeight.w800,
height: 0,
),
),
],
),
),
),
Positioned(
right: 20,
top: 10,
child: SizedBox(
width: 32,
height: 32,
child: Image.asset(
singleCategories.categories[index].iconUrl,
),
),
),
Positioned(
left: 127,
top: 9,
child: Container(
width: 31,
height: 31,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(),
),
),
],
),
),
var body = RefreshIndicator(
onRefresh: _refresh,
child: SafeArea(child:
Consumer<Categories>(builder: (context, singleCategories, child) {
return SingleChildScrollView(
physics: isScrollable
? const AlwaysScrollableScrollPhysics()
: const NeverScrollableScrollPhysics(),
child: Column(
children: <Widget>[
//Header Container
//HeaderSection(),
Container(height: 14),
Container(
height: 35,
padding: const EdgeInsets.all(0),
child: TimeButtonSection(
onToggle: toggleExpanded), // Dein Button-Bereich
),
GridView.builder(
controller: scrollController,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap:
true, // Damit der GridView korrekt in die Column passt
//physics: NeverScrollableScrollPhysics(), // Deaktiviert das Scrolling des GridView
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // Anzahl der Spalten im Grid
//crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: (itemWidth / itemHeight),
),
);
},
itemCount: singleCategories
.categories.length, // Anzahl der Elemente im Grid
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(6.0),
child: InkWell(
onTap: () async {
final events = await fetchGroupedEvents(
singleCategories.categories[index].category);
_isFirstLoad = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Event_Card_small(
event_grouped: events,
color: singleCategories
.categories[index].color,
screen_size: queryData,
category:
singleCategories.categories[index],
)));
},
child: SizedBox(
width: itemWidth,
height: itemHeight.toDouble(),
child: Stack(
children: [
Positioned(
left: 0,
top: 0,
child: Container(
width: itemWidth,
height: itemHeight.toDouble(),
decoration: ShapeDecoration(
image: DecorationImage(
image: AssetImage(singleCategories
.categories[index].imageUrl),
fit: BoxFit.cover,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
shadows: [
BoxShadow(
color: singleCategories
.categories[index].color,
blurRadius: 0,
offset: const Offset(0, 10),
spreadRadius: 0,
)
],
),
),
),
Positioned(
left: 16,
top: 15,
child: Text(
singleCategories.categories[index].amount
.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w500,
height: 0,
),
),
),
Positioned(
left: 13,
top: singleCategories.categories[index]
.textheight, //86, //TODO Bootom?
child: SizedBox(
width: itemWidth -
20, // Set a fixed width or use constraints
child: Wrap(
children: [
Text(
singleCategories
.categories[index].title,
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontFamily: 'Inter',
fontWeight: FontWeight.w800,
height: 0,
),
),
],
),
),
),
Positioned(
right: 20,
top: 10,
child: SizedBox(
width: 32,
height: 32,
child: SvgPicture.asset(
singleCategories.categories[index].iconUrl,
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.srcIn),
),
/* Image.asset(
singleCategories.categories[index].iconUrl,
), */
),
),
Positioned(
left: 127,
top: 9,
child: Container(
width: 31,
height: 31,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(),
),
),
],
),
),
),
);
},
),
//Body Container
Container(
height: 20,
),
const Footer(),
],
),
//Body Container
Container(
height: 20,
),
Footer(),
/* Image.asset(
'assets/images/FooterFooter.png', // Pfad zum Bild
//height: 120, // Höhe des Bildes
width: 390, // Breite des Bildes
), */
],
),
);
}));
);
})));
return Scaffold(
backgroundColor: Colors.white,
@ -400,7 +338,7 @@ class _HomePage extends State<HomePage> {
);
@override
void dispose() {
_scrollController.dispose();
scrollController.dispose();
super.dispose();
}
}

344
lib/screens/home_old.dart Normal file
View File

@ -0,0 +1,344 @@
import 'package:flutter/material.dart';
import 'package:Emma_home/utils/data.dart';
import 'package:Emma_home/screens/subheader_Datepicker.dart';
import 'package:Emma_home/screens/event_list.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePage createState() => _HomePage();
}
class _HomePage extends State<HomePage> with RouteAware {
late RouteObserver<PageRoute> routeObserver;
late Future<void> _fetchDataFuture;
bool isScrollable = false;
bool _isFirstLoad = true;
void toggleExpanded() {
setState(() {
isScrollable = !isScrollable;
});
}
// TODO: Ok nun ist es etwas optimiert. Fühlt sich aber sehr gefaked an.
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver = RouteObserver<PageRoute>();
routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
if (_isFirstLoad) {
_isFirstLoad = false;
return;
}
_updateData();
_isFirstLoad = true;
}
@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}
@override
void initState() {
super.initState();
_updateData();
}
_updateData() {
_fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt');
}
Future<void> _refresh() async {
setState(() {
// Aktualisiere die Liste (Beispiel: Einfügen neuer Daten)
_fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt');
});
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
/*24 is for notification bar on Android*/
// ScrollController und Status-Variable
ScrollController scrollController = ScrollController();
// Verfügbarer Bereich auf dem Bildschirm
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
double statusBarHeight = MediaQuery.of(context).padding.top;
double HeaderHeight = 60;
double TimeButtonHeight = 35;
double TimeButtonpadding = 20;
double FooterHeight = 91;
double bottomPadding = MediaQuery.of(context).padding.bottom;
final staticContentheight = statusBarHeight +
HeaderHeight +
TimeButtonHeight +
TimeButtonpadding +
FooterHeight +
bottomPadding;
double amaountOfCategoryLines = 4; //singleCategories.categories.length/2;
double paddingHeight = 10;
double shaddowHeight = 10;
final dynamicContentHeight =
((amaountOfCategoryLines + 1) * paddingHeight) +
(amaountOfCategoryLines * shaddowHeight);
final resultHeightRemove = staticContentheight + dynamicContentHeight;
final int itemHeight =
((screenHeight - resultHeightRemove) / 4).toInt(); //240-90) / 4;
final double itemWidth = (size.width - 40) / 2;
MediaQueryData queryData;
queryData = MediaQuery.of(context);
var appBar = AppBar(
leading: SizedBox(
height: 60,
width: 63,
child: IconButton(
icon: Image.asset('assets/images/logo.png'),
onPressed: () {
// Open drawer or perform action
},
),
),
title: Row(
children: [
const SizedBox(
height: 10, //height of button
width: 20, //width of button
child: Icon(Icons.keyboard_arrow_down),
),
const SizedBox(
//width of button
width: 10,
),
SizedBox(
width: 100.0,
child: TextField(
controller: TextEditingController(text: "Ingolstadt"),
decoration: const InputDecoration(
border: UnderlineInputBorder(),
),
),
),
],
),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// Perform search action
},
),
const SizedBox(
height: 40,
child: VerticalDivider(
thickness: 1,
width: 20,
color: Colors.black,
),
),
SizedBox(
height: 50, //height of button
//width of button
child: IconButton(
icon: Image.asset('assets/images/Login.png'),
onPressed: () {},
),
),
],
bottom: PreferredSize(
preferredSize: const Size.fromHeight(1.0),
child: Container(
color: Colors.black,
height: 1.0,
),
),
flexibleSpace: Container(),
);
var body = RefreshIndicator(
onRefresh: _refresh,
child: SafeArea(child:
Consumer<Categories>(builder: (context, singleCategories, child) {
return SingleChildScrollView(
physics: isScrollable
? const AlwaysScrollableScrollPhysics()
: const NeverScrollableScrollPhysics(),
child: Column(
children: <Widget>[
//Header Container
//HeaderSection(),
Container(height: 14),
Container(
height: 35,
padding: const EdgeInsets.all(0),
child: TimeButtonSection(
onToggle: toggleExpanded), // Dein Button-Bereich
),
GridView.builder(
controller: scrollController,
physics: const NeverScrollableScrollPhysics(),
shrinkWrap:
true, // Damit der GridView korrekt in die Column passt
//physics: NeverScrollableScrollPhysics(), // Deaktiviert das Scrolling des GridView
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // Anzahl der Spalten im Grid
//crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
childAspectRatio: (itemWidth / itemHeight),
),
itemCount: singleCategories
.categories.length, // Anzahl der Elemente im Grid
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(6.0),
child: InkWell(
onTap: () async {
final events = await fetchGroupedEvents(
singleCategories.categories[index].category);
_isFirstLoad = true;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Event_Card_small(
event_grouped: events,
color: singleCategories
.categories[index].color,
screen_size: queryData,
category:
singleCategories.categories[index],
)));
},
child: SizedBox(
width: itemWidth,
height: itemHeight.toDouble(),
child: Stack(
children: [
Positioned(
left: 0,
top: 0,
child: Container(
width: itemWidth,
height: itemHeight.toDouble(),
decoration: ShapeDecoration(
image: DecorationImage(
image: AssetImage(singleCategories
.categories[index].imageUrl),
fit: BoxFit.cover,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
shadows: [
BoxShadow(
color: singleCategories
.categories[index].color,
blurRadius: 0,
offset: const Offset(0, 10),
spreadRadius: 0,
)
],
),
),
),
Positioned(
left: 16,
top: 15,
child: Text(
singleCategories.categories[index].amount
.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w500,
height: 0,
),
),
),
Positioned(
left: 13,
top: singleCategories.categories[index]
.textheight, //86, //TODO Bootom?
child: SizedBox(
width: itemWidth -
20, // Set a fixed width or use constraints
child: Wrap(
children: [
Text(
singleCategories
.categories[index].title,
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontFamily: 'Inter',
fontWeight: FontWeight.w800,
height: 0,
),
),
],
),
),
),
Positioned(
right: 20,
top: 10,
child: SizedBox(
width: 32,
height: 32,
child: SvgPicture.asset(
singleCategories.categories[index].iconUrl,
colorFilter: const ColorFilter.mode(
Colors.white, BlendMode.srcIn),
),
/* Image.asset(
singleCategories.categories[index].iconUrl,
), */
),
),
Positioned(
left: 127,
top: 9,
child: Container(
width: 31,
height: 31,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(),
),
),
],
),
),
),
);
},
),
//Body Container
Container(
height: 20,
),
const Footer(),
],
),
);
})));
return Scaffold(
backgroundColor: Colors.white,
appBar: appBar,
body: Consumer<Categories>(builder: (context, singleCategories, child) {
return body;
}),
);
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
}
}

View File

@ -1,20 +1,14 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:Emma_home/screens/details_db.dart';
import 'package:Emma_home/utils/data.dart';
import 'package:Emma_home/screens/subheader_Datepicker.dart';
import 'package:Emma_home/screens/detail_widget.dart';
import 'package:provider/provider.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:Emma_home/main.dart';
import 'package:Emma_home/utils/data.dart';
import 'dart:math';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class MissingEvent extends StatefulWidget {
const MissingEvent({super.key});
@override
_MissingEvent createState() => _MissingEvent();
}
@ -28,7 +22,7 @@ class _MissingEvent extends State<MissingEvent> {
/*24 is for notification bar on Android*/
// ScrollController und Status-Variable
ScrollController _scrollController = ScrollController();
ScrollController scrollController = ScrollController();
// Verfügbarer Bereich auf dem Bildschirm
final screenWidth = MediaQuery.of(context).size.width;
@ -60,10 +54,10 @@ class _MissingEvent extends State<MissingEvent> {
queryData = MediaQuery.of(context);
late File imageFile = File("");
bool isloaded = false;
final ImagePicker _picker = ImagePicker();
final ImagePicker picker = ImagePicker();
Future<void> pickImage() async {
final XFile? image = await _picker.pickImage(
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
// Add any desired options, such as image quality
//imageQuality: 100,
@ -113,7 +107,7 @@ class _MissingEvent extends State<MissingEvent> {
}
Future<void> captureImage() async {
final XFile? image = await _picker.pickImage(
final XFile? image = await picker.pickImage(
source: ImageSource.camera,
//imageQuality: 100,
);
@ -216,14 +210,14 @@ class _MissingEvent extends State<MissingEvent> {
);
var body = Stack(children: [
Container(
padding: EdgeInsets.all(22.0),
padding: const EdgeInsets.all(22.0),
width: double.infinity,
//height: 952,
//clipBehavior: Clip.antiAlias,
child: Column(
children: [
const SizedBox(height: 10),
Align(
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Fehlendes Event bei uns?',
@ -243,7 +237,7 @@ class _MissingEvent extends State<MissingEvent> {
width: double.infinity,
height: 144,
child: RichText(
text: TextSpan(
text: const TextSpan(
text:
'Du hast unterwegs ein Event gesehen, welches noch nicht bei uns in der Liste steht? Schicke uns das Foto von dem Event zu. Wir werden diese, wenn nicht schon geschehen den Events hinzufügen. Danke für deine Unterstützung!',
style: TextStyle(
@ -263,9 +257,9 @@ class _MissingEvent extends State<MissingEvent> {
height: 200,
padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 85),
decoration: ShapeDecoration(
color: Color(0xFFEDEDED),
color: const Color(0xFFEDEDED),
shape: RoundedRectangleBorder(
side: BorderSide(
side: const BorderSide(
width: 1,
strokeAlign: BorderSide.strokeAlignOutside,
),
@ -315,7 +309,7 @@ class _MissingEvent extends State<MissingEvent> {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
child: Text(
child: const Text(
'Bild aufnehmen',
style: TextStyle(
color: Colors.black,
@ -326,7 +320,7 @@ class _MissingEvent extends State<MissingEvent> {
),
),
),
SizedBox(
const SizedBox(
width: 10,
),
Container(
@ -337,7 +331,7 @@ class _MissingEvent extends State<MissingEvent> {
clipBehavior: Clip.antiAlias,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
side: BorderSide(width: 2),
side: const BorderSide(width: 2),
borderRadius: BorderRadius.circular(10),
),
),
@ -346,11 +340,11 @@ class _MissingEvent extends State<MissingEvent> {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
SizedBox(
width: 23,
height: 20.70,
child: IconButton(
icon: FaIcon(FontAwesomeIcons.camera, size: 20),
icon: const FaIcon(FontAwesomeIcons.camera, size: 20),
onPressed: () {
// Füge hier die YouTube-Aktion hinzu
captureImage();
@ -358,7 +352,7 @@ class _MissingEvent extends State<MissingEvent> {
padding: EdgeInsets
.zero, // Entfernt das Padding des IconButton
constraints:
BoxConstraints(), // Entfernt die Standardbeschränkungen
const BoxConstraints(), // Entfernt die Standardbeschränkungen
),
),
],
@ -367,7 +361,7 @@ class _MissingEvent extends State<MissingEvent> {
],
),
const SizedBox(height: 10),
Row(
const Row(
children: [
/* Container(
width: 160,
@ -479,20 +473,20 @@ class _MissingEvent extends State<MissingEvent> {
// AnimatedOpacity für das Overlay
AnimatedOpacity(
opacity: isUploading ? 1.0 : 0.0, // Sichtbarkeit steuern
duration: Duration(milliseconds: 300), // Dauer der Animation
duration: const Duration(milliseconds: 300), // Dauer der Animation
curve: Curves.easeInOut, // Animationskurve
child: isUploading
? Container(
width: MediaQuery.of(context).size.width, // Volle Breite
height: MediaQuery.of(context).size.height, // Volle Höhe
color: Colors.black.withOpacity(0.5), // Halbtransparentes Grau
child: Center(
child: const Center(
child: CircularProgressIndicator(
color: Colors.white,
),
),
)
: SizedBox.shrink(), // Nichts anzeigen, wenn nicht sichtbar
: const SizedBox.shrink(), // Nichts anzeigen, wenn nicht sichtbar
),
]);

View File

@ -3,11 +3,12 @@ import 'dart:math';
import 'package:Emma_home/utils/clipper.dart';
import 'package:flutter/material.dart';
import 'package:Emma_home/utils/helper_functions.dart';
import 'package:flutter_svg/svg.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:Emma_home/screens/missing_event.dart';
class TimeButtonSection extends StatefulWidget {
const TimeButtonSection({required this.onToggle, Key? key}) : super(key: key);
const TimeButtonSection({required this.onToggle, super.key});
final VoidCallback onToggle;
@override
@ -44,7 +45,7 @@ class _TimeButtonSection extends State<TimeButtonSection> {
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text('Heute'),
child: const Text('Heute'),
),
// Button "Morgen" (outlined style)
OutlinedButton(
@ -66,7 +67,7 @@ class _TimeButtonSection extends State<TimeButtonSection> {
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text('Morgen'),
child: const Text('Morgen'),
),
// Button "Wochenende" (outlined style)
OutlinedButton(
@ -88,7 +89,7 @@ class _TimeButtonSection extends State<TimeButtonSection> {
borderRadius: BorderRadius.circular(10.0),
),
),
child: Text('Wochenende'),
child: const Text('Wochenende'),
),
// Button with calendar icon
IconButton(
@ -220,6 +221,20 @@ class EventCard2Section extends StatelessWidget {
'assets/images/Event_Images/image03.jpg',
'assets/images/Event_Images/image04.jpg',
'assets/images/Event_Images/image05.jpg',
'assets/images/Event_Images/image06.jpg',
'assets/images/Event_Images/image07.jpg',
'assets/images/Event_Images/image08.jpg',
'assets/images/Event_Images/image09.jpg',
//'assets/images/Event_Images/image10.jpg',
//'assets/images/Event_Images/image11.jpg',
'assets/images/Event_Images/image12.jpg',
//'assets/images/Event_Images/image13.jpg',
'assets/images/Event_Images/image14.jpg',
'assets/images/Event_Images/image15.jpg',
'assets/images/Event_Images/image16.jpg',
'assets/images/Event_Images/image17.jpg',
//'assets/images/Event_Images/image18.jpg',
'assets/images/Event_Images/image19.jpg',
];
final randomIndex = Random().nextInt(images.length);
return images[randomIndex];
@ -269,7 +284,14 @@ class EventCard2Section extends StatelessWidget {
Positioned(
right: 0,
top: 0,
child: ClipPath(
child: /* Image.asset(
getRandomImage(), // Pfad zum Bild
height: 110, // Höhe des Bildes
width: 115, // Breite des Bildes
fit: BoxFit.cover,
),
), */
ClipPath(
clipper: _getRandomClipper(),
child: Image.asset(
getRandomImage(), // Pfad zum Bild
@ -897,11 +919,11 @@ class TagSlider extends StatelessWidget {
}
}
class MusikHeader extends StatelessWidget {
class Cat_Sub_Header extends StatelessWidget {
final String name; // First variable
final String icon; // Second variable
const MusikHeader({
const Cat_Sub_Header({
super.key,
required this.name,
required this.icon,
@ -934,17 +956,24 @@ class MusikHeader extends StatelessWidget {
SizedBox(
width: 32,
height: 32,
child: Image.asset(
child: SvgPicture.asset(
icon,
/* colorFilter:
const ColorFilter.mode(Colors.black, BlendMode.srcIn), */
//color: Colors.blue,
),
/* Image.asset(
icon,
errorBuilder: (context, error, stackTrace) {
print('Error loading image: $error');
return const Icon(Icons.error);
},
),
), */
),
const SizedBox(width: 8),
Text(
name,
style: TextStyle(
style: const TextStyle(
color: Color(0xFF171717),
fontSize: 20,
fontFamily: 'Inter',
@ -1037,7 +1066,7 @@ class CardGenre extends StatelessWidget {
),
const SizedBox(height: 4),
Container(
child: Column(
child: const Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@ -1050,7 +1079,7 @@ class CardGenre extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const SizedBox(
SizedBox(
width: 83,
height: 24,
child: Text(
@ -1064,10 +1093,10 @@ class CardGenre extends StatelessWidget {
),
),
),
const SizedBox(width: 24),
SizedBox(width: 24),
SizedBox(
height: 20,
child: const Row(
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
@ -1255,7 +1284,7 @@ class CardGenre_temp extends StatelessWidget {
),
const SizedBox(height: 4),
Container(
child: Column(
child: const Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@ -1268,7 +1297,7 @@ class CardGenre_temp extends StatelessWidget {
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const SizedBox(
SizedBox(
width: 83,
height: 24,
child: Text(
@ -1282,10 +1311,10 @@ class CardGenre_temp extends StatelessWidget {
),
),
),
const SizedBox(width: 24),
SizedBox(width: 24),
SizedBox(
height: 20,
child: const Row(
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.start,
@ -1448,10 +1477,10 @@ class Event_Card extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
const SizedBox(
width: double.infinity,
height: 48,
child: const Column(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
@ -1596,6 +1625,8 @@ class Event_Card extends StatelessWidget {
}
class LostEvents extends StatelessWidget {
const LostEvents({super.key});
@override
Widget build(BuildContext context) {
return InkWell(
@ -1604,20 +1635,20 @@ class LostEvents extends StatelessWidget {
context,
MaterialPageRoute(
builder: (context) =>
MissingEvent()), // Die Seite, zu der du navigieren möchtest
const MissingEvent()), // Die Seite, zu der du navigieren möchtest
);
},
child: Container(
width: 350,
//height: 148,
padding: EdgeInsets.all(15.0),
padding: const EdgeInsets.all(15.0),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
side: BorderSide(width: 2),
side: const BorderSide(width: 2),
borderRadius: BorderRadius.circular(8),
),
shadows: [
shadows: const [
BoxShadow(
color: Color(0xFF000000),
blurRadius: 0,
@ -1626,7 +1657,7 @@ class LostEvents extends StatelessWidget {
)
],
),
child: Column(
child: const Column(
children: [
Align(
alignment: Alignment.centerLeft,
@ -1641,7 +1672,7 @@ class LostEvents extends StatelessWidget {
),
),
),
const SizedBox(height: 10),
SizedBox(height: 10),
SizedBox(
width: 317,
child: Text.rich(
@ -1682,7 +1713,7 @@ class LostEvents extends StatelessWidget {
),
),
),
const SizedBox(height: 15),
SizedBox(height: 15),
Align(
alignment: Alignment.centerRight,
child: Text(
@ -1703,6 +1734,8 @@ class LostEvents extends StatelessWidget {
}
class Footer extends StatelessWidget {
const Footer({super.key});
@override
Widget build(BuildContext context) {
return Container(
@ -1711,7 +1744,7 @@ class Footer extends StatelessWidget {
//height: 90,
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: Color(0xFFF2F2F2),
border: Border(
left: BorderSide(color: Color(0xFF868686)),
@ -1738,7 +1771,7 @@ class Footer extends StatelessWidget {
),
),
const SizedBox(width: 10),
Text(
const Text(
'© 2024 Alle Rechte vorbehalten',
style: TextStyle(
color: Colors.black,
@ -1753,56 +1786,56 @@ class Footer extends StatelessWidget {
height: 20,
width: 20,
child: IconButton(
icon: FaIcon(FontAwesomeIcons.instagram, size: 20),
icon: const FaIcon(FontAwesomeIcons.instagram, size: 20),
onPressed: () {
// Füge hier die YouTube-Aktion hinzu
},
padding:
EdgeInsets.zero, // Entfernt das Padding des IconButton
constraints:
BoxConstraints(), // Entfernt die Standardbeschränkungen
const BoxConstraints(), // Entfernt die Standardbeschränkungen
)),
const SizedBox(width: 10),
SizedBox(
height: 20,
width: 20,
child: IconButton(
icon: FaIcon(FontAwesomeIcons.tiktok, size: 20),
icon: const FaIcon(FontAwesomeIcons.tiktok, size: 20),
onPressed: () {
// Füge hier die YouTube-Aktion hinzu
},
padding:
EdgeInsets.zero, // Entfernt das Padding des IconButton
constraints:
BoxConstraints(), // Entfernt die Standardbeschränkungen
const BoxConstraints(), // Entfernt die Standardbeschränkungen
)),
const SizedBox(width: 10),
SizedBox(
height: 20,
width: 25,
child: IconButton(
icon: FaIcon(FontAwesomeIcons.youtube, size: 20),
icon: const FaIcon(FontAwesomeIcons.youtube, size: 20),
onPressed: () {
// Füge hier die YouTube-Aktion hinzu
},
padding:
EdgeInsets.zero, // Entfernt das Padding des IconButton
constraints:
BoxConstraints(), // Entfernt die Standardbeschränkungen
const BoxConstraints(), // Entfernt die Standardbeschränkungen
)),
const SizedBox(width: 10),
SizedBox(
height: 20,
width: 20,
child: IconButton(
icon: FaIcon(FontAwesomeIcons.facebook, size: 20),
icon: const FaIcon(FontAwesomeIcons.facebook, size: 20),
onPressed: () {
// Füge hier die YouTube-Aktion hinzu
},
padding:
EdgeInsets.zero, // Entfernt das Padding des IconButton
constraints:
BoxConstraints(), // Entfernt die Standardbeschränkungen
const BoxConstraints(), // Entfernt die Standardbeschränkungen
)),
const SizedBox(width: 10),
],
@ -1813,7 +1846,7 @@ class Footer extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
const Text(
' About us',
style: TextStyle(
color: Colors.black,
@ -1827,13 +1860,13 @@ class Footer extends StatelessWidget {
Container(
width: 3,
height: 3,
decoration: ShapeDecoration(
decoration: const ShapeDecoration(
color: Colors.black, // Schwarze Füllfarbe
shape: OvalBorder(side: BorderSide(width: 1)),
),
),
const SizedBox(width: 10),
Text(
const Text(
'Impressum',
style: TextStyle(
color: Colors.black,
@ -1847,13 +1880,13 @@ class Footer extends StatelessWidget {
Container(
width: 3,
height: 3,
decoration: ShapeDecoration(
decoration: const ShapeDecoration(
color: Colors.black, // Schwarze Füllfarbe
shape: OvalBorder(side: BorderSide(width: 1)),
),
),
const SizedBox(width: 10),
Text(
const Text(
'Kontakt',
style: TextStyle(
color: Colors.black,
@ -1867,13 +1900,13 @@ class Footer extends StatelessWidget {
Container(
width: 3,
height: 3,
decoration: ShapeDecoration(
decoration: const ShapeDecoration(
color: Colors.black, // Schwarze Füllfarbe
shape: OvalBorder(side: BorderSide(width: 1)),
),
),
const SizedBox(width: 10),
Text(
const Text(
'Help Service',
style: TextStyle(
color: Colors.black,
@ -1891,7 +1924,7 @@ class Footer extends StatelessWidget {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
const Text(
'Terms and conditions ',
style: TextStyle(
color: Colors.black,
@ -1905,13 +1938,13 @@ class Footer extends StatelessWidget {
Container(
width: 3,
height: 3,
decoration: ShapeDecoration(
decoration: const ShapeDecoration(
color: Colors.black, // Schwarze Füllfarbe
shape: OvalBorder(side: BorderSide(width: 1)),
),
),
const SizedBox(width: 20),
Text(
const Text(
'sponsered by: In4Event',
style: TextStyle(
color: Colors.black,

View File

@ -1,8 +1,7 @@
import 'dart:ui';
class Category {
String id, imageUrl, iconUrl,title,category;
String id, imageUrl, iconUrl, title, category;
Color color;
double? textheight;
int amount;

View File

@ -3,9 +3,8 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:Emma_home/utils/class.dart';
//import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:Emma_home/main.dart';
import 'package:intl/intl.dart' as intl;
import 'package:supabase_flutter/supabase_flutter.dart';
const Duration fakeAPIDuration = Duration(milliseconds: 50);
const Duration debounceDuration = Duration(milliseconds: 50);
@ -26,7 +25,7 @@ class Categories extends ChangeNotifier {
id: '1',
title: 'Musik',
imageUrl: 'assets/images/Musik.png',
iconUrl: 'assets/images/Icons/Icon_Musik.png',
iconUrl: 'assets/images/Icons/Icon_Musik.svg',
color: const Color.fromARGB(255, 249, 171, 21), //FD4949 //Musik
category: '34725c49-740b-45c5-8a51-7c742f92a621',
textheight: 86,
@ -36,7 +35,7 @@ class Categories extends ChangeNotifier {
id: '2',
title: 'Nachtleben',
imageUrl: 'assets/images/Nachtleben.png',
iconUrl: 'assets/images/Icons/Icon_Nachtleben.png',
iconUrl: 'assets/images/Icons/Icon_Nachtleben.svg',
color: const Color.fromARGB(255, 253, 73, 73), //FD4949 //Nachtleben
category: '2d8c714e-3290-4d8c-8a95-e3b100ad8599',
textheight: 86,
@ -46,7 +45,7 @@ class Categories extends ChangeNotifier {
id: '3',
title: 'Kunst & Kultur',
imageUrl: 'assets/images/Kultur.png',
iconUrl: 'assets/images/Icons/Icon_Kultur.png',
iconUrl: 'assets/images/Icons/Icon_Kultur.svg',
color: const Color.fromARGB(255, 80, 168, 250), //50A8FA//Kunst
category: '09d1f862-2b56-47af-8ee6-3c50056e3fa2',
textheight: 58,
@ -56,7 +55,7 @@ class Categories extends ChangeNotifier {
id: '4',
title: 'Sport & Verein',
imageUrl: 'assets/images/Sport.png',
iconUrl: 'assets/images/Icons/Icon_Sport.png',
iconUrl: 'assets/images/Icons/Icon_Sport.svg',
color: const Color.fromARGB(255, 80, 240, 250), //50F0FA //Sport
category: '15119876-9ff0-41e5-8fe5-c3675af5e054',
textheight: 58,
@ -66,7 +65,7 @@ class Categories extends ChangeNotifier {
id: '5',
title: 'Gesundheit',
imageUrl: 'assets/images/Gesundheit.png',
iconUrl: 'assets/images/Icons/Icon_Gesundheit.png',
iconUrl: 'assets/images/Icons/Icon_Gesundheit.svg',
color: const Color.fromARGB(255, 130, 73, 253), //8249FD //Gesundheit
category: '4ad3ac2d-04fc-4aa1-afae-17ec7bfc1714',
textheight: 86,
@ -76,7 +75,7 @@ class Categories extends ChangeNotifier {
id: '6',
title: 'Essen & Trinken',
imageUrl: 'assets/images/Essen.png',
iconUrl: 'assets/images/Icons/Icon_Essen.png',
iconUrl: 'assets/images/Icons/Icon_Essen.svg',
color: const Color.fromARGB(255, 253, 73, 73), //FD4949//Essen
category: 'ef83c4d3-228a-44e1-8a5d-8b47d2dfc351',
textheight: 58,
@ -86,7 +85,7 @@ class Categories extends ChangeNotifier {
id: '7',
title: 'Soziales',
imageUrl: 'assets/images/Soziales.png',
iconUrl: 'assets/images/Icons/Icon_Soziales.png',
iconUrl: 'assets/images/Icons/Icon_Soziales.svg',
color: const Color.fromARGB(255, 255, 0, 199), //FF00C7//Essen
category: '53a1782b-e07b-491d-b778-d99ef9cf57e2',
textheight: 86,
@ -96,7 +95,7 @@ class Categories extends ChangeNotifier {
id: '8',
title: 'Familie',
imageUrl: 'assets/images/Familie.png',
iconUrl: 'assets/images/Icons/Icon_Familie.png',
iconUrl: 'assets/images/Icons/Icon_Familie.svg',
color: const Color.fromARGB(
255, 66, 255, 0), //42FF00//Essen //HSL 104 100 50 100
category: '30cb3481-c425-4068-9714-adc86df85d3f',
@ -129,11 +128,13 @@ class Categories extends ChangeNotifier {
for (var index = 0; index < _categories.length; index++) {
//TODO: man müsste sicherstellen, dass die Main Category bei allen Events existent ist. Und dass in den jeweilige Subcategorien nicht die MainCatgeorie vorkommt. Erst dann kann das möglich sein.
//müsste man auch in der Admin Page ermöglichen.
final today = DateTime.now().toUtc().toString().split(' ')[0];
final response = await supabase
.from("events")
.select(
'id,name,main_category_id,location(name),event_category!inner(event_id)')
.eq('event_category.category_id', _categories[index].category);
'id,name,main_category_id,location(name),event_category!inner(event_id),time!inner(*)')
.eq('event_category.category_id',
_categories[index].category); //.gte('time.start_date', today);
var temp = (response.length);
_categories[index].amount = temp;
notifyListeners();
@ -189,6 +190,47 @@ class SupabaseDataService {
}
}
}
Future<List<Map<String, dynamic>>> fetchGroupedEvents_day(
String category) async {
try {
final String formattedDate =
DateFormat('yyyy-MM-dd').format(DateTime.now());
final response = await supabase.rpc('get_events_grouped_by_date_in_date',
params: {'cat_id': category, 'day': formattedDate});
//final response = await supabase.rpc('get_events_grouped_input_date', params: {'day': formattedDate});
// Cast auf die gewünschte Struktur
return (response as List)
.map((entry) => {
'start_date': entry['start_date'], // Das Gruppierungsdatum
'events': (entry['events'] as List)
.cast<Map<String, dynamic>>() // Event-Details
})
.toList();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
Future<List<Map<String, dynamic>>> fetchGroupedEvents(String category) async {
try {
final String formattedDate =
DateFormat('yyyy-MM-dd').format(DateTime.now());
final response = await supabase
.rpc('get_events_grouped_by_date', params: {'cat_id': category});
//final response = await supabase.rpc('get_events_grouped_input_date', params: {'day': formattedDate});
// Cast auf die gewünschte Struktur
return (response as List)
.map((entry) => {
'start_date': entry['start_date'], // Das Gruppierungsdatum
'events': (entry['events'] as List)
.cast<Map<String, dynamic>>() // Event-Details
})
.toList();
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
/* class _AsyncAutocomplete extends StatefulWidget {
const _AsyncAutocomplete();

View File

@ -1,4 +1,5 @@
import 'dart:math';
import 'package:Emma_home/utils/data.dart';
import 'package:flutter/material.dart';
String shortenText(String text, int maxLength) {
@ -21,6 +22,33 @@ String shortenText(String text, int maxLength) {
return '$shortened ...';
}
String extractTime24h(String timestamp) {
try {
DateTime dateTime = DateTime.parse(timestamp);
String hours = dateTime.hour.toString().padLeft(2, '0');
String minutes = dateTime.minute.toString().padLeft(2, '0');
return '$hours:$minutes';
} catch (e) {
print('Error parsing timestamp: $e');
return '--:--'; // or some other error indicator
}
}
//TODO: Color muss anhand der Categorie entschieden werden
// Also herauslesen welche Category das Event hat
// Dann den richtigen Eintrag in Data identifizieren udn die Farbe auswählen
Color extractColor(String categoryID) {
var singleCategories = Categories.instance;
final result = singleCategories.categories
.where((recipe) => recipe.category == categoryID)
.firstOrNull;
Color categorieColor = const Color.fromARGB(255, 255, 255, 255);
if (result != null) {
categorieColor = result.color;
}
return categorieColor;
}
class ScaleSize {
static double textScaleFactor(BuildContext context,
{double maxTextScaleFactor = 2}) {

View File

@ -37,12 +37,12 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
app_links: 10e0a0ab602ffaf34d142cd4862f29d34b303b2a
file_selector_macos: 54fdab7caa3ac3fc43c9fac4d7d8d231277f8cf2
file_selector_macos: cc3858c981fe6889f364731200d6232dac1d812d
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
COCOAPODS: 1.15.2
COCOAPODS: 1.16.2

View File

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: app_links
sha256: "4acba851087b25136e8f6e32a53bd4536eb3bec69947ddb66e7b9a5792ceb0c7"
sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99
url: "https://pub.dev"
source: hosted
version: "6.2.0"
version: "6.3.2"
app_links_linux:
dependency: transitive
description:
@ -33,22 +33,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
args:
dependency: transitive
description:
name: args
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
url: "https://pub.dev"
source: hosted
version: "2.6.0"
async:
dependency: transitive
description:
name: async
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.12.0"
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.1"
characters:
dependency: transitive
description:
@ -61,18 +69,18 @@ packages:
dependency: transitive
description:
name: clock
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.2"
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.19.0"
version: "1.18.0"
cross_file:
dependency: transitive
description:
@ -85,10 +93,10 @@ packages:
dependency: transitive
description:
name: crypto
sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
cupertino_icons:
dependency: "direct main"
description:
@ -101,10 +109,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.3.1"
ffi:
dependency: transitive
description:
@ -117,26 +125,26 @@ packages:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.0"
version: "7.0.1"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
url: "https://pub.dev"
source: hosted
version: "0.9.2+1"
version: "0.9.3+2"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385
sha256: "271ab9986df0c135d45c3cdb6bd0faa5db6f4976d3e4b437cf7d0f258d941bfc"
url: "https://pub.dev"
source: hosted
version: "0.9.4"
version: "0.9.4+2"
file_selector_platform_interface:
dependency: transitive
description:
@ -149,10 +157,10 @@ packages:
dependency: transitive
description:
name: file_selector_windows
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
sha256: "8f5d2f6590d51ecd9179ba39c64f722edc15226cc93dcc8698466ad36a4a85a4"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
version: "0.9.3+3"
flutter:
dependency: "direct main"
description: flutter
@ -178,10 +186,18 @@ packages:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "9d98bd47ef9d34e803d438f17fd32b116d31009f534a6fa5ce3a1167f189a6de"
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
url: "https://pub.dev"
source: hosted
version: "2.0.21"
version: "2.0.23"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: "54900a1a1243f3c4a5506d853a2b5c2dbc38d5f27e52a52618a8054401431123"
url: "https://pub.dev"
source: hosted
version: "2.0.16"
flutter_test:
dependency: "direct dev"
description: flutter
@ -196,26 +212,26 @@ packages:
dependency: "direct main"
description:
name: font_awesome_flutter
sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f"
sha256: d3a89184101baec7f4600d58840a764d2ef760fe1c5a20ef9e6b0e9b24a07a3a
url: "https://pub.dev"
source: hosted
version: "10.7.0"
version: "10.8.0"
functions_client:
dependency: transitive
description:
name: functions_client
sha256: b09f01be55ceec6a7a0916a0934e0c58d551292790901f15a24ae9d5654ea1f9
sha256: "61597ed93be197b1be6387855e4b760e6aac2355fcfc4df6d20d2b4579982158"
url: "https://pub.dev"
source: hosted
version: "2.3.3"
version: "2.4.0"
gotrue:
dependency: transitive
description:
name: gotrue
sha256: f3d4b70b8df6d05be2c6d558e8887576766685918be4ef87dbb8d7e547aeb049
sha256: b9541c62edc0ee1fddf2c95364251b8076a93bcdbc3ad27f14a633d187e89ccc
url: "https://pub.dev"
source: hosted
version: "2.9.0"
version: "2.11.0"
gtk:
dependency: transitive
description:
@ -252,26 +268,26 @@ packages:
dependency: transitive
description:
name: image_picker_android
sha256: "8c5abf0dcc24fe6e8e0b4a5c0b51a5cf30cefdf6407a3213dae61edc75a70f56"
sha256: fa8141602fde3f7e2f81dbf043613eb44dfa325fa0bcf93c0f142c9f7a2c193e
url: "https://pub.dev"
source: hosted
version: "0.8.12+12"
version: "0.8.12+18"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.6"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447"
sha256: "4f0568120c6fcc0aaa04511cb9f9f4d29fc3d0139884b1d06be88dcec7641d6b"
url: "https://pub.dev"
source: hosted
version: "0.8.12"
version: "0.8.12+1"
image_picker_linux:
dependency: transitive
description:
@ -324,18 +340,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.8"
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.9"
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
@ -352,6 +368,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
matcher:
dependency: transitive
description:
@ -380,10 +404,10 @@ packages:
dependency: transitive
description:
name: mime
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
version: "1.0.6"
nested:
dependency: transitive
description:
@ -396,26 +420,34 @@ packages:
dependency: transitive
description:
name: path
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.9.0"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
url: "https://pub.dev"
source: hosted
version: "2.2.10"
version: "2.2.14"
path_provider_foundation:
dependency: transitive
description:
@ -448,14 +480,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
version: "3.1.6"
plugin_platform_interface:
dependency: transitive
description:
@ -468,10 +508,10 @@ packages:
dependency: transitive
description:
name: postgrest
sha256: "3c6aea8d41cbb7cc33190a67fd8b0f21735a74d5871e52ada4c274aa3aa50dbb"
sha256: "9f759ac497a24839addbed69d9569ea6d51d2e4834c672b8c2a73752fb6945c8"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.4.0"
provider:
dependency: "direct main"
description:
@ -484,10 +524,10 @@ packages:
dependency: transitive
description:
name: realtime_client
sha256: "5d449be6dd49a413847b6da5cf48b44f7379047bc0ddc6f301d387d2ce4633b9"
sha256: "173c3dc40922bb0ae19a558ae1a0acf7b28ec8a458b54390c499bbe5ff15f049"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.4.0"
retry:
dependency: transitive
description:
@ -508,26 +548,26 @@ packages:
dependency: transitive
description:
name: shared_preferences
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
version: "2.3.3"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: a7e8467e9181cef109f601e3f65765685786c1a738a83d7fbbde377589c0d974
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.3"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d"
url: "https://pub.dev"
source: hosted
version: "2.5.2"
version: "2.5.3"
shared_preferences_linux:
dependency: transitive
description:
@ -564,7 +604,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
version: "0.0.99"
source_span:
dependency: transitive
description:
@ -577,18 +617,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.12.0"
version: "1.11.1"
storage_client:
dependency: transitive
description:
name: storage_client
sha256: "060aa8651ad2b30ce6fc30f4652317f45d21f8c6f6cc222b2430fc7f69f7d8ba"
sha256: "833666edcd804aaf434f3b13165fd553a8c6371a488618a58be8914856795c04"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.2.0"
stream_channel:
dependency: transitive
description:
@ -601,26 +641,26 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6"
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
version: "1.2.0"
supabase:
dependency: transitive
description:
name: supabase
sha256: c3a03d656110e13dd80ccabba7a5c591fece4c56ec3a21108e51b1e18d9c9a94
sha256: ecdfb226c483f05fd10425304de744144dfdda2f33d14151d2604cebe8c6d077
url: "https://pub.dev"
source: hosted
version: "2.4.0"
version: "2.6.0"
supabase_flutter:
dependency: "direct main"
description:
name: supabase_flutter
sha256: "79e5067f08572c7900bc77251e6c1e0cac80c3059b5820ba2b86469b22822b75"
sha256: bdbc6770e0e91db0b9d931f41ea4ee311d8819f539743f47e8cc795b492be75a
url: "https://pub.dev"
source: hosted
version: "2.7.0"
version: "2.8.1"
term_glyph:
dependency: transitive
description:
@ -633,10 +673,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.3"
version: "0.7.2"
timeago:
dependency: "direct main"
description:
@ -649,26 +689,26 @@ packages:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.4.0"
url_launcher:
dependency: transitive
description:
name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
url: "https://pub.dev"
source: hosted
version: "6.3.9"
version: "6.3.14"
url_launcher_ios:
dependency: transitive
description:
@ -681,18 +721,18 @@ packages:
dependency: transitive
description:
name: url_launcher_linux
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
version: "3.2.1"
url_launcher_platform_interface:
dependency: transitive
description:
@ -713,10 +753,34 @@ packages:
dependency: transitive
description:
name: url_launcher_windows
sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.3"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "27d5fefe86fb9aace4a9f8375b56b3c292b64d8c04510df230f849850d912cb7"
url: "https://pub.dev"
source: hosted
version: "1.1.15"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "2430b973a4ca3c4dbc9999b62b8c719a160100dcbae5c819bae0cacce32c9cdb"
url: "https://pub.dev"
source: hosted
version: "1.1.12"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
url: "https://pub.dev"
source: hosted
version: "1.1.16"
vector_math:
dependency: transitive
description:
@ -729,18 +793,18 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.3.1"
version: "14.2.5"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.1.0"
web_socket:
dependency: transitive
description:
@ -761,10 +825,18 @@ packages:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
url: "https://pub.dev"
source: hosted
version: "1.0.4"
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
yet_another_json_isolate:
dependency: transitive
description:
@ -774,5 +846,5 @@ packages:
source: hosted
version: "2.0.3"
sdks:
dart: ">=3.4.4 <4.0.0"
flutter: ">=3.22.0"
dart: ">=3.5.0 <4.0.0"
flutter: ">=3.24.0"

View File

@ -41,6 +41,7 @@ dependencies:
provider: ^6.0.5
flutter_dotenv: ^5.2.1
font_awesome_flutter: ^10.1.0
flutter_svg: ^2.0.5
dev_dependencies:

47
sql_functions.sql Normal file
View File

@ -0,0 +1,47 @@
CREATE OR REPLACE FUNCTION get_events_grouped_by_date_in_date(cat_id UUID, day date)
RETURNS TABLE(
start_date DATE,
events JSON
) AS $$
BEGIN
RETURN QUERY
WITH time_grouped AS (
SELECT
time.start_date::date AS group_start_date,
events.id AS event_id,
events.name AS event_name,
events.description AS event_description,
events.detail AS event_detail,
events.subheader AS event_subheader,
events.main_category_id AS event_main_cat,
location.name AS location_title,
time.start_date AS start_timestamp,
time.end_date AS end_timestamp
FROM events
INNER JOIN location ON events.location_id = location.id
INNER JOIN time ON time.event_id = events.id
INNER JOIN event_category ON event_category.event_id = events.id
WHERE event_category.category_id = cat_id AND time.start_date::date >= now()
GROUP BY time.start_date::date, events.id, location.name, time.start_date, time.end_date
)
SELECT
group_start_date AS start_date,
json_agg(json_build_object(
'id', event_id,
'name', event_name,
'description', event_description,
'detail', event_detail,
'subheader', event_subheader,
'main_category_id', event_main_cat,
'location_name', location_title,
'start', start_timestamp,
'end', end_timestamp
)) AS events
FROM time_grouped
GROUP BY group_start_date
ORDER BY group_start_date DESC;
END;
$$ LANGUAGE plpgsql;

View File

@ -8,12 +8,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:learn_project/main.dart';
import 'package:Emma_home/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);