From 7c72ed82b6e8160331f0fe0bffbbea8c4b4d1e06 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 18 Jun 2026 17:06:54 +0200 Subject: [PATCH] Revert TypeScript migration - keep JS/JSX --- eslint.config.js | 25 +-- package.json | 19 +- public/build/manifest.json | 106 ++------- resources/js/bootstrap.js | 34 +++ resources/js/bootstrap.ts | 6 - resources/js/{global.ts => global.js} | 0 resources/js/pages/Home.jsx | 31 +++ resources/js/pages/Home.tsx | 43 ---- resources/js/pages/Index.jsx | 119 ++++++++++ resources/js/pages/Index.tsx | 206 ------------------ resources/js/ssr.jsx | 12 + resources/js/ssr.tsx | 16 -- resources/js/types.d.ts | 31 --- resources/themes/atom/js/app.js | 25 +++ resources/themes/atom/js/app.ts | 18 -- resources/themes/atom/js/bootstrap.js | 34 +++ resources/themes/atom/js/bootstrap.ts | 7 - .../atom/js/components/ArticleReactions.js | 131 +++++++++++ .../atom/js/components/ArticleReactions.ts | 147 ------------- .../{AtomSliders.ts => AtomSliders.js} | 7 +- .../{ThemeSwitcher.ts => ThemeSwitcher.js} | 15 +- .../themes/atom/views/client/nitro.blade.php | 2 +- .../themes/atom/views/layouts/app.blade.php | 2 +- .../themes/atom/views/layouts/guest.blade.php | 2 +- .../themes/atom/views/maintenance.blade.php | 2 +- resources/themes/atom/vite.config.js | 8 +- resources/themes/dusk/js/app.js | 40 ++++ resources/themes/dusk/js/app.ts | 36 --- resources/themes/dusk/js/bootstrap.js | 31 +++ resources/themes/dusk/js/bootstrap.ts | 4 - .../dusk/js/components/ArticleReactions.js | 131 +++++++++++ .../dusk/js/components/ArticleReactions.ts | 147 ------------- .../themes/dusk/views/client/nitro.blade.php | 2 +- .../themes/dusk/views/layouts/app.blade.php | 2 +- .../themes/dusk/views/maintenance.blade.php | 2 +- resources/themes/dusk/vite.config.js | 8 +- resources/views/app.blade.php | 2 +- .../views/layouts/installation.blade.php | 2 +- tsconfig.json | 30 --- vite.config.js | 4 +- yarn.lock | 177 +++------------ 41 files changed, 680 insertions(+), 986 deletions(-) create mode 100755 resources/js/bootstrap.js delete mode 100755 resources/js/bootstrap.ts rename resources/js/{global.ts => global.js} (100%) create mode 100755 resources/js/pages/Home.jsx delete mode 100755 resources/js/pages/Home.tsx create mode 100755 resources/js/pages/Index.jsx delete mode 100755 resources/js/pages/Index.tsx create mode 100755 resources/js/ssr.jsx delete mode 100755 resources/js/ssr.tsx delete mode 100644 resources/js/types.d.ts create mode 100755 resources/themes/atom/js/app.js delete mode 100755 resources/themes/atom/js/app.ts create mode 100755 resources/themes/atom/js/bootstrap.js delete mode 100755 resources/themes/atom/js/bootstrap.ts create mode 100755 resources/themes/atom/js/components/ArticleReactions.js delete mode 100755 resources/themes/atom/js/components/ArticleReactions.ts rename resources/themes/atom/js/components/{AtomSliders.ts => AtomSliders.js} (83%) rename resources/themes/atom/js/components/{ThemeSwitcher.ts => ThemeSwitcher.js} (71%) create mode 100755 resources/themes/dusk/js/app.js delete mode 100755 resources/themes/dusk/js/app.ts create mode 100755 resources/themes/dusk/js/bootstrap.js delete mode 100755 resources/themes/dusk/js/bootstrap.ts create mode 100755 resources/themes/dusk/js/components/ArticleReactions.js delete mode 100755 resources/themes/dusk/js/components/ArticleReactions.ts delete mode 100644 tsconfig.json diff --git a/eslint.config.js b/eslint.config.js index a0ec258..5f2f610 100755 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,6 +1,5 @@ import globals from "globals"; -import tseslint from "@typescript-eslint/eslint-plugin"; -import tsParser from "@typescript-eslint/parser"; +import pluginVue from "eslint-plugin-vue"; export default [ { @@ -12,32 +11,22 @@ export default [ "build/**", ], }, + ...pluginVue.configs["flat/essential"], { - files: ["**/*.{ts,tsx}"], languageOptions: { - parser: tsParser, - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - ecmaFeatures: { - jsx: true, - }, - }, globals: { ...globals.browser, ...globals.node, + Alpine: "readonly", + $: "readonly", + jQuery: "readonly", }, }, - plugins: { - "@typescript-eslint": tseslint, - }, rules: { "no-console": "warn", "no-debugger": "warn", - "@typescript-eslint/no-unused-vars": [ - "warn", - { argsIgnorePattern: "^_" }, - ], + "vue/multi-word-component-names": "off", + "vue/no-v-html": "off", }, }, ]; diff --git a/package.json b/package.json index 7634b12..88e28ef 100755 --- a/package.json +++ b/package.json @@ -8,17 +8,16 @@ "build:atom": "vite build --config resources/themes/atom/vite.config.js && php artisan optimize:clear && php artisan optimize && chown -R www-data:www-data public/build", "build:dusk": "vite build --config resources/themes/dusk/vite.config.js && php artisan optimize:clear && php artisan optimize && chown -R www-data:www-data public/build", "build:all": "vite build --config resources/themes/atom/vite.config.js && vite build --config resources/themes/dusk/vite.config.js && php artisan optimize:clear && php artisan optimize && chown -R www-data:www-data public/build", - "typecheck": "tsc --noEmit", "preview": "vite preview", - "format": "prettier \"resources/**/*.{js,ts,tsx,vue,blade}\" --ignore-unknown --write", - "format:check": "prettier \"resources/**/*.{js,ts,tsx,vue,blade.php}\" --check", - "lint": "eslint \"resources/js/\" --ext .ts,.tsx", - "lint:fix": "eslint \"resources/js/\" --ext .ts,.tsx --fix", + "format": "prettier \"resources/**/*.{js,ts,vue,blade}\" --ignore-unknown --write", + "format:check": "prettier \"resources/**/*.{js,ts,vue,blade.php}\" --check", + "lint": "eslint resources/js/", + "lint:fix": "eslint resources/js/ --fix", "lint:css": "stylelint \"resources/**/*.css\"", "lint:css:fix": "stylelint \"resources/**/*.css\" --fix", "lint:all": "yarn lint && yarn lint:css", "lint:fix:all": "yarn lint:fix && yarn lint:fix:css", - "check": "yarn typecheck && yarn lint:all && yarn format:check", + "check": "yarn lint:all && yarn format:check", "check:php": "php -l app/ && php -l routes/ && php -l database/ && php -l resources/", "check:security": "composer audit && npm audit", "check:deps": "npm outdated --long --json || true", @@ -34,17 +33,12 @@ "@tailwindcss/forms": "0.5.11", "@tailwindcss/postcss": "4.3.0", "@tailwindcss/typography": "0.5.19", - "@types/lodash": "^4.17.24", - "@types/react": "^19.2.17", - "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "^8.61.1", - "@typescript-eslint/parser": "^8.61.1", "alpinejs": "3.15.12", "autoprefixer": "10.5.0", "axios": "^1.17.0", "esbuild": "^0.28.0", "eslint": "^10.4.1", - "globals": "^17.6.0", + "eslint-plugin-vue": "10.9.2", "laravel-vite-plugin": "^3.1.0", "lodash": "^4.18.1", "postcss": "8.5.15", @@ -55,7 +49,6 @@ "stylelint-config-standard": "^40.0.0", "tailwindcss": "4.3.0", "turbolinks": "5.2.0", - "typescript": "^6.0.3", "vite": "^8.0.16" }, "dependencies": { diff --git a/public/build/manifest.json b/public/build/manifest.json index 7bc56e7..f7d8067 100644 --- a/public/build/manifest.json +++ b/public/build/manifest.json @@ -1,26 +1,15 @@ { - "_axios-BEkq_c61.js": { - "file": "assets/axios-BEkq_c61.js", + "_axios-Bb9VWCvi.js": { + "file": "assets/axios-Bb9VWCvi.js", "name": "axios", "imports": [ - "_chunk-b3L32Ng1.js" + "_chunk-QTnfLwEv.js" ] }, - "_chunk-b3L32Ng1.js": { - "file": "assets/chunk-b3L32Ng1.js", + "_chunk-QTnfLwEv.js": { + "file": "assets/chunk-QTnfLwEv.js", "name": "chunk" }, - "_swiper-Cjlszzo3.js": { - "file": "assets/swiper-Cjlszzo3.js", - "name": "swiper", - "css": [ - "assets/swiper-CrMA9oas.css" - ] - }, - "_swiper-CrMA9oas.css": { - "file": "assets/swiper-CrMA9oas.css", - "src": "_swiper-CrMA9oas.css" - }, "public/assets/images/background-dark.jpg": { "file": "assets/background-dark-BfkMu3-0.jpg", "src": "public/assets/images/background-dark.jpg" @@ -29,18 +18,6 @@ "file": "assets/background-light-CP7oKwVT.jpg", "src": "public/assets/images/background-light.jpg" }, - "public/assets/images/dusk/background_image.png": { - "file": "assets/background_image-BH7pVpv1.png", - "src": "public/assets/images/dusk/background_image.png" - }, - "public/assets/images/dusk/leaderboard_circle_image.png": { - "file": "assets/leaderboard_circle_image-BYkDVX69.png", - "src": "public/assets/images/dusk/leaderboard_circle_image.png" - }, - "public/assets/images/dusk/store_icon.png": { - "file": "assets/store_icon-B52tsSKO.png", - "src": "public/assets/images/dusk/store_icon.png" - }, "public/assets/images/icons/article.gif": { "file": "assets/article-CYhGsSKA.gif", "src": "public/assets/images/icons/article.gif" @@ -134,7 +111,7 @@ "src": "public/assets/images/profile/profile-bg.png" }, "resources/css/global.css": { - "file": "assets/global-CwMfkl9f.css", + "file": "assets/global-DmKtm1TC.css", "name": "global", "names": [ "global.css" @@ -169,27 +146,27 @@ "assets/community-Do_t1zw9.png" ] }, - "resources/js/global.ts": { - "file": "assets/global-B6tm4RcQ.js", + "resources/js/global.js": { + "file": "assets/global-r22-sRCc.js", "name": "global", - "src": "resources/js/global.ts", + "src": "resources/js/global.js", "isEntry": true, "imports": [ - "_chunk-b3L32Ng1.js", - "_axios-BEkq_c61.js" + "_chunk-QTnfLwEv.js", + "_axios-Bb9VWCvi.js" ] }, - "resources/js/ssr.tsx": { - "file": "assets/ssr-GVDc-G73.js", + "resources/js/ssr.jsx": { + "file": "assets/ssr-DdmZbD73.js", "name": "ssr", - "src": "resources/js/ssr.tsx", + "src": "resources/js/ssr.jsx", "isEntry": true, "imports": [ - "_chunk-b3L32Ng1.js" + "_chunk-QTnfLwEv.js" ] }, "resources/themes/atom/css/app.css": { - "file": "assets/app-BPKvU7LK.css", + "file": "assets/app-DtTGSxkD.css", "name": "app", "names": [ "app.css" @@ -224,56 +201,17 @@ "assets/community-Do_t1zw9.png" ] }, - "resources/themes/atom/js/app.ts": { - "file": "assets/app-evCrhLY1.js", + "resources/themes/atom/js/app.js": { + "file": "assets/app-CAkt-7PZ.js", "name": "app", - "src": "resources/themes/atom/js/app.ts", + "src": "resources/themes/atom/js/app.js", "isEntry": true, "imports": [ - "_chunk-b3L32Ng1.js", - "_swiper-Cjlszzo3.js", - "_axios-BEkq_c61.js" - ] - }, - "resources/themes/dusk/css/app.css": { - "file": "assets/app-CHSILL1f.css", - "name": "app", - "names": [ - "app.css" - ], - "src": "resources/themes/dusk/css/app.css", - "isEntry": true, - "assets": [ - "assets/background_image-BH7pVpv1.png", - "assets/feeds-BtHcJdHX.png", - "assets/chat-r5H1PnTg.png", - "assets/article-CYhGsSKA.gif", - "assets/lighthouse-BON6qnQ0.png", - "assets/store_icon-B52tsSKO.png", - "assets/catalog-D-956oDx.png", - "assets/inventory-BlHYLNGT.png", - "assets/due-chat-CeO4yxLu.png", - "assets/friends-BxpcKlvz.png", - "assets/credits-Dpg5Nmby.png", - "assets/duckets-CaGJI1Oy.png", - "assets/diamonds-BtfqKoQu.png", - "assets/trophy-gold-bbKmpkii.png", - "assets/trophy-silver-bGfHJkQ_.png", - "assets/trophy-bronze-CgV5j1MU.png", - "assets/leaderboard_circle_image-BYkDVX69.png" - ] - }, - "resources/themes/dusk/js/app.ts": { - "file": "assets/app-DKy1JARZ.js", - "name": "app", - "src": "resources/themes/dusk/js/app.ts", - "isEntry": true, - "imports": [ - "_swiper-Cjlszzo3.js", - "_axios-BEkq_c61.js" + "_chunk-QTnfLwEv.js", + "_axios-Bb9VWCvi.js" ], "css": [ - "assets/app-DU8Y3NnC.css" + "assets/app-CeYfhhVD.css" ] } } \ No newline at end of file diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js new file mode 100755 index 0000000..34478d4 --- /dev/null +++ b/resources/js/bootstrap.js @@ -0,0 +1,34 @@ +import _ from "lodash"; +window._ = _; + +/** + * We'll load the axios HTTP library which allows us to easily issue requests + * to our Laravel back-end. This library automatically handles sending the + * CSRF token as a header based on the value of the "XSRF" token cookie. + */ + +import axios from "axios"; +window.axios = axios; + +window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; + +/** + * Echo exposes an expressive API for subscribing to channels and listening + * for events that are broadcast by Laravel. Echo and event broadcasting + * allows your team to easily build robust real-time web applications. + */ + +// import Echo from 'laravel-echo'; + +// import Pusher from 'pusher-js'; +// window.Pusher = Pusher; + +// window.Echo = new Echo({ +// broadcaster: 'pusher', +// key: import.meta.env.VITE_PUSHER_APP_KEY, +// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`, +// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, +// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, +// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', +// enabledTransports: ['ws', 'wss'], +// }); diff --git a/resources/js/bootstrap.ts b/resources/js/bootstrap.ts deleted file mode 100755 index 11434e8..0000000 --- a/resources/js/bootstrap.ts +++ /dev/null @@ -1,6 +0,0 @@ -import _ from "lodash"; -import axios from "axios"; - -window._ = _; -window.axios = axios; -window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; diff --git a/resources/js/global.ts b/resources/js/global.js similarity index 100% rename from resources/js/global.ts rename to resources/js/global.js diff --git a/resources/js/pages/Home.jsx b/resources/js/pages/Home.jsx new file mode 100755 index 0000000..e0bf985 --- /dev/null +++ b/resources/js/pages/Home.jsx @@ -0,0 +1,31 @@ +import { Head } from '@inertiajs/react' + +export default function Home({ auth, hotelName }) { + return ( + <> + +
+
+

