diff --git a/.gitea/workflows/qs.yml b/.gitea/workflows/qs.yml index 35863d9..1be31af 100644 --- a/.gitea/workflows/qs.yml +++ b/.gitea/workflows/qs.yml @@ -20,8 +20,8 @@ jobs: working-directory: app/frontend run: "node ../node_modules/typescript/bin/tsc --noEmit" - name: "Stylelint" - working-directory: app/frontend/styles - run: "node ../../node_modules/stylelint/bin/stylelint.mjs ." + working-directory: app/frontend + run: "node ../node_modules/stylelint/bin/stylelint.mjs ." - name: "ESLint" working-directory: app run: "node node_modules/eslint/bin/eslint.js frontend" @@ -48,21 +48,3 @@ jobs: - name: "PHP Stan" working-directory: app run: "vendor/bin/phpstan analyze" - - qs_mixed: - name: "QS Mixed" - runs-on: "ubuntu-latest" - container: - image: "git.euph.dev/actions/runner-php-8.3:latest" - steps: - - name: "Checkout" - uses: "https://git.euph.dev/actions/checkout@v3" - - name: "Install Dependencies" - working-directory: app - run: | - parallel --halt soon,fail=1 ::: \ - "composer check-platform-reqs && composer install --no-scripts --audit" \ - "npm install --no-fund" - - name: "Lint" - working-directory: app - run: "node node_modules/eslint/bin/eslint.js frontend" diff --git a/app/Justfile b/Justfile similarity index 94% rename from app/Justfile rename to Justfile index 1ed58d2..90008bf 100644 --- a/app/Justfile +++ b/Justfile @@ -1,8 +1,8 @@ _default: @bin/just/choose.sh {{ source_file() }} choose -mod backend -mod frontend +mod backend 'app/backend/mod.just' +mod frontend 'app/frontend/mod.just' alias i := install alias start := up @@ -69,7 +69,7 @@ lint linter="": just frontend::lint all && just backend::lint;; *PHP*) just backend::lint ;; *TS*) just frontend::lint TS ;; - *SCSS*) just frontend::lint all SCSS ;; + *SCSS*) just frontend::lint SCSS ;; *Twig*) just frontend::lint TWIG ;; esac diff --git a/app/frontend/templates/icons/euphcloud.svg.twig b/app/assets/icons/branding/euphcloud.svg similarity index 90% rename from app/frontend/templates/icons/euphcloud.svg.twig rename to app/assets/icons/branding/euphcloud.svg index 347cfc2..b30e425 100644 --- a/app/frontend/templates/icons/euphcloud.svg.twig +++ b/app/assets/icons/branding/euphcloud.svg @@ -1,5 +1,4 @@ diff --git a/app/backend/TestController.php b/app/backend/TestController.php index 1ec6b80..b62038a 100644 --- a/app/backend/TestController.php +++ b/app/backend/TestController.php @@ -27,7 +27,7 @@ final readonly class TestController { return new Response( $this->twig->render( - 'base.html.twig' + 'sites/index.html.twig' ) ); } diff --git a/app/backend/mod.just b/app/backend/mod.just index 1418d9d..279ee7a 100644 --- a/app/backend/mod.just +++ b/app/backend/mod.just @@ -1,17 +1,19 @@ __default: - @../bin/just/choose.sh {{ source_file() }} choose + @../../bin/just/choose.sh {{ source_file() }} choose # Checks whether the requriements are met [group('main')] check: #!/bin/bash - source ../bin/just/colors.sh - source ../bin/just/check.sh + source ../../bin/just/colors.sh + source ../../bin/just/check.sh printf "${BLUE_BG}${BLACK_FG} Checking Backend Requirements ${CLEAR}\n" cd .. check_cmd "php" "Php" check_cmd "composer" "Composer" + check_cmd "symfony" "Symfony cli" + current_composer_version=$(composer --version 2>/dev/null | awk '{print $3}' | cut -d '.' -f 1) if [ "${current_composer_version}" = "2" ]; then printf >&2 "${GREEN_FG}✔ Composer${BLUE_FG} Version ${GREEN_FG}${current_composer_version}${BLUE_FG} is ${GREEN_FG}installed${BLUE_FG}.\n" @@ -19,8 +21,6 @@ check: printf >&2 "${RED_FG}✘ Wrong Composer Version${YELLOW_FG} is installed!\n Version ${RED_FG}2${YELLOW_FG} is ${RED_FG}required${YELLOW_FG}.\n" error = 1 fi - - check_cmd "symfony" "Symfony cli" required_php_version=$(cat .php-version) current_php_version=$(symfony php -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;") if [ "${current_php_version}" = "${required_php_version}" ]; then @@ -34,7 +34,12 @@ check: check "[ $(php -m | grep -c pdo_mysql) -eq 1 ]" "Php Mysql PDO" check_cmd "docker" "Docker" - check "$(docker compose version >/dev/null 2>&1)" "Docker Compose" + if [[ "$(docker compose version 2>&1)" == "Docker Compose version v"* ]]; then + printf >&2 "${GREEN_FG}✔ Docker Compose${BLUE_FG} is ${GREEN_FG}installed${BLUE_FG}.\n" + else + printf >&2 "${RED_FG}✘ Docker Compose${YELLOW_FG} is ${RED_FG}not installed${YELLOW_FG}! \n" + error=1 + fi if ((error > 0 )); then exit 1 diff --git a/app/compose.yaml b/app/compose.yaml index a2edb72..77ad28d 100644 --- a/app/compose.yaml +++ b/app/compose.yaml @@ -1,5 +1,3 @@ -version: '3' - services: mysql: container_name: 'euph-website_mysql' diff --git a/app/composer.json b/app/composer.json index 649acd3..463a909 100644 --- a/app/composer.json +++ b/app/composer.json @@ -23,11 +23,15 @@ "symfony/flex": "^2", "symfony/form": "7.1.*", "symfony/framework-bundle": "7.1.*", + "symfony/http-client": "7.1.*", "symfony/monolog-bundle": "^3.0", "symfony/runtime": "7.1.*", - "symfony/stimulus-bundle": "^2.12", + "symfony/stimulus-bundle": "^2.18", "symfony/twig-bundle": "7.1.*", "symfony/uid": "7.1.*", + "symfony/ux-icons": "^2.18", + "symfony/ux-swup": "^2.18", + "symfony/ux-twig-component": "*", "symfony/validator": "7.1.*", "symfony/webpack-encore-bundle": "^2.1", "symfony/yaml": "7.1.*", diff --git a/app/composer.lock b/app/composer.lock index 1e05384..c910dba 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ee85551bd6012966efcff3c2d44a4b98", + "content-hash": "9af65731bd60f6cd005a51b1747d6d92", "packages": [ { "name": "dflydev/dot-access-data", @@ -3675,6 +3675,178 @@ ], "time": "2024-06-28T08:00:31+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "90ace27d17ccc9afc6f7ec0081e8529fb0e29425" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/90ace27d17ccc9afc6f7ec0081e8529fb0e29425", + "reference": "90ace27d17ccc9afc6f7ec0081e8529fb0e29425", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-28T08:00:31+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v7.1.1", @@ -5786,6 +5958,244 @@ ], "time": "2024-05-31T14:57:53+00:00" }, + { + "name": "symfony/ux-icons", + "version": "v2.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-icons.git", + "reference": "a00140b15feb16a0d991ee04e115f2a15b0d9941" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-icons/zipball/a00140b15feb16a0d991ee04e115f2a15b0d9941", + "reference": "a00140b15feb16a0d991ee04e115f2a15b0d9941", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0" + }, + "conflict": { + "symfony/flex": "<1.13" + }, + "require-dev": { + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "6.4|^7.0", + "symfony/phpunit-bridge": "^6.3|^7.0", + "symfony/ux-twig-component": "^2.14", + "zenstruck/console-test": "^1.5" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "name": "symfony/ux", + "url": "https://github.com/symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\Icons\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Bond", + "email": "kevinbond@gmail.com" + }, + { + "name": "Simon André", + "email": "smn.andre@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Renders local and remote SVG icons in your Twig templates.", + "homepage": "https://symfony.com", + "keywords": [ + "icons", + "svg", + "symfony-ux", + "twig" + ], + "support": { + "source": "https://github.com/symfony/ux-icons/tree/v2.18.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-07T23:22:02+00:00" + }, + { + "name": "symfony/ux-swup", + "version": "v2.18.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-swup.git", + "reference": "208f26399b594613a0eb18dcf6117f67a691a2c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-swup/zipball/208f26399b594613a0eb18dcf6117f67a691a2c4", + "reference": "208f26399b594613a0eb18dcf6117f67a691a2c4", + "shasum": "" + }, + "conflict": { + "symfony/flex": "<1.13" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "name": "symfony/ux", + "url": "https://github.com/symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\Swup\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Swup integration for Symfony", + "homepage": "https://symfony.com", + "keywords": [ + "symfony-ux" + ], + "support": { + "source": "https://github.com/symfony/ux-swup/tree/v2.18.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-01T17:50:16+00:00" + }, + { + "name": "symfony/ux-twig-component", + "version": "v2.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/ux-twig-component.git", + "reference": "c5ba36dc0f55b75d4c6d7dc546dfdbe4002f82e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ux-twig-component/zipball/c5ba36dc0f55b75d4c6d7dc546dfdbe4002f82e7", + "reference": "c5ba36dc0f55b75d4c6d7dc546dfdbe4002f82e7", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.2|^3.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "twig/twig": "^3.8" + }, + "conflict": { + "symfony/config": "<5.4.0" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^6.0|^7.0", + "symfony/stimulus-bundle": "^2.9.1", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/webpack-encore-bundle": "^1.15" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "name": "symfony/ux", + "url": "https://github.com/symfony/ux" + } + }, + "autoload": { + "psr-4": { + "Symfony\\UX\\TwigComponent\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Twig components for Symfony", + "homepage": "https://symfony.com", + "keywords": [ + "components", + "symfony-ux", + "twig" + ], + "support": { + "source": "https://github.com/symfony/ux-twig-component/tree/v2.18.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-11T18:51:33+00:00" + }, { "name": "symfony/validator", "version": "v7.1.2", diff --git a/app/config/bundles.php b/app/config/bundles.php index bb709fe..2fb9c9a 100644 --- a/app/config/bundles.php +++ b/app/config/bundles.php @@ -16,4 +16,7 @@ return [ Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Presta\SitemapBundle\PrestaSitemapBundle::class => ['all' => true], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], + Symfony\UX\Swup\SwupBundle::class => ['all' => true], ]; diff --git a/app/config/packages/twig_component.yaml b/app/config/packages/twig_component.yaml new file mode 100644 index 0000000..2b203cd --- /dev/null +++ b/app/config/packages/twig_component.yaml @@ -0,0 +1,5 @@ +twig_component: + anonymous_template_directory: 'components/' + defaults: + # Namespace & directory for components + App\Components\: 'components/' diff --git a/app/config/routes.yaml b/app/config/routes.yaml index e1710e3..1bd9ebd 100644 --- a/app/config/routes.yaml +++ b/app/config/routes.yaml @@ -7,9 +7,9 @@ controllers: presta_sitemap: resource: "@PrestaSitemapBundle/config/routing.yml" -when@dev: - test_style: - path: /test/styles - controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController - defaults: - template: 'test/styles.html.twig' +#when@dev: +# test_style: +# path: /test/styles +# controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController +# defaults: +# template: 'test/styles.html.twig' diff --git a/app/frontend/.eslintrc.json b/app/frontend/.eslintrc.json index e228e47..1833da0 100644 --- a/app/frontend/.eslintrc.json +++ b/app/frontend/.eslintrc.json @@ -12,6 +12,12 @@ "ecmaVersion": "latest", "sourceType": "module" }, + "overrides": [ + { + "files": ["*.svelte"], + "parser": "svelte-eslint-parser" + } + ], "plugins": [ "@typescript-eslint" ], diff --git a/app/frontend/.stylelintignore b/app/frontend/.stylelintignore new file mode 100644 index 0000000..ebcbcc3 --- /dev/null +++ b/app/frontend/.stylelintignore @@ -0,0 +1,4 @@ +*.ts +*.twig +*.json +mod.just diff --git a/app/frontend/styles/.stylelintrc.json b/app/frontend/.stylelintrc.json similarity index 100% rename from app/frontend/styles/.stylelintrc.json rename to app/frontend/.stylelintrc.json diff --git a/app/frontend/app.ts b/app/frontend/app.ts index 9d189f3..0585164 100644 --- a/app/frontend/app.ts +++ b/app/frontend/app.ts @@ -1,3 +1,46 @@ import '@styles/app.scss'; import '@pkg/stimulus'; -import '@pkg/flowbite'; +import '@pkg/swup'; + +import {Theme, THEME_LOCAL_STORAGE_ID} from '#const/theme'; + +const DARK_MODE_QUERY: MediaQueryList = window.matchMedia('(prefers-color-scheme: dark)'); + +function initTheme(): void { + handleTheme(DARK_MODE_QUERY.matches); + DARK_MODE_QUERY.addEventListener('change', handleThemeChange); +} + +function handleThemeChange(e: MediaQueryListEvent): void { + handleTheme(e.matches); +} + +function handleTheme(prefersDark: boolean): void { + const theme = localStorage[THEME_LOCAL_STORAGE_ID]; + if (theme === Theme.DARK) { + document.documentElement.classList.add(Theme.DARK); + console.log('explicit dark'); + } else if (!(THEME_LOCAL_STORAGE_ID in localStorage) && prefersDark) { + document.documentElement.classList.add(Theme.DARK); + console.log('implicit dark'); + } else { + document.documentElement.classList.remove(Theme.DARK); + console.log('light'); + } +} + +export {initTheme}; + +// On page load or when changing themes, best to add inline in `head` to avoid FOUC + + +// Whenever the user explicitly chooses light mode +//localStorage.theme = 'light'; + +// Whenever the user explicitly chooses dark mode +//localStorage.theme = 'dark'; + +// Whenever the user explicitly chooses to respect the OS preference +//localStorage.removeItem('theme'); + +initTheme(); diff --git a/app/frontend/constants/http.ts b/app/frontend/constants/http.ts deleted file mode 100644 index 177d9e5..0000000 --- a/app/frontend/constants/http.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare enum HttpCodes { - OK = 200 -} - -export {HttpCodes}; diff --git a/app/frontend/controllers.json b/app/frontend/controllers.json deleted file mode 100644 index e2ce9b5..0000000 --- a/app/frontend/controllers.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "controllers": [], - "entrypoints": [] -} diff --git a/app/frontend/controllers/Components/BurgerMenu_controller.ts b/app/frontend/controllers/Components/BurgerMenu_controller.ts new file mode 100644 index 0000000..252fe50 --- /dev/null +++ b/app/frontend/controllers/Components/BurgerMenu_controller.ts @@ -0,0 +1,20 @@ +import {Controller} from '@hotwired/stimulus'; + +export default class extends Controller { + static targets: Array = ['container']; + declare readonly containerTarget: HTMLElement; + + connect(): void { + console.log('Init Burgers'); + this.containerTarget.style.left = ''; + this.containerTarget.style.right = `-${this.containerTarget.offsetWidth}px`; + } + + open(): void { + this.containerTarget.style.right = '0'; + } + + close(): void { + this.containerTarget.style.right = `-${this.containerTarget.offsetWidth}px`; + } +} diff --git a/app/frontend/controllers/controllers.json b/app/frontend/controllers/controllers.json new file mode 100644 index 0000000..e26681a --- /dev/null +++ b/app/frontend/controllers/controllers.json @@ -0,0 +1,11 @@ +{ + "controllers": { + "@symfony/ux-swup": { + "swup": { + "enabled": true, + "fetch": "eager" + } + } + }, + "entrypoints": [] +} diff --git a/app/frontend/controllers/hello_controller.ts b/app/frontend/controllers/hello_controller.ts deleted file mode 100644 index 861e403..0000000 --- a/app/frontend/controllers/hello_controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {Controller} from '@hotwired/stimulus'; - -export default class extends Controller { - - static targets: Array = ['container']; - declare readonly containerTarget: HTMLElement; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - afterLoad(identifier: string, application: HTMLElement): void { - console.log(this.containerTarget); - } -} diff --git a/app/frontend/domain/theme.ts b/app/frontend/domain/theme.ts deleted file mode 100644 index 40c7070..0000000 --- a/app/frontend/domain/theme.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {Theme, THEME_LOCAL_STORAGE_ID} from '@const/theme'; - -const DARK_MODE_QUERY: MediaQueryList = window.matchMedia('(prefers-color-scheme: dark)'); - -function initTheme(): void { - handleTheme(DARK_MODE_QUERY.matches); - DARK_MODE_QUERY.addEventListener('change', handleThemeChange); -} - -function handleThemeChange(e: MediaQueryListEvent): void { - handleTheme(e.matches); -} - -function handleTheme(prefersDark: boolean): void { - const theme = localStorage[THEME_LOCAL_STORAGE_ID]; - if (theme === Theme.DARK) { - document.documentElement.classList.add(Theme.DARK); - console.log('explicit dark'); - } else if (!(THEME_LOCAL_STORAGE_ID in localStorage) && prefersDark) { - document.documentElement.classList.add(Theme.DARK); - console.log('implicit dark'); - } else { - document.documentElement.classList.remove(Theme.DARK); - console.log('light'); - } -} - -export {initTheme}; - -// On page load or when changing themes, best to add inline in `head` to avoid FOUC - - -// Whenever the user explicitly chooses light mode -//localStorage.theme = 'light'; - -// Whenever the user explicitly chooses dark mode -//localStorage.theme = 'dark'; - -// Whenever the user explicitly chooses to respect the OS preference -//localStorage.removeItem('theme'); diff --git a/app/frontend/mod.just b/app/frontend/mod.just index d4c9dc8..bcc527c 100644 --- a/app/frontend/mod.just +++ b/app/frontend/mod.just @@ -1,14 +1,15 @@ __default: - @../bin/just/choose.sh {{ source_file() }} choose + @../../bin/just/choose.sh {{ source_file() }} choose # Checks whether the requriements are met [group('main')] check: #!/bin/bash - source ../bin/just/colors.sh - source ../bin/just/check.sh + source ../../bin/just/colors.sh + source ../../bin/just/check.sh printf "${BLUE_BG}${BLACK_FG} Checking Frontend Requirements ${CLEAR}\n" + check_cmd "screen" "screen" check_cmd "volta" "Volta" check_cmd "node" "Node" check_cmd "npm" "NPM" @@ -39,7 +40,7 @@ session_name := "euph-website_frontend" [group('main')] up: halt #!/bin/bash - source ../bin/just/colors.sh + source ../../bin/just/colors.sh cd .. && screen -dmS {{ session_name }} npm run watch >> /dev/null if [ $? -eq 0 ]; then printf "${GREEN_FG}Frontend was started${CLEAR}\n" @@ -51,7 +52,7 @@ up: halt [group('main')] halt: #!/bin/bash - source ../bin/just/colors.sh + source ../../bin/just/colors.sh screen -XS {{ session_name }} quit >> /dev/null if [ $? -eq 0 ]; then printf "${GREEN_FG}Frontend was stopped${CLEAR}\n" @@ -60,7 +61,7 @@ halt: [group('main')] attach: #!/bin/bash - source ../bin/just/colors.sh + source ../../bin/just/colors.sh if screen -ls | grep -q {{ session_name }}; then screen -r {{ session_name }} else diff --git a/app/frontend/packages/flowbite.ts b/app/frontend/packages/flowbite.ts deleted file mode 100644 index 8b51c09..0000000 --- a/app/frontend/packages/flowbite.ts +++ /dev/null @@ -1,4 +0,0 @@ -import 'flowbite'; -import {initFlowbite} from 'flowbite'; - -initFlowbite(); diff --git a/app/frontend/packages/swup.ts b/app/frontend/packages/swup.ts new file mode 100644 index 0000000..bcb6697 --- /dev/null +++ b/app/frontend/packages/swup.ts @@ -0,0 +1,2 @@ +//import Swup from 'swup'; +//new Swup(); diff --git a/app/frontend/styles/app.scss b/app/frontend/styles/app.scss index 4553c1f..a645929 100644 --- a/app/frontend/styles/app.scss +++ b/app/frontend/styles/app.scss @@ -1,5 +1,5 @@ -@import "components/header"; -@import "components/burger-menu"; +@import "components/Header"; +@import "components/BurgerMenu/Index"; @tailwind base; @tailwind components; @tailwind utilities; diff --git a/app/frontend/styles/components/BurgerMenu/Index.scss b/app/frontend/styles/components/BurgerMenu/Index.scss new file mode 100644 index 0000000..dd8bd1c --- /dev/null +++ b/app/frontend/styles/components/BurgerMenu/Index.scss @@ -0,0 +1,33 @@ +@import "Nav"; +@import "Login"; +@import "User"; + +.burger-menu { + @apply ml-auto h-full aspect-square; + + &__container { + @apply fixed top-0 right-0 h-screen overflow-y-auto z-40; + @apply flex flex-col p-2 gap-2 w-64; + @apply bg-gray-200 dark:bg-gray-600; + + transition: ease-in-out 200ms; + } + + &__button-open { + @apply h-full aspect-square; + } + + &__button-close { + @apply h-8 w-8 absolute right-2 aspect-square; + } + + &__icon { + @apply text-gray-900 dark:text-gray-100; + @apply h-6 w-6; + } + + &__icon-full { + @apply text-gray-900 dark:text-gray-100; + @apply h-full w-full; + } +} diff --git a/app/frontend/styles/components/BurgerMenu/Login.scss b/app/frontend/styles/components/BurgerMenu/Login.scss new file mode 100644 index 0000000..cc860ba --- /dev/null +++ b/app/frontend/styles/components/BurgerMenu/Login.scss @@ -0,0 +1,8 @@ +.burger-menu-login { + @apply flex p-2 gap-2 items-center justify-center; + @apply rounded-lg bg-blue-500 app__text; + + &__icon { + @apply burger-menu__icon; + } +} diff --git a/app/frontend/styles/components/BurgerMenu/Nav.scss b/app/frontend/styles/components/BurgerMenu/Nav.scss new file mode 100644 index 0000000..bd0324e --- /dev/null +++ b/app/frontend/styles/components/BurgerMenu/Nav.scss @@ -0,0 +1,20 @@ +.burger-menu-nav { + @apply text-lg app__text; + + &__list { + @apply flex flex-col gap-2; + } + + &__item { + @apply h-8; + } + + &__link { + @apply flex p-1 gap-2 items-center; + @apply rounded-md hover:bg-gray-200 dark:hover:bg-gray-600; + } + + &__icon { + @apply burger-menu__icon; + } +} diff --git a/app/frontend/styles/components/BurgerMenu/User.scss b/app/frontend/styles/components/BurgerMenu/User.scss new file mode 100644 index 0000000..85aa586 --- /dev/null +++ b/app/frontend/styles/components/BurgerMenu/User.scss @@ -0,0 +1,47 @@ +.burger-menu-user { + @apply flex flex-col items-center; + @apply text-gray-900 dark:text-gray-100; + + + &__picture-wrapper { + @apply w-1/3 aspect-square mx-auto; + } + + &__name { + @apply app__text-bold text-xl; + @apply h-6; + } + + &__icon-full { + @apply burger-menu__icon-full; + } + + &__email { + @apply app__text-light text-base; + @apply h-6; + } + + &__info { + @apply app__text-light text-base; + @apply h-6; + } + + &__actions { + @apply inline-flex mt-2; + + button { + @apply inline-flex p-1; + @apply bg-transparent; + @apply app__text text-sm; + @apply border border-r-0 border-gray-900 dark:border-gray-100; + + &:first-of-type { + @apply rounded-s-lg; + } + + &:last-of-type { + @apply rounded-e-lg border-r; + } + } + } +} diff --git a/app/frontend/styles/components/header.scss b/app/frontend/styles/components/Header.scss similarity index 96% rename from app/frontend/styles/components/header.scss rename to app/frontend/styles/components/Header.scss index 40637c4..b69ad7c 100644 --- a/app/frontend/styles/components/header.scss +++ b/app/frontend/styles/components/Header.scss @@ -1,4 +1,4 @@ -#header { +.header { @apply flex h-12 p-2 gap-2 items-center; @apply bg-gray-300 dark:bg-gray-700; diff --git a/app/frontend/styles/components/burger-menu.scss b/app/frontend/styles/components/burger-menu.scss deleted file mode 100644 index a53be92..0000000 --- a/app/frontend/styles/components/burger-menu.scss +++ /dev/null @@ -1,79 +0,0 @@ -#burger-menu { - @apply fixed top-0 right-0 h-screen overflow-y-auto z-40; - @apply flex flex-col p-2 gap-2 w-64; - @apply bg-gray-100 dark:bg-gray-700; - - - &__button-open { - @apply ml-auto h-full aspect-square; - } - - &__button-close { - @apply h-8 w-8 absolute right-2 aspect-square; - } - - &__user-section { - @apply flex flex-col items-center; - @apply text-black dark:text-white; - } - - &__user-picture-wrapper { - @apply w-1/3 aspect-square mx-auto; - } - - &__user-name { - @apply app__text-bold text-xl; - @apply h-6; - } - - &__user-email { - @apply app__text-light text-base; - @apply h-6; - } - - &__user-info { - @apply app__text-light text-base; - @apply h-6; - } - - &__user-actions { - @apply inline-flex mt-2; - - button { - @apply inline-flex p-1; - @apply bg-transparent; - @apply app__text text-sm; - @apply border border-r-0 border-gray-900 dark:border-white; - - &:first-of-type { - @apply rounded-s-lg; - } - - &:last-of-type { - @apply rounded-e-lg border-r; - } - } - } - - &__login { - @apply flex p-2 gap-2 items-center justify-center; - @apply rounded-lg bg-blue-500 app__text; - } - - &__nav { - @apply text-lg app__text; - - &-list { - @apply flex flex-col gap-2; - } - - &-item { - @apply h-8; - } - - &-link { - @apply flex p-1 gap-2 items-center; - @apply rounded-md hover:bg-gray-200 dark:hover:bg-gray-600; - } - } -} diff --git a/app/frontend/templates/base.html.twig b/app/frontend/templates/base.html.twig index 12c356b..cb37b51 100644 --- a/app/frontend/templates/base.html.twig +++ b/app/frontend/templates/base.html.twig @@ -15,14 +15,14 @@ + {{ encore_entry_link_tags('app') }} - {{ encore_entry_script_tags('theme') }} {{ encore_entry_script_tags('app') }} {% block title %}Euph{% endblock %} - -{% include 'components/header.html.twig' %} + + {% block body %}{% endblock %} diff --git a/app/frontend/templates/components/BurgerMenu/Index.html.twig b/app/frontend/templates/components/BurgerMenu/Index.html.twig new file mode 100644 index 0000000..36b1d84 --- /dev/null +++ b/app/frontend/templates/components/BurgerMenu/Index.html.twig @@ -0,0 +1,24 @@ +{% set logged_in = true %} +
+ +
+ + + +
+ +
+
+ diff --git a/app/frontend/templates/components/BurgerMenu/Login.html.twig b/app/frontend/templates/components/BurgerMenu/Login.html.twig new file mode 100644 index 0000000..e5d5d5f --- /dev/null +++ b/app/frontend/templates/components/BurgerMenu/Login.html.twig @@ -0,0 +1,9 @@ +{% props logged_in = false %} + +{% if not logged_in %} +
+ +{% endif %} diff --git a/app/frontend/templates/components/BurgerMenu/Nav.html.twig b/app/frontend/templates/components/BurgerMenu/Nav.html.twig new file mode 100644 index 0000000..f889a2d --- /dev/null +++ b/app/frontend/templates/components/BurgerMenu/Nav.html.twig @@ -0,0 +1,16 @@ + + +{% macro nav_item(name, href, icon) %} +
  • + + + {{ name }} + +
  • +{% endmacro %} diff --git a/app/frontend/templates/components/BurgerMenu/User.html.twig b/app/frontend/templates/components/BurgerMenu/User.html.twig new file mode 100644 index 0000000..13a94ff --- /dev/null +++ b/app/frontend/templates/components/BurgerMenu/User.html.twig @@ -0,0 +1,25 @@ +{% props logged_in = false %} + +
    +
    + +
    + {% if logged_in %} + Username + +
    + {{ _self.user_action('Profile', 'user') }} + {{ _self.user_action('Settings', 'gear') }} + {{ _self.user_action('Logout', 'sign-out') }} +
    + {% else %} + not logged in + {% endif %} +
    + +{% macro user_action(name, icon) %} + +{% endmacro %} diff --git a/app/frontend/templates/components/header.html.twig b/app/frontend/templates/components/Header.html.twig similarity index 52% rename from app/frontend/templates/components/header.html.twig rename to app/frontend/templates/components/Header.html.twig index b2de304..74f6428 100644 --- a/app/frontend/templates/components/header.html.twig +++ b/app/frontend/templates/components/Header.html.twig @@ -1,14 +1,14 @@ -