From ee90542ec94ea17b4ed18d4239786399923e562c Mon Sep 17 00:00:00 2001 From: root Date: Thu, 24 Oct 2024 19:48:09 +0000 Subject: [PATCH] more stuff added a new script and fixed the navbar in tailwind instead of css but having problems with getting prettier to work (probs because of biome) --- .prettierignore | 2 + .prettierrc | 10 + biome.json | 2 +- package-lock.json | 22 +- package.json | 5 +- settings.json | 4 + src/App.tsx | 454 ++++++++++++------------- src/index.css | 14 +- src/index.tsx | 20 +- src/routes/admin/Admin.css | 72 +--- src/routes/admin/Admin.tsx | 87 ++--- src/routes/admin/news/Create.tsx | 4 +- src/routes/admin/news/News.tsx | 162 ++++----- src/routes/admin/songs/Songs.tsx | 546 ++++++++++++++++++++----------- src/routes/admin/test/Test.tsx | 15 +- 15 files changed, 765 insertions(+), 654 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 settings.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..971b5a8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +public +AdminViewPdfs \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..bddfd39 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,10 @@ +{ + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindConfig": "./tailwind.config.js", + "tabWidth": 2, + "useTabs": true, + "singleQuote": false, + "jsxSingleQuote": false, + "trailingComma": "es5", + "semi": true +} diff --git a/biome.json b/biome.json index 36a2658..0ac02b3 100644 --- a/biome.json +++ b/biome.json @@ -10,7 +10,7 @@ "ignore": ["./src/api"] }, "formatter": { - "enabled": true, + "enabled": false, "indentStyle": "tab" }, "organizeImports": { diff --git a/package-lock.json b/package-lock.json index 03148f8..e0bc8a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.23.1", - "sort-by": "^1.2.0", + "sort-by": "^0.0.2", "tailwindcss": "^3.4.14" }, "devDependencies": { @@ -4459,15 +4459,6 @@ "node": ">= 6" } }, - "node_modules/object-path": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.6.0.tgz", - "integrity": "sha512-fxrwsCFi3/p+LeLOAwo/wyRMODZxdGBtUlWRzsEpsUVrisZbEfZ21arxLGfaWfcnqb8oHPNihIb4XPE8CQPN5A==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/ohash": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", @@ -5309,13 +5300,10 @@ } }, "node_modules/sort-by": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sort-by/-/sort-by-1.2.0.tgz", - "integrity": "sha512-aRyW65r3xMnf4nxJRluCg0H/woJpksU1dQxRtXYzau30sNBOmf5HACpDd9MZDhKh7ALQ5FgSOfMPwZEtUmMqcg==", - "license": "MIT", - "dependencies": { - "object-path": "0.6.0" - } + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/sort-by/-/sort-by-0.0.2.tgz", + "integrity": "sha512-iOX5oHA4a0eqTMFiWrHYqv924UeRKFBLhym7iwSVG37Egg2wApgZKAjyzM9WZjMwKv6+8Zi+nIaJ7FYsO9EkoA==", + "license": "MIT" }, "node_modules/source-map": { "version": "0.6.1", diff --git a/package.json b/package.json index cfb9cdc..8cce23e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "build": "tsc && vite build", "lint": "biome lint --write ./src", "preview": "vite preview", - "generate-api": "openapi-ts" + "generate-api": "openapi-ts", + "format": "prettier --write src/**/*.{js,jsx,ts,tsx,css,html}" }, "dependencies": { "@hey-api/client-fetch": "^0.4.0", @@ -17,7 +18,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.23.1", - "sort-by": "^1.2.0", + "sort-by": "^0.0.2", "tailwindcss": "^3.4.14" }, "devDependencies": { diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..d1b4edb --- /dev/null +++ b/settings.json @@ -0,0 +1,4 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index dfdb0c2..d8c7f13 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,174 +1,174 @@ import "./App.css"; function App() { - return ( -
-
- ); + return ( +
+
+ ); } export default App; function Nav() { - return ( - <> - - - ); + {/* Mobile menu, show/hide based on menu state. */} +
+
+ {/* Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" */} + + Dashboard + + + Team + + + Projects + + + Calendar + +
+
+ + + ); } diff --git a/src/index.css b/src/index.css index 46dfb6b..fc4a0b9 100644 --- a/src/index.css +++ b/src/index.css @@ -3,10 +3,10 @@ @tailwind utilities; :root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - --wavelength-612-color: #FF5700; - --wavelength-612-color-light: #FF7F33; - --wavelength-612-color-dark: #CC4700; -} \ No newline at end of file + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + --wavelength-612-color: #ff5700; + --wavelength-612-color-light: #ff7f33; + --wavelength-612-color-dark: #cc4700; +} diff --git a/src/index.tsx b/src/index.tsx index b5abbaf..5ddd38b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -6,7 +6,7 @@ import "./index.css"; import AdminPage from "./routes/admin/Admin"; import { AuthService, client } from "./api"; -client.setConfig({baseUrl: "http://127.0.0.1:8000"}) +client.setConfig({ baseUrl: "http://127.0.0.1:8000" }); const token = await AuthService.authJwtLogin({ body: { username: "boss@fsektionen.se", password: "dabdab" }, @@ -14,9 +14,12 @@ const token = await AuthService.authJwtLogin({ const myHeaders = new Headers(); -myHeaders.append("Authorization", `${token.data!.token_type} ${token.data!.access_token}`) +myHeaders.append( + "Authorization", + `${token.data!.token_type} ${token.data!.access_token}` +); -client.setConfig({headers: myHeaders}) +client.setConfig({ headers: myHeaders }); // OpenAPI.interceptors.request.use((request) => { // (request.headers as Headers).set( @@ -38,11 +41,12 @@ const router = createBrowserRouter([ }, ]); -const rootElement = document.getElementById('root'); +const rootElement = document.getElementById("root"); if (rootElement) { const root = ReactDOM.createRoot(rootElement); - root.render( - - ,) + root.render( + + + + ); } - diff --git a/src/routes/admin/Admin.css b/src/routes/admin/Admin.css index 3602e75..3ace0d6 100644 --- a/src/routes/admin/Admin.css +++ b/src/routes/admin/Admin.css @@ -1,72 +1,8 @@ -.sidebar { - display: block; - text-align: left; - background-color: var(--wavelength-612-color); - max-width: 10%; - height: 100vh; - flex-grow: 1; - overflow-y: auto; -} - -.sidebar a, -.sidebar button { - text-align: left; - display: inline-block; - box-sizing: border-box; - background: none; - padding: 10px; - height: auto; - width: 100%; - border: none; - cursor: pointer; -} - -/* Styles for the second sidebar */ -.second-sidebar { - display: block; - text-align: left; - background-color: lightgray; - max-width: 15%; - height: 100vh; - position: absolute; - left: 10%; - /* Position it next to the main sidebar */ - top: 0; - overflow-y: auto; - z-index: 1000; - /* Ensure it is above other content */ -} - -.second-sidebar a { - text-align: left; - display: inline-block; - box-sizing: border-box; - background: none; - padding: 10px; - height: auto; - width: 100%; -} - -.content { - text-align: left; - padding: 10px; - margin-left: 5%; - /* Default margin for when only the main sidebar is open */ - transition: margin-left 0.3s; - /* Smooth transition */ -} - -/* Adjust the margin when the second sidebar is open */ -body.second-sidebar-open .content { - margin-left: 15%; - /* Adjust to accommodate both sidebars */ -} - #root { - all: unset; - display: flex; + all: unset; + display: flex; } body { - all: unset; -} \ No newline at end of file + all: unset; +} diff --git a/src/routes/admin/Admin.tsx b/src/routes/admin/Admin.tsx index e60f1a2..570d000 100644 --- a/src/routes/admin/Admin.tsx +++ b/src/routes/admin/Admin.tsx @@ -1,51 +1,58 @@ - -import { useState, useEffect } from "react"; +import { useState } from "react"; import { Link, Route, Routes } from "react-router-dom"; import Landing from "./Landing"; import News from "./news/News"; import Songs from "./songs/Songs"; -import "./Admin.css"; import Test from "./test/Test"; export default function AdminPage() { - // State to manage the visibility of the second sidebar - const [isSecondSidebarOpen, setIsSecondSidebarOpen] = useState(false); + // State to manage which dropdown is open + const [openDropdown, setOpenDropdown] = useState(false); + + // Function to toggle the visibility of the dropdown + const toggleDropdown = () => { + setOpenDropdown(!openDropdown); + }; - // Function to toggle the visibility - const toggleSecondSidebar = () => { - setIsSecondSidebarOpen(!isSecondSidebarOpen); - }; + return ( +
+ {/* Sidebar */} +
+ + Home + + + Test + + - // Add or remove a class on the body element based on the state - useEffect(() => { - if (isSecondSidebarOpen) { - document.body.classList.add("second-sidebar-open"); - } else { - document.body.classList.remove("second-sidebar-open"); - } - }, [isSecondSidebarOpen]); + {/* Dropdown Menu */} + {openDropdown && ( +
+ + Nyheter + + + Sånger + +
+ )} +
- return ( - <> -
- Home - Test - -
- {isSecondSidebarOpen && ( -
- Nyheter - Sånger -
- )} -
- - } /> - } /> - } /> - } /> - -
- - ); + {/* Content */} +
+ + } /> + } /> + } /> + } /> + +
+
+ ); } diff --git a/src/routes/admin/news/Create.tsx b/src/routes/admin/news/Create.tsx index 8784862..9bc3b09 100644 --- a/src/routes/admin/news/Create.tsx +++ b/src/routes/admin/news/Create.tsx @@ -47,7 +47,9 @@ function NewsItem(newsItem?: NewsRead) { setNews((prev) => ({ ...prev, content_sv: c.target.value })) } /> - + ); } diff --git a/src/routes/admin/news/News.tsx b/src/routes/admin/news/News.tsx index c95c1cc..2fe773a 100644 --- a/src/routes/admin/news/News.tsx +++ b/src/routes/admin/news/News.tsx @@ -3,90 +3,94 @@ import { Create } from "./Create"; import { type NewsRead, NewsService } from "../../../api"; export interface NewsItem { - title: string; - creator: string; - dateCreated: string; - id: number; + title: string; + creator: string; + dateCreated: string; + id: number; } export default function News() { - const [news, setNews] = useState>([]); - const [loading, setLoading] = useState(true); + const [news, setNews] = useState>([]); + const [loading, setLoading] = useState(true); - useEffect(() => { - // Fetch news data when the component mounts - const fetchNews = async () => { - try { - const response = await NewsService.getAllNews(); - setNews(response.data || []); - } catch (error) { - console.error("Error fetching news:", error); - } finally { - setLoading(false); - } - }; + useEffect(() => { + // Fetch news data when the component mounts + const fetchNews = async () => { + try { + const response = await NewsService.getAllNews(); + setNews(response.data || []); + } catch (error) { + console.error("Error fetching news:", error); + } finally { + setLoading(false); + } + }; - fetchNews(); - }, []); + fetchNews(); + }, []); - if (loading) { - return

Loading...

; - } + if (loading) { + return

Loading...

; + } - return ( -
-

Administrera nyheter

-

- Här kan du skapa nyheter & redigera existerande nyheter på hemsidan. -

-
- - -
-

Senaste nyheter

- - - - - - - - - - - {news.map((newsItem, index) => ( - - - - - - - ))} - -
TitelSkapareDatum skapadRedigera
{newsItem.title_sv}{newsItem.author_id} - {new Date(newsItem.created_at).toLocaleDateString()} - - -
- -
- ); + return ( +
+

+ Administrera nyheter +

+

+ Här kan du skapa nyheter & redigera existerande nyheter på hemsidan. +

+
+ + +
+

+ Senaste nyheter +

+ + + + + + + + + + + {news.map((newsItem, index) => ( + + + + + + + ))} + +
TitelSkapareDatum skapadRedigera
{newsItem.title_sv}{newsItem.author_id} + {new Date(newsItem.created_at).toLocaleDateString()} + + +
+ +
+ ); } diff --git a/src/routes/admin/songs/Songs.tsx b/src/routes/admin/songs/Songs.tsx index 9b2388f..c49294b 100644 --- a/src/routes/admin/songs/Songs.tsx +++ b/src/routes/admin/songs/Songs.tsx @@ -1,212 +1,368 @@ import React, { useEffect, useState } from "react"; import "../Admin.css"; -import { SongCreate, SongsGetAllSongsResponse, SongsService } from "../../../api"; // Justera din importväg efter behov +import { + SongCreate, + SongsGetAllSongsResponse, + SongsService, +} from "../../../api"; // Adjust your import path as needed // Main Songs Component export default function Songs() { - const [songs, setSongs] = useState([]); // Ändrat från null till tom array - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const [showAddForm, setShowAddForm] = useState(false); // State för att visa/inte visa formuläret - const [newSong, setNewSong] = useState({ - title: "", - author: "", // Bytt från 'author' till 'artist' för konsistens - melody: "", // Använd tom sträng istället för null - content: "", // Tom sträng eller standardvärde - category: { id: 1, name: "SNELA" } // Förutsatt att detta är ett giltigt standardvärde - // Lägg till andra fält med tomma värden om det behövs - }); + const [songs, setSongs] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [showAddForm, setShowAddForm] = useState(false); + const [showUpdateForm, setShowUpdateForm] = useState(false); + const [newSong, setNewSong] = useState({ + title: "", + author: "", + melody: "", + content: "", + category: { id: 1, name: "SNELA" }, + }); + useEffect(() => { + const fetchSongs = async () => { + try { + const response = await SongsService.getAllSongs(); + const fetchedSongs = response.data ?? []; + setSongs(fetchedSongs); + } catch (error) { + console.error("Failed to fetch songs:", error); + setError("Failed to fetch songs. Please try again later."); + } finally { + setLoading(false); + } + }; - useEffect(() => { - console.log("useEffect executed"); // Kontrollera om useEffect körs - const fetchSongs = async () => { - console.log("fetchSongs called"); // Kontrollera om fetchSongs anropas - try { - const response = await SongsService.getAllSongs(); - console.log("API response:", response); // Logga hela svaret - const fetchedSongs = response.data ?? []; - console.log("Fetched song data:", fetchedSongs); // Logga de hämtade låtarna - setSongs(fetchedSongs); - } catch (error) { - console.error("Failed to fetch songs:", error); - setError("Failed to fetch songs. Please try again later."); - } finally { - setLoading(false); - } - }; + fetchSongs(); + }, []); - fetchSongs(); - }, []); + const handleAddButtonClick = () => { + setShowAddForm(!showAddForm); + }; + + const handleUpdateButtonClick = () => { + setShowUpdateForm(!showUpdateForm) + }; - const handleAddButtonClick = () => { - setShowAddForm(true); - }; + const handleFormChange = ( + e: React.ChangeEvent + ) => { + const { name, value } = e.target; + setNewSong((prev) => ({ + ...prev, + [name]: value, + })); + }; - const handleFormChange = (e: React.ChangeEvent) => { - const { name, value } = e.target; - setNewSong((prev) => ({ - ...prev, - [name]: value, - })); - }; + const handleFormSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const response = await SongsService.createSong({ body: newSong }); + if (response.data) { + setSongs((prevSongs) => [...prevSongs, response.data]); + setShowAddForm(false); + setNewSong({ + title: "", + author: "", + melody: "", + content: "", + category: { id: 1, name: "SNELA" }, + }); + } else { + throw new Error("Response data is undefined"); + } + } catch (error) { + console.error("Failed to add song:", error); + setError("Failed to add song. Please try again."); + } + }; + + const handleCancel = () => { + setShowAddForm(false); + setNewSong({ + title: "", + author: "", + melody: "", + content: "", + category: { id: 1, name: "SNELA" }, + }); + }; - const handleFormSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - const response = await SongsService.createSong({ body: newSong }); // Ändrat från createSong till addSong, justera efter din API-metod - if (response.data) { // Säkerställ att response.data är definierad - console.log("Added song:", response.data); - setSongs((prevSongs) => [...prevSongs, response.data]); - setShowAddForm(false); - setNewSong({ - title: "", - author: "", - melody: "", - content: "", - category: { id: 1, name: "SNELA" } - }); // Återställ alla fält - } else { - throw new Error("Response data is undefined"); - } - } catch (error) { - console.error("Failed to add song:", error); - setError("Failed to add song. Please try again."); - } - }; + // Conditional rendering based on the loading, error, and data state + if (loading) return

Loading...

; + if (error) return

{error}

; - const handleCancel = () => { - setShowAddForm(false); - setNewSong({ - title: "", - author: "", - melody: "", - content: "", - category: { id: 1, name: "SNELA" } - }); // Återställ alla fält - }; + if (showAddForm) { + return ( +
+

Lägg till ny låt

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ); + } - // Conditional rendering based on the loading, error, and data state - if (loading) return

