diff --git a/.eslintrc.cjs b/.eslintrc.cjs index d6c9537..30af7ce 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,18 +1,18 @@ module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], - }, -} + root: true, + env: { browser: true, es2020: true }, + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended", + ], + ignorePatterns: ["dist", ".eslintrc.cjs"], + parser: "@typescript-eslint/parser", + plugins: ["react-refresh"], + rules: { + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, +}; diff --git a/package.json b/package.json index 5c54a08..fe549cd 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,45 @@ { - "name": "triggerfrontend", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" - }, - "dependencies": { - "@emotion/react": "^11.13.0", - "@iconify/react": "^5.0.2", - "@mantine/core": "^7.12.1", - "@mantine/dates": "^7.12.1", - "@mantine/form": "^7.12.1", - "@mantine/hooks": "^7.12.1", - "@mantine/modals": "^7.12.1", - "@tabler/icons-react": "^3.12.0", - "@tanstack/react-query": "^5.51.23", - "clsx": "^2.1.1", - "dayjs": "^1.11.12", - "jotai": "^2.9.3", - "mantine-react-table": "^2.0.0-beta.6", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-icons": "^5.3.0", - "react-query": "^3.39.3", - "react-router-dom": "^6.26.0", - "react-toastify": "^10.0.5" - }, - "devDependencies": { - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^8.1.0", - "@typescript-eslint/parser": "^8.1.0", - "@vitejs/plugin-react": "^4.3.1", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.9", - "typescript": "^5.5.4", - "vite": "^5.4.0" - } + "name": "triggerfrontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.13.0", + "@iconify/react": "^5.0.2", + "@mantine/core": "^7.12.1", + "@mantine/dates": "^7.12.1", + "@mantine/form": "^7.12.1", + "@mantine/hooks": "^7.12.1", + "@mantine/modals": "^7.12.1", + "@tabler/icons-react": "^3.12.0", + "@tanstack/react-query": "^5.51.23", + "clsx": "^2.1.1", + "dayjs": "^1.11.12", + "jotai": "^2.9.3", + "mantine-react-table": "^2.0.0-beta.6", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-icons": "^5.3.0", + "react-query": "^3.39.3", + "react-router-dom": "^6.26.0", + "react-toastify": "^10.0.5" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/parser": "^8.1.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^9.9.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.9", + "typescript": "^5.5.4", + "vite": "^5.4.0" + } } diff --git a/src/App.tsx b/src/App.tsx index cfedfdc..59113e2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,66 +1,76 @@ -import Homepage from './pages/homepage/Homepage' -import { MantineProvider, DEFAULT_THEME, createTheme, mergeMantineTheme } from '@mantine/core' +import Homepage from "./pages/homepage/Homepage"; +import { + MantineProvider, + DEFAULT_THEME, + createTheme, + mergeMantineTheme, +} from "@mantine/core"; import { Route, createBrowserRouter, createRoutesFromElements, RouterProvider, } from "react-router-dom"; -import Settings from './pages/settings/Settings'; -import { ModalsProvider } from '@mantine/modals'; -import { useLocalStorage } from '@mantine/hooks'; -import { useEffect, useState } from 'react'; -import { useQueryAPI } from './hooks/useAPI'; -import ThemeProvider from './components/ThemeProvider'; -import '@mantine/core/styles.css'; //import Mantine V7 styles needed by MRT -import '@mantine/dates/styles.css'; //if using mantine date picker features -import 'mantine-react-table/styles.css'; //import MRT styles +import Settings from "./pages/settings/Settings"; +import { ModalsProvider } from "@mantine/modals"; +import { useLocalStorage } from "@mantine/hooks"; +import { useEffect, useState } from "react"; +import { useQueryAPI } from "./hooks/useAPI"; +import ThemeProvider from "./components/ThemeProvider"; +import "@mantine/core/styles.css"; //import Mantine V7 styles needed by MRT +import "@mantine/dates/styles.css"; //if using mantine date picker features +import "mantine-react-table/styles.css"; //import MRT styles function App() { - - const { data, isFetched } = useQueryAPI({ + const { data, isFetched } = useQueryAPI({ endpoint: "api/themes", }); - const [themeName, setThemeName] = useLocalStorage({ - key: 'theme', - defaultValue: 'blackboard', + const [themeName, setThemeName] = useLocalStorage({ + key: "theme", + defaultValue: "blackboard", }); - const [currentTheme, setCurrentTheme] = useState({}); + const [currentTheme, setCurrentTheme] = useState({}); - const overrides = createTheme({ - white:currentTheme.colorbackground, - fontFamily: '-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif', - }); + const overrides = createTheme({ + white: currentTheme.colorbackground, + fontFamily: + "-apple-system,Jost,BlinkMacSystemFont,Helvetica Neue,Roboto,sans-serif", + }); - const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides); + const mantineTheme = mergeMantineTheme(DEFAULT_THEME, overrides); - useEffect(() => { - if(data && themeName) { - let temp = data.find((t: any) => t.name === themeName) - setCurrentTheme(temp); - } - }, [isFetched, themeName]) + useEffect(() => { + if (data && themeName) { + const temp = data.find((t: any) => t.name === themeName); + setCurrentTheme(temp); + } + }, [isFetched, themeName]); - const router = createBrowserRouter( + const router = createBrowserRouter( createRoutesFromElements( } /> - } /> + } + /> , ), ); - return ( - - - - - - - - ) + return ( + + {currentTheme && ( + + + + + + )} + + ); } -export default App +export default App; diff --git a/src/DataTable/DataTable.tsx b/src/DataTable/DataTable.tsx index 17a1758..ad015a3 100644 --- a/src/DataTable/DataTable.tsx +++ b/src/DataTable/DataTable.tsx @@ -1,17 +1,17 @@ -import { MantineReactTable, useMantineReactTable } from "mantine-react-table" +import { MantineReactTable, useMantineReactTable } from "mantine-react-table"; import { memo } from "react"; +import "../dataTableStyles.css"; export function DataTableComponent({ - columns, - tableData, - isFetching, - isLoading, + columns, + tableData, + isFetching, + isLoading, onCreatingRowSave, onEditingRowSave, }: any) { - - const table = useMantineReactTable({ - columns: columns, + const table = useMantineReactTable({ + columns: columns, data: tableData, enableFacetedValues: true, enablePagination: false, @@ -34,59 +34,23 @@ export function DataTableComponent({ showLoadingOverlay: isLoading, isLoading: isLoading, }, - // mantineToolbarAlertBannerBadgeProps: { - // style: { - // color: "red", - // }, - // }, - // mantineTopToolbarProps: { - // style: { - // color: "var(--color-text-pri)", - // background: "var(--color-background)", - // border: "none", - // boxShadow: "none", - // }, - // }, - // mantineTableHeadProps: { - // style: { - // boxShadow: "none", - // }, - // }, - // mantineTableHeadCellProps: { - // style: { - // color: "var(--color-text-pri)", - // background: "var(--color-background)", - // borderRight: "none", - // borderLeft: "none", - // }, - // }, - // mantineTableBodyCellProps: { - // style: { - // background: "var(--color-background)", - // borderRight: "none", - // borderLeft: "none", - // }, - // }, - // mantinePaperProps: { - // style: { - // border: "none", - // boxShadow: "none", - // background: "var(--color-background)", - // }, - // }, - // mantineTableContainerProps: { - // style: { - // border: "none", - // boxShadow: "none", - // background: "var(--color-background)", - // }, - // }, + mantineTableHeadProps: { + style: { + color: "var(--color-text-pri)", + }, + }, + mantineTableBodyCellProps: { + style: { + color: "var(--color-text-pri)", + background: "var(--color-background)", + borderRight: "none", + borderLeft: "none", + }, + }, }); - return ( - - ); + return ; } export const DataTable = memo(DataTableComponent); -export default DataTable; \ No newline at end of file +export default DataTable; diff --git a/src/DataTable/columns/ApplicationColumns.tsx b/src/DataTable/columns/ApplicationColumns.tsx index 8304424..ebfaec4 100644 --- a/src/DataTable/columns/ApplicationColumns.tsx +++ b/src/DataTable/columns/ApplicationColumns.tsx @@ -2,14 +2,14 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function ApplicationColumns() { - const columns = useMemo[]>( + const columns = useMemo[]>( () => [ { accessorFn: (row) => { if (row.id) { return `${row.id}`; } - return ""; + return ""; }, enableEditing: false, id: "id", @@ -27,7 +27,7 @@ export default function ApplicationColumns() { if (row.name) { return `${row.name}`; } - return ""; + return ""; }, id: "name", header: "Name", @@ -43,7 +43,7 @@ export default function ApplicationColumns() { if (row.url) { return `${row.url}`; } - return ""; + return ""; }, id: "url", header: "Url", @@ -59,7 +59,7 @@ export default function ApplicationColumns() { if (row.icon) { return `${row.icon}`; } - return ""; + return ""; }, id: "icon", header: "Icon", @@ -75,7 +75,7 @@ export default function ApplicationColumns() { if (row.urlbase) { return `${row.urlbase}`; } - return ""; + return ""; }, id: "urlbase", header: "Base Url", @@ -91,7 +91,7 @@ export default function ApplicationColumns() { if (row.category) { return `${row.category}`; } - return ""; + return ""; }, id: "category", header: "Category", @@ -106,6 +106,5 @@ export default function ApplicationColumns() { [], ); - return columns; + return columns; } - diff --git a/src/DataTable/columns/BookmarkColumns.tsx b/src/DataTable/columns/BookmarkColumns.tsx index 1956123..6bfe615 100644 --- a/src/DataTable/columns/BookmarkColumns.tsx +++ b/src/DataTable/columns/BookmarkColumns.tsx @@ -2,14 +2,14 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function ApplicationColumns(groups: any, groupData: any) { - const columns = useMemo[]>( + const columns = useMemo[]>( () => [ { accessorFn: (row) => { if (row.id) { return `${row.id}`; } - return ""; + return ""; }, enableEditing: false, id: "id", @@ -27,7 +27,7 @@ export default function ApplicationColumns(groups: any, groupData: any) { if (row.name) { return `${row.name}`; } - return ""; + return ""; }, id: "name", header: "Name", @@ -43,7 +43,7 @@ export default function ApplicationColumns(groups: any, groupData: any) { if (row.url) { return `${row.url}`; } - return ""; + return ""; }, id: "url", header: "Url", @@ -60,7 +60,7 @@ export default function ApplicationColumns(groups: any, groupData: any) { if (index !== null && index !== undefined) { return `${index}`; } - return "N/A"; + return "N/A"; }, id: "category", header: "Category", @@ -78,6 +78,5 @@ export default function ApplicationColumns(groups: any, groupData: any) { [groups], ); - return columns; + return columns; } - diff --git a/src/DataTable/columns/CategoryColumns.tsx b/src/DataTable/columns/CategoryColumns.tsx index fcc466e..b9a8ccf 100644 --- a/src/DataTable/columns/CategoryColumns.tsx +++ b/src/DataTable/columns/CategoryColumns.tsx @@ -2,14 +2,14 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function CategoryColumns() { - const columns = useMemo[]>( + const columns = useMemo[]>( () => [ { accessorFn: (row) => { if (row.id) { return `${row.id}`; } - return ""; + return ""; }, enableEditing: false, id: "id", @@ -18,12 +18,12 @@ export default function CategoryColumns() { Cell: ({ renderedCellValue, row }) => renderedCellValue, Header: ({ column }) => column.columnDef.header, }, - { + { accessorFn: (row) => { if (row.category_name) { return `${row.category_name}`; } - return ""; + return ""; }, id: "category_name", header: "Name", @@ -31,12 +31,12 @@ export default function CategoryColumns() { Cell: ({ renderedCellValue, row }) => renderedCellValue, Header: ({ column }) => column.columnDef.header, }, - { + { accessorFn: (row) => { if (row.category_index > -1) { return `${row.category_index}`; } - return ""; + return ""; }, enableEditing: false, id: "category_index", @@ -45,12 +45,12 @@ export default function CategoryColumns() { Cell: ({ renderedCellValue, row }) => renderedCellValue, Header: ({ column }) => column.columnDef.header, }, - { + { accessorFn: (row) => { if (row.column_filter) { return `${row.column_filter}`; } - return ""; + return ""; }, id: "column_filter", header: "Filter Name", @@ -62,6 +62,5 @@ export default function CategoryColumns() { [], ); - return columns; + return columns; } - diff --git a/src/DataTable/columns/MessagesColumns.tsx b/src/DataTable/columns/MessagesColumns.tsx index 7438d32..7d9b6e7 100644 --- a/src/DataTable/columns/MessagesColumns.tsx +++ b/src/DataTable/columns/MessagesColumns.tsx @@ -2,14 +2,14 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function MessagesColumns() { - const columns = useMemo[]>( + const columns = useMemo[]>( () => [ { accessorFn: (row) => { if (row.id) { return `${row.id}`; } - return ""; + return ""; }, enableEditing: false, id: "id", @@ -27,7 +27,7 @@ export default function MessagesColumns() { if (row.message) { return `${row.message}`; } - return ""; + return ""; }, id: "message", header: "Message", @@ -43,7 +43,7 @@ export default function MessagesColumns() { if (row.easteregg) { return `${row.easteregg}`; } - return ""; + return ""; }, id: "easteregg", header: "Easter Egg?", @@ -58,6 +58,5 @@ export default function MessagesColumns() { [], ); - return columns; + return columns; } - diff --git a/src/DataTable/columns/PersonalizationColumns.tsx b/src/DataTable/columns/PersonalizationColumns.tsx index 25a05b7..1572e13 100644 --- a/src/DataTable/columns/PersonalizationColumns.tsx +++ b/src/DataTable/columns/PersonalizationColumns.tsx @@ -2,61 +2,60 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function PersonalizationColumns() { - const columns = useMemo[]>( - () => [ - { - accessorFn: (row: any) => { - if (row.firstname) { - return `${row.firstname}`; - } - return ""; - }, - id: "firstname", - header: "First Name", - size: 50, - mantineCopyButtonProps: ({ cell, row }) => ({ - className: "firstname", - id: `${cell.getValue()}-firstname`, - }), - Cell: ({ renderedCellValue, row }) => renderedCellValue, - Header: ({ column }) => column.columnDef.header, - }, - { - accessorFn: (row: any) => { - if (row.lastname) { - return `${row.lastname}`; - } - return ""; - }, - id: "lastname", - header: "Last Name", - mantineCopyButtonProps: ({ cell, row }) => ({ - className: "lastname", - id: `${cell.getValue()}-lastname`, - }), - Cell: ({ renderedCellValue, row }) => renderedCellValue, - Header: ({ column }) => column.columnDef.header, - }, - { - accessorFn: (row: any) => { - if (row.email) { - return `${row.email}`; - } - return ""; - }, - id: "email", - header: "Email", - mantineCopyButtonProps: ({ cell, row }) => ({ - className: "email", - id: `${cell.getValue()}-email`, - }), - Cell: ({ renderedCellValue, row }) => renderedCellValue, - Header: ({ column }) => column.columnDef.header, - }, - ], - [], - ); + const columns = useMemo[]>( + () => [ + { + accessorFn: (row: any) => { + if (row.firstname) { + return `${row.firstname}`; + } + return ""; + }, + id: "firstname", + header: "First Name", + size: 50, + mantineCopyButtonProps: ({ cell, row }) => ({ + className: "firstname", + id: `${cell.getValue()}-firstname`, + }), + Cell: ({ renderedCellValue, row }) => renderedCellValue, + Header: ({ column }) => column.columnDef.header, + }, + { + accessorFn: (row: any) => { + if (row.lastname) { + return `${row.lastname}`; + } + return ""; + }, + id: "lastname", + header: "Last Name", + mantineCopyButtonProps: ({ cell, row }) => ({ + className: "lastname", + id: `${cell.getValue()}-lastname`, + }), + Cell: ({ renderedCellValue, row }) => renderedCellValue, + Header: ({ column }) => column.columnDef.header, + }, + { + accessorFn: (row: any) => { + if (row.email) { + return `${row.email}`; + } + return ""; + }, + id: "email", + header: "Email", + mantineCopyButtonProps: ({ cell, row }) => ({ + className: "email", + id: `${cell.getValue()}-email`, + }), + Cell: ({ renderedCellValue, row }) => renderedCellValue, + Header: ({ column }) => column.columnDef.header, + }, + ], + [], + ); - return columns; + return columns; } - diff --git a/src/DataTable/columns/SearchProviderColumns.tsx b/src/DataTable/columns/SearchProviderColumns.tsx index 3af0045..f1b75b8 100644 --- a/src/DataTable/columns/SearchProviderColumns.tsx +++ b/src/DataTable/columns/SearchProviderColumns.tsx @@ -2,14 +2,14 @@ import type { MRT_ColumnDef } from "mantine-react-table"; import { useMemo } from "react"; export default function SearchProviderColumns() { - const columns = useMemo[]>( + const columns = useMemo[]>( () => [ { accessorFn: (row) => { if (row.id) { return `${row.id}`; } - return ""; + return ""; }, enableEditing: false, id: "id", @@ -23,7 +23,7 @@ export default function SearchProviderColumns() { if (row.name) { return `${row.name}`; } - return ""; + return ""; }, id: "name", header: "Name", @@ -35,7 +35,7 @@ export default function SearchProviderColumns() { if (row.url) { return `${row.url}`; } - return ""; + return ""; }, id: "url", header: "Url", @@ -47,7 +47,7 @@ export default function SearchProviderColumns() { if (row.prefix) { return `${row.prefix}`; } - return ""; + return ""; }, id: "prefix", header: "Prefix", @@ -58,6 +58,5 @@ export default function SearchProviderColumns() { [], ); - return columns; + return columns; } - diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 4a1cb29..81c7edc 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -1,11 +1,20 @@ -import { Box } from '@mantine/core'; +import { Box } from "@mantine/core"; -export default function ThemeProvider({ theme, children }: { theme: any, children: React.ReactNode }) { - return {children}; -} \ No newline at end of file +export default function ThemeProvider({ + theme, + children, +}: { theme: any; children: React.ReactNode }) { + return ( + + {children} + + ); +} diff --git a/src/components/ToastError.tsx b/src/components/ToastError.tsx index dfa5273..a042497 100644 --- a/src/components/ToastError.tsx +++ b/src/components/ToastError.tsx @@ -1,10 +1,10 @@ -import { Stack, Text } from '@mantine/core'; -import { stackClasses } from '../styles'; +import { Stack, Text } from "@mantine/core"; +import { stackClasses } from "../styles"; export function ToastError({ err }: { err: any }) { const errorResponse = JSON.parse(err.message); return ( - + Status: {errorResponse.status} {errorResponse.statusText} diff --git a/src/contexts/HomepageFilters.ts b/src/contexts/HomepageFilters.ts index a96fcf1..4f38add 100644 --- a/src/contexts/HomepageFilters.ts +++ b/src/contexts/HomepageFilters.ts @@ -1,3 +1,3 @@ -import { atom } from 'jotai'; +import { atom } from "jotai"; -export const HomepageFilters = atom([{value: 'All', label: 'All'}]); +export const HomepageFilters = atom([{ value: "All", label: "All" }]); diff --git a/src/dataTableStyles.css b/src/dataTableStyles.css index 73c98d2..96b7fd6 100644 --- a/src/dataTableStyles.css +++ b/src/dataTableStyles.css @@ -1,173 +1,6 @@ -.mrt-table-paper { - height: 100%; - overflow: visible; - background-color: transparent; - border: none; - border-style: none; - box-shadow: none; - &.mantine-Overlay-root { - color: var(--mantine-primary-color-7); - background-color: alpha(var(--mantine-color-appGray-9), 0.5); - } - &.mrt-toolbar-dropzone { - height: 4.5vh; - width: 35vw; - color: var(--mantine-primary-color-6); - font-size: 36px; - background-color: rgb(255, 255, 255, 1); - justify-self: center; - &.inner { - font-size: 36px; - } - } - & ::-webkit-scrollbar { - width: 8px; - height: 8px; - border-radius: 5px; - background-color: transparent; - - } - & ::-webkit-scrollbar-thumb:hover { - background-color: var(--mantine-primary-color-4); - } - & ::-webkit-scrollbar-track { - background-color: transparent; - border-radius: 5px; - } - & ::-webkit-scrollbar-thumb { - border-radius: 5px; - background-color: var(--mantine-primary-color-6); - } - & ::-webkit-scrollbar-corner { - background-color: light-dark(white, var(--mantine-primary-color-8)); - } -} - -.mrt-table-container { - height: 100%; - background-color: light-dark(white, var(--mantine-primary-color-8)); - border-top: solid; - border-top-color: light-dark( - var(--mantine-color-appGray-1), - var(--mantine-primary-color-6) - ); - border-top-width: 1px; - border-left: solid; - border-left-color: light-dark( - var(--mantine-color-appGray-1), - var(--mantine-primary-color-6) - ); - border-left-width: 1px; - border-right: solid; - border-right-color: light-dark( - var(--mantine-color-appGray-1), - var(--mantine-primary-color-6) - ); - border-right-width: 1px; - border-bottom: none; - border-radius: 4px; - border-bottom-left-radius: 0px; - border-bottom-right-radius: 0px; -} - -.mantine-Table-th { - color: light-dark(var(--mantine-color-appGray-7), var(--mantine-primary-color-3)); - background-color: light-dark(white, var(--mantine-primary-color-8)); - border-color: light-dark( - var(--mantine-color-appGray-1), - var(--mantine-primary-color-7) - ); - /* & .mantine-ActionIcon-root { - margin-right: 1px; - display: none; - } */ - & .mrt-table-head-cell-content { - padding-top: 12px; - padding-bottom: 12px; - align-items: center; - justify-content: center; - white-space: nowrap; - .mrt-table-head-cell-labels { - & > * > .mantine-Text-root { - font-size: 14px; - font-weight: bold; - } - } - & .mrt-table-head-cell-content-actions { - transition: 1s all ease; - & .mantine-ActionIcon-root { - color: transparent; - background-color: transparent; - display: hidden; - } - } - } - & .mrt-table-head-cell-resize-handle { - display: flex; - width: 4px; - border-radius: 4px; - border-left-color: transparent; - background-color: light-dark( - var(--mantine-primary-color-1), - var(--mantine-primary-color-6) - ); - } - & .mantine-TableHeadCell-Content-Labels { - cursor: pointer; - position: absolute; - } - &:hover { - & .mrt-table-head-cell-content-actions { - & .mantine-ActionIcon-root { - color: light-dark(var(--mantine-primary-color-6), var(--mantine-primary-color-3)); - background-color: light-dark( - var(--mantine-primary-color-1), - var(--mantine-primary-color-6) - ); - display: grid; - position: absolute; - right: 0; - } - } - & .mrt-table-head-cell-resize-handle { - border-left-color: var(--mantine-primary-color-2); - border-width: 4px; - border-left-style: solid; - } - } -} - -.mantine-Mark-root { - background-color: light-dark( - var(--mantine-primary-color-7), - var(--mantine-primary-color-7) - ); - color: white; -} - -.mantine-Table-tr { - height: 56px; - box-shadow: none; - & .table-icon-device-floppy { - color: light-dark(var(--mantine-primary-color-6), var(--mantine-primary-color-3)); - } -} - -.mantine-Table-td { - color: light-dark(var(--mantine-color-appGray-7), var(--mantine-primary-color-3)); - justify-content: center; - border-color: light-dark( - var(--mantine-color-appGray-1), - var(--mantine-primary-color-7) - ); - - & > * > .mantine-Text-root { - font-size: 14px; - } -} - .mrt-table-head-sort-button { display: none; + color: var(--color-text-pri) !important; } .mrt-table-head-sort-button[data-sorted='asc'] { diff --git a/src/hooks/index.ts b/src/hooks/index.ts index b580ef6..7f2993e 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -1 +1 @@ -export { useQueryAPI } from './useAPI'; \ No newline at end of file +export { useQueryAPI } from "./useAPI"; diff --git a/src/hooks/useAPI.ts b/src/hooks/useAPI.ts index 5722f33..040c69c 100644 --- a/src/hooks/useAPI.ts +++ b/src/hooks/useAPI.ts @@ -1,21 +1,25 @@ -import { useQuery, useQueryClient, useMutation, useInfiniteQuery } from '@tanstack/react-query'; -import { useCallback } from 'react'; -import { toast } from 'react-toastify'; +import { + useQuery, + useQueryClient, + useMutation, + useInfiniteQuery, +} from "@tanstack/react-query"; +import { useCallback } from "react"; +import { toast } from "react-toastify"; export function useQueryAPI({ endpoint }: { endpoint: string }) { - const callEndpoint = async (endpoint: string) => { const url = `http://localhost:5000/trigger/${endpoint}`; const options: object = { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site', + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, }; @@ -27,30 +31,28 @@ export function useQueryAPI({ endpoint }: { endpoint: string }) { }; return useQuery({ - queryKey: ['GET', endpoint], + queryKey: ["GET", endpoint], queryFn: () => callEndpoint(endpoint), }); } export function useMutationAPI() { - const callEndpoint = async ( method: string, endpoint: string, body: object | undefined | null, ) => { - const url = `http://localhost:5000/trigger/${endpoint}`; const options: any = { method: method, headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site' + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, body: JSON.stringify(body), }; @@ -58,7 +60,7 @@ export function useMutationAPI() { const response = await fetch(url, options); if (!response.ok) { const responseData = await response.json(); - if (typeof responseData.detail !== 'string') { + if (typeof responseData.detail !== "string") { const errorResponse = JSON.stringify({ status: response.status, statusText: response.statusText, @@ -71,7 +73,7 @@ export function useMutationAPI() { throw new Error(errorResponse); } - if (typeof responseData.detail === 'object') { + if (typeof responseData.detail === "object") { const errorResponse = JSON.stringify({ status: response.status, statusText: response.statusText, @@ -108,16 +110,18 @@ export function useMutationAPI() { }) => callEndpoint(method, endpoint, body), onMutate: () => {}, onSuccess: (data, variables) => { - queryClient.invalidateQueries({ queryKey: ['GET', variables.endpoint] }); + queryClient.invalidateQueries({ queryKey: ["GET", variables.endpoint] }); - if (variables.endpoint.includes('/')) { + if (variables.endpoint.includes("/")) { if ((variables.endpoint.match(/\//g) || []).length > 2) { - const GetEndpoint = variables.endpoint.split('/'); + const GetEndpoint = variables.endpoint.split("/"); const Endpoint = `${GetEndpoint[1]}/${GetEndpoint[2]}`; - queryClient.invalidateQueries({ queryKey: ['GET', `/${Endpoint}`] }); + queryClient.invalidateQueries({ queryKey: ["GET", `/${Endpoint}`] }); } else { - const GetEndpoint = variables.endpoint.split('/')[1]; - queryClient.invalidateQueries({ queryKey: ['GET', `/${GetEndpoint}`] }); + const GetEndpoint = variables.endpoint.split("/")[1]; + queryClient.invalidateQueries({ + queryKey: ["GET", `/${GetEndpoint}`], + }); } } }, @@ -125,32 +129,30 @@ export function useMutationAPI() { } export function useFileUploadAPI() { - const callEndpoint = async ( method: string, endpoint: string, body?: object | FormData | undefined | null, ) => { - const url = `http://localhost:5000/trigger/${endpoint}`; const options = { method: method, headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site', + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, body: body ?? undefined, }; const response = await fetch(url, options as unknown as Body); if (!response.ok) { const responseData = await response.json(); - if (typeof responseData.detail !== 'string') { + if (typeof responseData.detail !== "string") { const errorResponse = JSON.stringify({ status: response.status, statusText: response.statusText, @@ -190,10 +192,10 @@ export function useFileUploadAPI() { }) => callEndpoint(method, endpoint, body), onMutate: () => {}, onSuccess: (variables) => { - queryClient.invalidateQueries({ queryKey: ['GET', variables.endpoint] }); - if (variables.endpoint?.includes('/')) { - const GetEndpoint = variables.endpoint.split('/')[1]; - queryClient.invalidateQueries({ queryKey: ['GET', `/${GetEndpoint}`] }); + queryClient.invalidateQueries({ queryKey: ["GET", variables.endpoint] }); + if (variables.endpoint?.includes("/")) { + const GetEndpoint = variables.endpoint.split("/")[1]; + queryClient.invalidateQueries({ queryKey: ["GET", `/${GetEndpoint}`] }); } }, }); @@ -204,12 +206,11 @@ export function useFetchAllRecordsAPI({ endpoint }: { endpoint: string }) { const queryClient = useQueryClient(); const fetchPage = async (page: number, retryCount = 0): Promise => { - // Start building the URL const url = new URL(`http://localhost:5000/trigger/${endpoint}`); // Check and append custom query parameters from the endpoint - const customParams = new URLSearchParams(endpoint.split('?')[1]); + const customParams = new URLSearchParams(endpoint.split("?")[1]); for (const [key, value] of customParams) { if (!url.searchParams.has(key)) { url.searchParams.append(key, value); @@ -217,19 +218,19 @@ export function useFetchAllRecordsAPI({ endpoint }: { endpoint: string }) { } // Add 'page' and 'size' parameters - url.searchParams.set('page', page.toString()); // Use 'set' to ensure uniqueness - url.searchParams.set('size', pageSize.toString()); + url.searchParams.set("page", page.toString()); // Use 'set' to ensure uniqueness + url.searchParams.set("size", pageSize.toString()); const options: any = { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site', + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, }; @@ -294,18 +295,18 @@ export function useFetchAllRecordsAPI({ endpoint }: { endpoint: string }) { return allItems; } catch (error) { // Handling errors in fetching the first page - console.error('Error fetching the first page:', error); + console.error("Error fetching the first page:", error); return []; // Return empty array on error } }; const invalidate = useCallback(() => { - queryClient.invalidateQueries({ queryKey: ['GET', endpoint] }); + queryClient.invalidateQueries({ queryKey: ["GET", endpoint] }); }, [queryClient, endpoint]); return { ...useQuery({ - queryKey: ['GET', endpoint], + queryKey: ["GET", endpoint], queryFn: callEndpoint, }), invalidate, @@ -322,31 +323,31 @@ export function useDownloadFile() { async ({ endpoint, file_name }: DownloadFileOptions) => { const url = `http://localhost:5000/trigger/${endpoint}`; const options: any = { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site', + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, }; - const toastID = toast.loading('Processing...'); + const toastID = toast.loading("Processing..."); try { const response = await fetch(url, options); if (!response.ok) { - throw new Error('Network response was not ok'); + throw new Error("Network response was not ok"); } const blob = await response.blob(); - if (blob.type === 'application/json') { + if (blob.type === "application/json") { const blob_text = await blob.text(); - const cleaned_text = blob_text.replace(/"/g, ''); + const cleaned_text = blob_text.replace(/"/g, ""); toast.update(toastID, { render: cleaned_text, - type: 'info', + type: "info", isLoading: false, autoClose: 5000, closeButton: null, @@ -354,11 +355,11 @@ export function useDownloadFile() { return; } - if (typeof window !== 'undefined') { + if (typeof window !== "undefined") { const blobURL = window.URL.createObjectURL(blob); - const a = document.createElement('a'); + const a = document.createElement("a"); - a.style.display = 'none'; + a.style.display = "none"; a.href = blobURL; a.download = file_name; @@ -368,17 +369,17 @@ export function useDownloadFile() { document.body.removeChild(a); toast.update(toastID, { render: `${file_name} Downloaded`, - type: 'success', + type: "success", isLoading: false, autoClose: 5000, closeButton: null, }); } } catch (error) { - console.error('Download failed:', error); + console.error("Download failed:", error); toast.update(toastID, { render: `Error Downloading ${file_name}. Please try again.`, - type: 'error', + type: "error", isLoading: false, autoClose: 5000, closeButton: null, @@ -391,7 +392,6 @@ export function useDownloadFile() { return downloadFile; } - export const useFetchInfiniteQuery = ({ endpoint, pageSize = 10, @@ -399,27 +399,27 @@ export const useFetchInfiniteQuery = ({ endpoint: string; pageSize?: number; }) => { - const queryKey = ['GET', endpoint]; + const queryKey = ["GET", endpoint]; const fetchInfiniteQuery = async (endpoint: string) => { const url = `http://localhost:5000/trigger/${endpoint}`; const requestOptions: any = { - method: 'GET', + method: "GET", headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': '*', - 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', - 'Access-Control-Allow-Credentials': true, - 'Sec-Fetch-Mode': 'no-cors', - 'Sec-Fetch-Site': 'same-site' + "Content-Type": "application/json", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "POST, GET, OPTIONS", + "Access-Control-Allow-Credentials": true, + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-site", }, }; try { const response = await fetch(url, requestOptions); return await response.json(); } catch (error) { - console.error('Error fetching transactions:', error); + console.error("Error fetching transactions:", error); throw error; } }; @@ -431,12 +431,25 @@ export const useFetchInfiniteQuery = ({ } return allPages.length + 1; }; - const { data, isLoading, isFetchingNextPage, fetchNextPage, isError, isFetching } = - useInfiniteQuery({ - queryKey, - queryFn, - getNextPageParam, - initialPageParam: 1, - }); - return { data, isLoading, isFetchingNextPage, fetchNextPage, isError, isFetching }; -}; \ No newline at end of file + const { + data, + isLoading, + isFetchingNextPage, + fetchNextPage, + isError, + isFetching, + } = useInfiniteQuery({ + queryKey, + queryFn, + getNextPageParam, + initialPageParam: 1, + }); + return { + data, + isLoading, + isFetchingNextPage, + fetchNextPage, + isError, + isFetching, + }; +}; diff --git a/src/main.tsx b/src/main.tsx index b8f20d8..1354143 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,22 +1,21 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient({ - defaultOptions: { - queries: { - gcTime: 1000 * 60 * 60 * 24, // 24 hours - staleTime: 1000 * 60 * 1, // 1 min - }, - }, + defaultOptions: { + queries: { + gcTime: 1000 * 60 * 60 * 24, // 24 hours + staleTime: 1000 * 60 * 1, // 1 min + }, + }, }); -ReactDOM.createRoot(document.getElementById('root')!).render( - - - - - - , -) +ReactDOM.createRoot(document.getElementById("root")!).render( + + + + + , +); diff --git a/src/pages/homepage/Homepage.tsx b/src/pages/homepage/Homepage.tsx index ae42bdb..0d64ca8 100644 --- a/src/pages/homepage/Homepage.tsx +++ b/src/pages/homepage/Homepage.tsx @@ -1,28 +1,31 @@ -import { Stack } from '@mantine/core'; -import stackClasses from '../../styles/Stack.module.css'; -import {useQueryAPI} from '../../hooks/useAPI'; -import Search from './components/Search'; -import Header from './components/Header'; -import Applications from './components/Applications'; -import Bookmarks from './components/Bookmarks'; -import SettingsButton from './components/SettingsButton'; -import { useEffect, useState } from 'react'; -import '../../index.css'; -import { useLocalStorage } from '@mantine/hooks'; +import { Stack } from "@mantine/core"; +import stackClasses from "../../styles/Stack.module.css"; +import { useQueryAPI } from "../../hooks/useAPI"; +import Search from "./components/Search"; +import Header from "./components/Header"; +import Applications from "./components/Applications"; +import Bookmarks from "./components/Bookmarks"; +import SettingsButton from "./components/SettingsButton"; +import { useEffect, useState } from "react"; +import "../../index.css"; +import { useLocalStorage } from "@mantine/hooks"; -export default function Homepage({theme}:any) { - const { data, isFetching } = useQueryAPI({ endpoint: 'api/messages' }); - const [displayedGreeting, setDisplayedGreeting] = useState(''); - const [contentType, setContentType] = useLocalStorage({ key: 'contenttype', defaultValue: 'All' }); +export default function Homepage({ theme }: any) { + const { data, isFetching } = useQueryAPI({ endpoint: "api/messages" }); + const [displayedGreeting, setDisplayedGreeting] = useState(""); + const [contentType, setContentType] = useLocalStorage({ + key: "contenttype", + defaultValue: "All", + }); function date() { const currentDate = new Date(); const dateOptions: Intl.DateTimeFormatOptions = { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric', + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", }; - const date = currentDate.toLocaleDateString('en-GB', dateOptions); + const date = currentDate.toLocaleDateString("en-GB", dateOptions); return date; } function greet(list: any) { @@ -32,7 +35,7 @@ export default function Homepage({theme}:any) { let timeBased: any = []; let easterEggs: any = []; for (const l of list) { - if (l.easteregg === 'N') { + if (l.easteregg === "N") { timeBased = timeBased.concat(l); } else { easterEggs = easterEggs.concat(l); @@ -51,12 +54,16 @@ export default function Homepage({theme}:any) { }, [isFetching]); return ( - +
- - - + + + ); } diff --git a/src/pages/homepage/components/AppItem.tsx b/src/pages/homepage/components/AppItem.tsx index af35381..a1d55c1 100644 --- a/src/pages/homepage/components/AppItem.tsx +++ b/src/pages/homepage/components/AppItem.tsx @@ -1,41 +1,43 @@ -import { Icon } from '@iconify/react'; -import { Box, Stack, Text } from '@mantine/core'; -import { useState } from 'react'; -import stacks from '../../../styles/Stack.module.css'; -import texts from '../../../styles/Text.module.css'; +import { Icon } from "@iconify/react"; +import { Box, Stack, Text } from "@mantine/core"; +import { useState } from "react"; +import stacks from "../../../styles/Stack.module.css"; +import texts from "../../../styles/Text.module.css"; function AppItem({ url, icon, name }: any) { - const [textDecoration, setTextDecoration] = useState('none'); + const [textDecoration, setTextDecoration] = useState("none"); return ( setTextDecoration('underline')} - onMouseOut={() => setTextDecoration('none')} + onMouseOver={() => setTextDecoration("underline")} + onMouseOut={() => setTextDecoration("none")} className={stacks.appItemBox} > - {name} + + {name} + { if (!isFetching) { @@ -13,24 +13,26 @@ function Applications({contentType}: any) { } }, [isFetching]); return ( - - Applications + + + Applications + {applications?.map((item: any) => { - if (item.category === contentType || contentType === 'All') + if (item.category === contentType || contentType === "All") return ( -

{links?.category}

- {links?.map((links) => ( - - ))} - - ); -} - -export default BookmarkGroups; diff --git a/src/pages/homepage/components/Bookmarks.tsx b/src/pages/homepage/components/Bookmarks.tsx index 43ff6bc..87dbf29 100644 --- a/src/pages/homepage/components/Bookmarks.tsx +++ b/src/pages/homepage/components/Bookmarks.tsx @@ -1,15 +1,15 @@ -import { Stack, Text } from '@mantine/core'; -import { useEffect, useState } from 'react'; -import {useQueryAPI} from '../../../hooks/useAPI'; -import texts from '../../../styles/Text.module.css'; -import LinkGroups from './LinkGroups'; +import { Stack, Text } from "@mantine/core"; +import { useEffect, useState } from "react"; +import { useQueryAPI } from "../../../hooks/useAPI"; +import texts from "../../../styles/Text.module.css"; +import LinkGroups from "./LinkGroups"; -function Links({contentType}: any) { +function Links({ contentType }: any) { const { data: linkData, isFetched: linksIsFetched } = useQueryAPI({ - endpoint: 'api/links', + endpoint: "api/links", }); const { data: groupData, isFetched: groupsIsFetched } = useQueryAPI({ - endpoint: 'api/categories', + endpoint: "api/categories", }); const [bookmarks, setBookmarks] = useState([]); const [categories, setCategories] = useState([]); @@ -24,29 +24,32 @@ function Links({contentType}: any) { return ( <> {groupsIsFetched && linksIsFetched && categories?.length > 0 && ( - - Bookmarks + + + Bookmarks + {categories.map((category: any) => { if ( category.column_filter === contentType || - contentType === 'All' + contentType === "All" ) { return ( bookmark.category === category.category_index, + (bookmark: any) => + bookmark.category === category.category_index, )} /> ); diff --git a/src/pages/homepage/components/Header.tsx b/src/pages/homepage/components/Header.tsx index 7eae4c4..a76bbde 100644 --- a/src/pages/homepage/components/Header.tsx +++ b/src/pages/homepage/components/Header.tsx @@ -1,6 +1,6 @@ -import { Stack, Text } from '@mantine/core'; -import { useEffect, useState } from 'react'; -import {textClasses} from '../../../styles'; +import { Stack, Text } from "@mantine/core"; +import { useEffect, useState } from "react"; +import { textClasses } from "../../../styles"; function Header({ greet, date }: any) { const [time, setTime] = useState(new Date()); @@ -22,50 +22,56 @@ function Header({ greet, date }: any) { return ( - {greet} + + {greet} + - + {date} {`${ time.getHours() === 0 ? 12 : time.getHours() > 12 - ? time.getHours() - 12 - : time.getHours() - }:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`} + ? time.getHours() - 12 + : time.getHours() + }:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? "PM" : "AM"}`} diff --git a/src/pages/homepage/components/LinkGroups.tsx b/src/pages/homepage/components/LinkGroups.tsx index ba128de..a064e88 100644 --- a/src/pages/homepage/components/LinkGroups.tsx +++ b/src/pages/homepage/components/LinkGroups.tsx @@ -1,17 +1,19 @@ -import { Stack, Text } from '@mantine/core'; -import texts from '../../../styles/Text.module.css'; -import LinkItem from './LinkItem'; +import { Stack, Text } from "@mantine/core"; +import texts from "../../../styles/Text.module.css"; +import LinkItem from "./LinkItem"; function LinkGroups({ links, category }: any) { return ( - {category} + + {category} + {links?.map((link: any) => ( ))} diff --git a/src/pages/homepage/components/LinkItem.tsx b/src/pages/homepage/components/LinkItem.tsx index e1974ee..c0d0e9b 100644 --- a/src/pages/homepage/components/LinkItem.tsx +++ b/src/pages/homepage/components/LinkItem.tsx @@ -1,9 +1,14 @@ -import { Text } from '@mantine/core'; -import texts from '../../../styles/Text.module.css'; +import { Text } from "@mantine/core"; +import texts from "../../../styles/Text.module.css"; function LinkItem({ link }: any) { return ( - + {link.name} ); diff --git a/src/pages/homepage/components/MessageInfo.jsx b/src/pages/homepage/components/MessageInfo.jsx index 9c824a7..5de9cb6 100644 --- a/src/pages/homepage/components/MessageInfo.jsx +++ b/src/pages/homepage/components/MessageInfo.jsx @@ -1,9 +1,9 @@ -import { useEffect, useState } from 'react'; -import Messages from '../../../components/Messages'; -import useQueryAPI from '../../../hooks/useAPI'; +import { useEffect, useState } from "react"; +import Messages from "../../../components/Messages"; +import useQueryAPI from "../../../hooks/useAPI"; function MessageInfo() { - const messageData = useQueryAPI({ endpoint: 'api/messages' }); + const messageData = useQueryAPI({ endpoint: "api/messages" }); const [greetings, setGreetings] = useState([]); useEffect(() => { @@ -15,7 +15,7 @@ function MessageInfo() { return ( <> {greetings && ( -
+
{greetings.map((greeting, index) => ( { - const option = item.target.value.substr(1, item.target.value.indexOf(' ') - 1) || item.target.value.substr(1); - const subtext = item.target.value.substr(2 + option.length); - if (item.key === 'Enter') { - if (item.target.value.startsWith('/')) { - open(`${providerURL}${subtext}`, '_self'); - } else if (validURL(item.target.value)) { - if (containsProtocol(item.target.value)) window.location = item.target.value; - else open(`https://${item.target.value}`, '_self'); - } else { - open(`${providerURL}${subtext}`, '_self'); - } - } - } + const [providerLabel, setProviderLabel] = useState("Google Search"); + const [providerURL, setProviderURL] = useState( + "https://www.google.com/search?q=", + ); - function validURL(str: any) { - const pattern = new RegExp( - '^(https?:\\/\\/)?' + // protocol - '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name - '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address - '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path - '(\\?[;&a-z\\d%_.~+=-]*)?' + // query string - '(\\#[-a-z\\d_]*)?$', - 'i', - ); // fragment locator - return !!pattern.test(str); - } - function containsProtocol(str: any) { - const pattern = /^(https?:\/\/){1}.*/i; - return !!pattern.test(str); - } + const handleKeyPress = (item: any) => { + const option = + item.target.value.substr(1, item.target.value.indexOf(" ") - 1) || + item.target.value.substr(1); + const subtext = item.target.value.substr(2 + option.length); + if (item.key === "Enter") { + if (item.target.value.startsWith("/")) { + open(`${providerURL}${subtext}`, "_self"); + } else if (validURL(item.target.value)) { + if (containsProtocol(item.target.value)) + window.location = item.target.value; + else open(`https://${item.target.value}`, "_self"); + } else { + open(`${providerURL}${subtext}`, "_self"); + } + } + }; - return ( + function validURL(str: any) { + const pattern = new RegExp( + "^(https?:\\/\\/)?" + // protocol + "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name + "((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address + "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path + "(\\?[;&a-z\\d%_.~+=-]*)?" + // query string + "(\\#[-a-z\\d_]*)?$", + "i", + ); // fragment locator + return !!pattern.test(str); + } + function containsProtocol(str: any) { + const pattern = /^(https?:\/\/){1}.*/i; + return !!pattern.test(str); + } + + return ( { - if(item.target.value.startsWith('/')) { - setProviderLabel(providers?.find((p: any) => p.prefix === item.target.value.split(' ')[0]).name); - setProviderURL(providers?.find((p: any) => p.prefix === item.target.value.split(' ')[0]).url); - } else { - setProviderLabel('Google Search'); - setProviderURL('https://www.google.com/search?q='); - } - }} - onKeyUp={(item: any) => { - handleKeyPress(item); - }} + if (item.target.value.startsWith("/")) { + setProviderLabel( + providers?.find( + (p: any) => p.prefix === item.target.value.split(" ")[0], + ).name, + ); + setProviderURL( + providers?.find( + (p: any) => p.prefix === item.target.value.split(" ")[0], + ).url, + ); + } else { + setProviderLabel("Google Search"); + setProviderURL("https://www.google.com/search?q="); + } + }} + onKeyUp={(item: any) => { + handleKeyPress(item); + }} /> ); -} \ No newline at end of file +} diff --git a/src/pages/homepage/components/SettingsButton.tsx b/src/pages/homepage/components/SettingsButton.tsx index 691c5ed..66a72b2 100644 --- a/src/pages/homepage/components/SettingsButton.tsx +++ b/src/pages/homepage/components/SettingsButton.tsx @@ -1,58 +1,58 @@ -import { Button, Menu, NavLink, Select } from '@mantine/core'; -import { useEffect, useState } from 'react'; -import { FiMenu, FiMonitor } from 'react-icons/fi'; -import {useQueryAPI} from '../../../hooks/useAPI'; -import button from '../../../styles/Button.module.css'; -import menu from '../../../styles/Menu.module.css'; -import navLink from '../../../styles/NavLink.module.css'; -import selectClasses from '../../../styles/Select.module.css'; +import { Button, Menu, NavLink, Select } from "@mantine/core"; +import { useEffect, useState } from "react"; +import { FiMenu, FiMonitor } from "react-icons/fi"; +import { useQueryAPI } from "../../../hooks/useAPI"; +import button from "../../../styles/Button.module.css"; +import menu from "../../../styles/Menu.module.css"; +import navLink from "../../../styles/NavLink.module.css"; +import selectClasses from "../../../styles/Select.module.css"; + +function SettingsButton({ contentType, setContentType, theme }: any) { + const { data, isFetched } = useQueryAPI({ endpoint: "api/appCategories" }); + const [categories, setCategories] = useState([ + { value: "All", label: "All" }, + ]); -function SettingsButton({contentType, setContentType, theme}: any) { - const { data, isFetched } = useQueryAPI({ endpoint: 'api/appCategories' }); - const [categories, setCategories] = useState([{value: 'All', label: 'All'}]); - useEffect(() => { - if(data) { - const list: [any] = data.map((category: any) => {return {value: category.category, label: category.category}}) || []; - list.unshift({value: 'All', label: 'All'}); + if (data) { + const list: [any] = + data.map((category: any) => { + return { value: category.category, label: category.category }; + }) || []; + list.unshift({ value: "All", label: "All" }); setCategories(list); } }, [data, isFetched]); function runWakeCommand() { const requestOptions = { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, + method: "GET", + headers: { "Content-Type": "application/json" }, }; - fetch('/trigger/api/wakeDakota', requestOptions); + fetch("/trigger/api/wakeDakota", requestOptions); } return ( - + - + - + classNames={navLink} + > } onClick={() => runWakeCommand()} className={navLink.defaultNavLink} @@ -60,12 +60,12 @@ function SettingsButton({contentType, setContentType, theme}: any) { />