+ Welkom bij {hotelName} +

+

+ Dit is een Inertia.js pagina — zelfde layout, zelfde Tailwind, zelfde stijlen. +

+
+ + Naar huis + +
+
+
+ + ) +} diff --git a/resources/js/pages/Home.tsx b/resources/js/pages/Home.tsx deleted file mode 100755 index 34ce8c2..0000000 --- a/resources/js/pages/Home.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Head } from "@inertiajs/react"; - -interface HomeProps { - auth: Record; - hotelName: string; -} - -export default function Home({ hotelName }: HomeProps) { - return ( - <> - -
-
-

- Welkom bij {hotelName} -

-

- Dit is een Inertia.js pagina — zelfde layout, zelfde Tailwind, - zelfde stijlen. -

-
- - Naar huis - -
-
-
- - ); -} diff --git a/resources/js/pages/Index.jsx b/resources/js/pages/Index.jsx new file mode 100755 index 0000000..4d3a3fa --- /dev/null +++ b/resources/js/pages/Index.jsx @@ -0,0 +1,119 @@ +import { Head, usePage } from '@inertiajs/react' + +export default function Index({ articles, photos }) { + const { avatarImager } = usePage().props + + return ( + <> + + +
+
+
+ + + {photos.length > 0 && ( +
+
+
+
+
+

Laatste foto's

+

Bekijk de mooiste momenten vastgelegd door gebruikers.

+
+
+ + +
+ )} +
+ + ) +} diff --git a/resources/js/pages/Index.tsx b/resources/js/pages/Index.tsx deleted file mode 100755 index d361847..0000000 --- a/resources/js/pages/Index.tsx +++ /dev/null @@ -1,206 +0,0 @@ -import { Head, usePage } from "@inertiajs/react"; - -interface User { - look: string; - username: string; -} - -interface Article { - id: number; - slug: string; - title: string; - image: string; - user?: User; -} - -interface Photo { - id: number; - url: string; - user?: User; -} - -interface IndexProps { - articles: Article[]; - photos: Photo[]; -} - -interface SharedProps extends Record { - avatarImager: string; -} - -export default function Index({ articles, photos }: IndexProps) { - const { avatarImager } = usePage().props; - - return ( - <> - - -
-
-
-
-
-
-

- Laatste nieuws -

-

- Blijf op de hoogte van het laatste hotel nieuws. -

-
-
- - - - {photos.length > 0 && ( -
-
-
-
-
-

- Laatste foto's -

-

- Bekijk de mooiste momenten vastgelegd door gebruikers. -

-
-
- - -
- )} -
- - ); -} diff --git a/resources/js/ssr.jsx b/resources/js/ssr.jsx new file mode 100755 index 0000000..49ff5b1 --- /dev/null +++ b/resources/js/ssr.jsx @@ -0,0 +1,12 @@ +import { createInertiaApp } from '@inertiajs/react' +import { createRoot } from 'react-dom/client' + +createInertiaApp({ + resolve: name => { + const pages = import.meta.glob('./pages/**/*.jsx', { eager: true }) + return pages[`./pages/${name}.jsx`] + }, + setup({ el, App, props }) { + createRoot(el).render() + }, +}) diff --git a/resources/js/ssr.tsx b/resources/js/ssr.tsx deleted file mode 100755 index 9ceb0fc..0000000 --- a/resources/js/ssr.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { createInertiaApp } from "@inertiajs/react"; -import { createRoot } from "react-dom/client"; -import type { ComponentType } from "react"; - -createInertiaApp({ - resolve: (name: string) => { - const pages = import.meta.glob<{ default: ComponentType }>( - "./pages/**/*.tsx", - { eager: true }, - ); - return pages[`./pages/${name}.tsx`]; - }, - setup({ el, App, props }) { - createRoot(el).render(); - }, -}); diff --git a/resources/js/types.d.ts b/resources/js/types.d.ts deleted file mode 100644 index d1c49a9..0000000 --- a/resources/js/types.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -declare module "alpinejs" { - interface Alpine { - data(name: string, callback: (...args: unknown[]) => Record): void; - plugin(plugin: unknown): void; - start(): void; - } - const Alpine: Alpine; - export default Alpine; -} - -declare module "@alpinejs/focus" { - const focus: unknown; - export default focus; -} - -declare module "turbolinks" { - interface TurbolinksStatic { - start(): void; - } - const Turbolinks: TurbolinksStatic; - export default Turbolinks; -} - -interface Window { - _: import("lodash").default; - axios: import("axios").AxiosStatic; - App: { - defaultReactions: string[]; - isAuthenticated: boolean; - }; -} diff --git a/resources/themes/atom/js/app.js b/resources/themes/atom/js/app.js new file mode 100755 index 0000000..46cd354 --- /dev/null +++ b/resources/themes/atom/js/app.js @@ -0,0 +1,25 @@ +import "./bootstrap"; +import "./external/flowbite"; + +import "swiper/css"; +import "swiper/css/pagination"; + +import Alpine from "alpinejs"; +import Focus from "@alpinejs/focus"; + +import ArticleReactions from "./components/ArticleReactions.js"; + +import ThemeSwitcher from "./components/ThemeSwitcher.js"; +import AtomSliders from "./components/AtomSliders.js"; + +ThemeSwitcher.init(); +ArticleReactions.init(); +AtomSliders.init(); +Alpine.plugin(Focus); +Alpine.start(); + +console.log( + "%cAtom CMS%c\n\nAtom CMS is a CMS for made for the community to enjoy. You can join our wonderful community at https://discord.gg/rX3aShUHdg\n\n", + "color: #14619c; -webkit-text-stroke: 2px black; font-size: 32px; font-weight: bold;", + "", +); diff --git a/resources/themes/atom/js/app.ts b/resources/themes/atom/js/app.ts deleted file mode 100755 index 4101c2f..0000000 --- a/resources/themes/atom/js/app.ts +++ /dev/null @@ -1,18 +0,0 @@ -import "./bootstrap"; -import "./external/flowbite"; - -import "swiper/css"; -import "swiper/css/pagination"; - -import Alpine from "alpinejs"; -import Focus from "@alpinejs/focus"; - -import ArticleReactions from "./components/ArticleReactions"; -import ThemeSwitcher from "./components/ThemeSwitcher"; -import AtomSliders from "./components/AtomSliders"; - -ThemeSwitcher.init(); -ArticleReactions.init(); -AtomSliders.init(); -Alpine.plugin(Focus); -Alpine.start(); diff --git a/resources/themes/atom/js/bootstrap.js b/resources/themes/atom/js/bootstrap.js new file mode 100755 index 0000000..25ba4f6 --- /dev/null +++ b/resources/themes/atom/js/bootstrap.js @@ -0,0 +1,34 @@ +/** + * We'll load the axios HTTP library which allows us to easily issue requests + * to our Laravel back-end. This library automatically handles sending the + * CSRF token as a header based on the value of the "XSRF" token cookie. + */ + +import axios from "axios"; +import Turbolinks from "turbolinks"; + +window.axios = axios; +window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; + +Turbolinks.start(); + +/** + * Echo exposes an expressive API for subscribing to channels and listening + * for events that are broadcast by Laravel. Echo and event broadcasting + * allows your team to easily build robust real-time web applications. + */ + +// import Echo from 'laravel-echo'; + +// import Pusher from 'pusher-js'; +// window.Pusher = Pusher; + +// window.Echo = new Echo({ +// broadcaster: 'pusher', +// key: import.meta.env.VITE_PUSHER_APP_KEY, +// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_CLUSTER}.pusher.com`, +// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80, +// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443, +// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https', +// enabledTransports: ['ws', 'wss'], +// }); diff --git a/resources/themes/atom/js/bootstrap.ts b/resources/themes/atom/js/bootstrap.ts deleted file mode 100755 index 88f04f2..0000000 --- a/resources/themes/atom/js/bootstrap.ts +++ /dev/null @@ -1,7 +0,0 @@ -import axios from "axios"; -import Turbolinks from "turbolinks"; - -window.axios = axios; -window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; - -Turbolinks.start(); diff --git a/resources/themes/atom/js/components/ArticleReactions.js b/resources/themes/atom/js/components/ArticleReactions.js new file mode 100755 index 0000000..9163877 --- /dev/null +++ b/resources/themes/atom/js/components/ArticleReactions.js @@ -0,0 +1,131 @@ +import Alpine from "alpinejs"; + +const ArticleReactions = { + init() { + document.addEventListener("alpine:init", () => this.startComponent()); + }, + + startComponent() { + Alpine.data( + "reactions", + (myReactions = [], articleReactions = [], url = "") => ({ + url, + myReactions, + articleReactions, + allReactions: [], + isAuthenticated: false, + + init() { + this.treatArticleReactions(); + this.allReactions = window.App.defaultReactions; + this.isAuthenticated = window.App.isAuthenticated; + + this.dispatchFlowbiteEvent(); + }, + + treatArticleReactions() { + let articleReactions = this.articleReactions; + + this.articleReactions = []; + + Object.entries(articleReactions).forEach((reactionData) => { + let reactionName = reactionData[0], + reactions = Object.values(reactionData[1]); + + this.articleReactions.push({ + id: this.generateVirtualReactionId(reactionName), + name: reactionName, + count: reactions.length, + users: reactions.map((reaction) => reaction.user?.username ?? ""), + }); + }); + }, + + toggleReaction(reaction) { + if (!this.url.length || !this.isAuthenticated) return; + + axios.post(this.url, { reaction }).then((response) => { + if (!response.data.success) return; + + if (!response.data.added) { + this.removeReaction(reaction, response.data.username); + return; + } + + this.addReaction(reaction, response.data.username); + }); + }, + + addReaction(name, username) { + this.myReactions.push(name); + + let existingReaction = this.getReactionDataFromName(name); + + if (existingReaction) { + existingReaction.count++; + existingReaction.users.push(username); + return; + } + + this.articleReactions.push({ + id: this.generateVirtualReactionId(name), + name, + count: 1, + users: [username], + }); + + this.dispatchFlowbiteEvent(); + }, + + removeReaction(name, username) { + this.myReactions.splice(this.myReactions.indexOf(name), 1); + + let reactionData = this.getReactionDataFromName(name); + + if (reactionData.count > 1) { + reactionData.count--; + reactionData.users.splice(reactionData.users.indexOf(username), 1); + return; + } + + this.$nextTick(() => { + this.articleReactions.splice( + this.articleReactions.indexOf(reactionData), + 1, + ); + }); + }, + + generateVirtualReactionId(name) { + return name + Math.floor(Math.random() * 1000); + }, + + canAddReactionFromModal(name) { + return !this.userHasReaction(name) && !this.articleHasReaction(name); + }, + + userHasReaction(reaction) { + return this.myReactions.includes(reaction.name); + }, + + articleHasReaction(name) { + return typeof this.getReactionDataFromName(name) !== "undefined"; + }, + + getReactionDataFromName(name) { + return this.articleReactions.find( + (reaction) => reaction.name === name, + ); + }, + + dispatchFlowbiteEvent() { + this.$nextTick(() => + document.dispatchEvent(new CustomEvent("reactions:loaded")), + ); + }, + }), + ); + }, +}; + +export { ArticleReactions as default }; diff --git a/resources/themes/atom/js/components/ArticleReactions.ts b/resources/themes/atom/js/components/ArticleReactions.ts deleted file mode 100755 index 7ba0723..0000000 --- a/resources/themes/atom/js/components/ArticleReactions.ts +++ /dev/null @@ -1,147 +0,0 @@ -import Alpine from "alpinejs"; - -interface ReactionData { - id: string; - name: string; - count: number; - users: string[]; -} - -interface ReactionComponent extends Record { - url: string; - myReactions: string[]; - articleReactions: ReactionData[]; - allReactions: string[]; - isAuthenticated: boolean; - init(): void; - treatArticleReactions(rawReactions: Record): void; - toggleReaction(reaction: string): void; - addReaction(name: string, username: string): void; - removeReaction(name: string, username: string): void; - generateVirtualReactionId(name: string): string; - canAddReactionFromModal(name: string): boolean; - userHasReaction(reaction: ReactionData | string): boolean; - articleHasReaction(name: string): boolean; - getReactionDataFromName(name: string): ReactionData | undefined; - dispatchFlowbiteEvent(): void; - $nextTick: (callback: () => void) => void; -} - -const ArticleReactions = { - init() { - document.addEventListener("alpine:init", () => this.startComponent()); - }, - - startComponent() { - Alpine.data("reactions", (...args: unknown[]) => { - const [myReactions = [], , url = ""] = args as [string[], Record, string]; - const rawArticleReactions = args[1] as Record | undefined; - - return { - url, - myReactions: myReactions as string[], - articleReactions: [] as ReactionData[], - allReactions: [] as string[], - isAuthenticated: false, - - init(this: ReactionComponent) { - if (rawArticleReactions) { - this.treatArticleReactions(rawArticleReactions); - } - this.allReactions = window.App.defaultReactions; - this.isAuthenticated = window.App.isAuthenticated; - this.dispatchFlowbiteEvent(); - }, - - treatArticleReactions(this: ReactionComponent, raw: Record) { - const transformed: ReactionData[] = []; - - Object.entries(raw).forEach(([name, reactions]) => { - const values = Object.values(reactions); - transformed.push({ - id: this.generateVirtualReactionId(name), - name, - count: values.length, - users: values.map((r) => r.user?.username ?? ""), - }); - }); - - this.articleReactions = transformed; - }, - - toggleReaction(this: ReactionComponent, reaction: string) { - if (!this.url.length || !this.isAuthenticated) return; - - window.axios - .post(this.url, { reaction }) - .then((response: { data: { success: boolean; added: boolean; username: string } }) => { - if (!response.data.success) return; - if (!response.data.added) { - this.removeReaction(reaction, response.data.username); - return; - } - this.addReaction(reaction, response.data.username); - }); - }, - - addReaction(this: ReactionComponent, name: string, username: string) { - this.myReactions.push(name); - const existing = this.getReactionDataFromName(name); - if (existing) { - existing.count++; - existing.users.push(username); - return; - } - this.articleReactions.push({ - id: this.generateVirtualReactionId(name), - name, - count: 1, - users: [username], - }); - this.dispatchFlowbiteEvent(); - }, - - removeReaction(this: ReactionComponent, name: string, username: string) { - this.myReactions.splice(this.myReactions.indexOf(name), 1); - const data = this.getReactionDataFromName(name); - if (!data) return; - if (data.count > 1) { - data.count--; - data.users.splice(data.users.indexOf(username), 1); - return; - } - this.$nextTick(() => { - this.articleReactions.splice(this.articleReactions.indexOf(data), 1); - }); - }, - - generateVirtualReactionId(this: ReactionComponent, name: string): string { - return name + Math.floor(Math.random() * 1000); - }, - - canAddReactionFromModal(this: ReactionComponent, name: string): boolean { - return !this.userHasReaction(name) && !this.articleHasReaction(name); - }, - - userHasReaction(this: ReactionComponent, reaction: ReactionData | string): boolean { - const name = typeof reaction === "string" ? reaction : reaction.name; - return this.myReactions.includes(name); - }, - - articleHasReaction(this: ReactionComponent, name: string): boolean { - return typeof this.getReactionDataFromName(name) !== "undefined"; - }, - - getReactionDataFromName(this: ReactionComponent, name: string): ReactionData | undefined { - return this.articleReactions.find((r) => r.name === name); - }, - - dispatchFlowbiteEvent(this: ReactionComponent) { - this.$nextTick(() => document.dispatchEvent(new CustomEvent("reactions:loaded"))); - }, - } as ReactionComponent; - }); - }, -}; - -export { ArticleReactions as default }; diff --git a/resources/themes/atom/js/components/AtomSliders.ts b/resources/themes/atom/js/components/AtomSliders.js similarity index 83% rename from resources/themes/atom/js/components/AtomSliders.ts rename to resources/themes/atom/js/components/AtomSliders.js index be5a2de..afbf1fc 100755 --- a/resources/themes/atom/js/components/AtomSliders.ts +++ b/resources/themes/atom/js/components/AtomSliders.js @@ -1,11 +1,6 @@ import Swiper from "swiper"; -interface AtomSlidersStore { - init(): void; - initArticleSlider(): void; -} - -const AtomSliders: AtomSlidersStore = { +const AtomSliders = { init() { document.addEventListener("turbolinks:load", () => { this.initArticleSlider(); diff --git a/resources/themes/atom/js/components/ThemeSwitcher.ts b/resources/themes/atom/js/components/ThemeSwitcher.js similarity index 71% rename from resources/themes/atom/js/components/ThemeSwitcher.ts rename to resources/themes/atom/js/components/ThemeSwitcher.js index 4b4acaa..21683b9 100755 --- a/resources/themes/atom/js/components/ThemeSwitcher.ts +++ b/resources/themes/atom/js/components/ThemeSwitcher.js @@ -1,19 +1,10 @@ -type Theme = "light" | "dark"; - -interface ThemeSwitcherStore { - currentTheme: Theme; - init(): void; - initButton(): void; - toggleTheme(): void; -} - -const ThemeSwitcher: ThemeSwitcherStore = { +const ThemeSwitcher = { currentTheme: "light", init() { if ( localStorage.theme === "dark" || - (typeof window.matchMedia !== "undefined" && + (typeof window.matchMedia != "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches && localStorage.theme !== "light") ) { @@ -24,7 +15,7 @@ const ThemeSwitcher: ThemeSwitcherStore = { }, initButton() { - const themeSwitcher = document.getElementById("theme-switcher"); + let themeSwitcher = document.getElementById("theme-switcher"); themeSwitcher?.addEventListener("click", () => this.toggleTheme()); }, diff --git a/resources/themes/atom/views/client/nitro.blade.php b/resources/themes/atom/views/client/nitro.blade.php index 5d2a66e..bc3d232 100755 --- a/resources/themes/atom/views/client/nitro.blade.php +++ b/resources/themes/atom/views/client/nitro.blade.php @@ -9,7 +9,7 @@ - @vite(['resources/themes/' . setting('theme') . '/css/app.css', 'resources/themes/' . setting('theme') . '/js/app.ts'], 'build') + @vite(['resources/themes/' . setting('theme') . '/css/app.css', 'resources/themes/' . setting('theme') . '/js/app.js'], 'build')