Loading...

; - if (error) return

{error}

; + if (showUpdateForm) { + return ( +
+

Updatera låt

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ); + } - return ( -
-

Administrera sånger

-

Här kan du skapa nyheter & redigera existerande sånger på hemsidan.

+ return ( +
+

+ Administrera sånger +

+

+ Här kan du skapa nyheter & redigera existerande sånger på hemsidan. +

-
- - -
- {/* Lägg till formuläret för att skapa en ny låt */} - {showAddForm && ( -
-

Lägg till ny låt

-
- - -
-
- {/* Ändrat från 'author' till 'artist' */} - -
-
- - -
-
- - -
-
- - {/* Om kategorin är statisk kan du använda ett select-fält */} - -
-
- - -
-
- )} -

Sånginformation

+
+ + +
- {/* Render the song details */} - - - - - - - - - - - - {songs.map((song) => ( - - - {/* Ändrat från song.author till song.artist om nödvändigt */} - - - - - ))} - -
TitelArtistIdLyssningarÅtgärd
{song.title}{song.author}{song.id}{song.views} - -
-
- ); +

+ Sånginformation +

+ + + + + + + + + + + + {songs.map((song) => ( + + + + + + + + ))} + +
TitelArtistIdLyssningarÅtgärd
{song.title}{song.author}{song.id}{song.views} + +
+
+ ); } diff --git a/src/routes/admin/test/Test.tsx b/src/routes/admin/test/Test.tsx index 5c5127a..e6225ff 100644 --- a/src/routes/admin/test/Test.tsx +++ b/src/routes/admin/test/Test.tsx @@ -1,10 +1,7 @@ - - export default function Test() { - - return ( -
-

Hejsan

-
- ); -} \ No newline at end of file + return ( +
+

Hejsan

+
+ ); +}