diff --git a/admin/package.json b/admin/package.json index d74fedc12..20ada9564 100644 --- a/admin/package.json +++ b/admin/package.json @@ -14,6 +14,7 @@ "@radix-ui/react-toast": "^1.1.5", "i18next": "^23.10.1", "i18next-browser-languagedetector": "^7.2.0", + "lucide-react": "^0.356.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-i18next": "^14.1.0", diff --git a/admin/pnpm-workspace.yaml b/admin/pnpm-workspace.yaml deleted file mode 100644 index e69de29bb..000000000 diff --git a/admin/public/Karla-Bold.ttf b/admin/public/Karla-Bold.ttf new file mode 100644 index 000000000..2348e0072 Binary files /dev/null and b/admin/public/Karla-Bold.ttf differ diff --git a/admin/public/Karla-BoldItalic.ttf b/admin/public/Karla-BoldItalic.ttf new file mode 100644 index 000000000..3c0e045ec Binary files /dev/null and b/admin/public/Karla-BoldItalic.ttf differ diff --git a/admin/public/Karla-ExtraBold.ttf b/admin/public/Karla-ExtraBold.ttf new file mode 100644 index 000000000..f18471195 Binary files /dev/null and b/admin/public/Karla-ExtraBold.ttf differ diff --git a/admin/public/Karla-ExtraBoldItalic.ttf b/admin/public/Karla-ExtraBoldItalic.ttf new file mode 100644 index 000000000..3799659c0 Binary files /dev/null and b/admin/public/Karla-ExtraBoldItalic.ttf differ diff --git a/admin/public/Karla-ExtraLight.ttf b/admin/public/Karla-ExtraLight.ttf new file mode 100644 index 000000000..0f8642c02 Binary files /dev/null and b/admin/public/Karla-ExtraLight.ttf differ diff --git a/admin/public/Karla-ExtraLightItalic.ttf b/admin/public/Karla-ExtraLightItalic.ttf new file mode 100644 index 000000000..bb328e175 Binary files /dev/null and b/admin/public/Karla-ExtraLightItalic.ttf differ diff --git a/admin/public/Karla-Italic.ttf b/admin/public/Karla-Italic.ttf new file mode 100644 index 000000000..1853cbe4e Binary files /dev/null and b/admin/public/Karla-Italic.ttf differ diff --git a/admin/public/Karla-Light.ttf b/admin/public/Karla-Light.ttf new file mode 100644 index 000000000..46457ece7 Binary files /dev/null and b/admin/public/Karla-Light.ttf differ diff --git a/admin/public/Karla-LightItalic.ttf b/admin/public/Karla-LightItalic.ttf new file mode 100644 index 000000000..3b0f01ff1 Binary files /dev/null and b/admin/public/Karla-LightItalic.ttf differ diff --git a/admin/public/Karla-Medium.ttf b/admin/public/Karla-Medium.ttf new file mode 100644 index 000000000..9066b49c4 Binary files /dev/null and b/admin/public/Karla-Medium.ttf differ diff --git a/admin/public/Karla-MediumItalic.ttf b/admin/public/Karla-MediumItalic.ttf new file mode 100644 index 000000000..ea9535355 Binary files /dev/null and b/admin/public/Karla-MediumItalic.ttf differ diff --git a/admin/public/Karla-Regular.ttf b/admin/public/Karla-Regular.ttf new file mode 100644 index 000000000..c164d0047 Binary files /dev/null and b/admin/public/Karla-Regular.ttf differ diff --git a/admin/public/Karla-SemiBold.ttf b/admin/public/Karla-SemiBold.ttf new file mode 100644 index 000000000..82e0c5abf Binary files /dev/null and b/admin/public/Karla-SemiBold.ttf differ diff --git a/admin/public/Karla-SemiBoldItalic.ttf b/admin/public/Karla-SemiBoldItalic.ttf new file mode 100644 index 000000000..77c19ef69 Binary files /dev/null and b/admin/public/Karla-SemiBoldItalic.ttf differ diff --git a/admin/src/App.tsx b/admin/src/App.tsx index 3db45f0e8..a1a1e4377 100644 --- a/admin/src/App.tsx +++ b/admin/src/App.tsx @@ -6,6 +6,7 @@ import {NavLink, Outlet, useNavigate} from "react-router-dom"; import {useStore} from "./store/store.ts"; import {LoadingScreen} from "./utils/LoadingScreen.tsx"; import {Trans, useTranslation} from "react-i18next"; +import {Cable, Construction, Crown, NotepadText, Wrench} from "lucide-react"; const WS_URL = import.meta.env.DEV? 'http://localhost:9001' : '' export const App = ()=> { @@ -86,14 +87,19 @@ export const App = ()=> { return
-
-

Etherpad

-
    -
  • -
  • -
  • -
  • -
+
+
+ + +

Etherpad

+
+
    +
  • +
  • +
  • +
  • +
+
diff --git a/admin/src/components/IconButton.tsx b/admin/src/components/IconButton.tsx new file mode 100644 index 000000000..e91f3e914 --- /dev/null +++ b/admin/src/components/IconButton.tsx @@ -0,0 +1,16 @@ +import {FC, ReactElement} from "react"; + +export type IconButtonProps = { + icon: JSX.Element, + title: string|ReactElement, + onClick: ()=>void, + className?: string, + disabled?: boolean +} + +export const IconButton:FC = ({icon,className,onClick,title, disabled})=>{ + return +} diff --git a/admin/src/components/SearchField.tsx b/admin/src/components/SearchField.tsx new file mode 100644 index 000000000..62a965d40 --- /dev/null +++ b/admin/src/components/SearchField.tsx @@ -0,0 +1,14 @@ +import {ChangeEventHandler, FC} from "react"; +import {Search} from 'lucide-react' +export type SearchFieldProps = { + value: string, + onChange: ChangeEventHandler, + placeholder?: string +} + +export const SearchField:FC = ({onChange,value, placeholder})=>{ + return + + + +} diff --git a/admin/src/index.css b/admin/src/index.css index e9683befa..087de1b1f 100644 --- a/admin/src/index.css +++ b/admin/src/index.css @@ -1,17 +1,23 @@ :root { --etherpad-color: #0f775b; + --etherpad-comp: #9C8840; + --etherpad-light: #99FF99; } - +@font-face { + font-family: Karla; + src: url(/Karla-Regular.ttf); +} html, body, #root { box-sizing: border-box; height: 100%; - + font-family: "Karla", sans-serif; } *, *:before, *:after { box-sizing: inherit; + font-size: 16px; } body { @@ -22,44 +28,111 @@ body { } div.menu { - height: 100%; - padding: 15px; - width: 220px; - border-right: 1px solid #ccc; - position: fixed; + height: 100vh; + font-size: 16px; + font-weight: bolder; + display: flex; + align-items: center; + justify-content: center; + max-width: 20%; + min-width: 20%; +} + +.icon-button{ + display: flex; + gap: 10px; + background-color: var(--etherpad-color); + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; +} + +.icon-button svg { + align-self: center; +} + +.icon-button span { + align-self: center; +} + + +div.menu span:first-child { + display: flex; + justify-content: center; +} + +div.menu span:first-child svg { + margin-right: 10px; + align-self: center; +} + + +div.menu h1 { + font-size: 50px; + text-align: center; +} + +.inner-menu { + border-radius: 0 20px 20px 0; + padding: 10px; + flex-grow: 100; + background-color: var(--etherpad-comp); + color: white; + height: 100vh; } div.menu ul { + color: white; padding: 0; } +div.menu li a { + display: flex; + gap: 10px; + margin-bottom: 20px; +} + +div.menu svg { + align-self: center; +} + div.menu li { + padding: 10px; + color: white; list-style: none; margin-left: 3px; line-height: 3; - border-top: 1px solid #ccc; } -div.menu li:last-child { - border-bottom: 1px solid #ccc; + +div.menu li:has(.active) { + background-color: #9C885C ; } +div.menu li a { + color: lightgray; +} + + + div.innerwrapper { - padding: 15px; - padding-left: 265px; + background-color: #F0F0F0; + overflow: auto; + height: 100vh; + flex-grow: 100; + padding: 20px; } div.innerwrapper-err { - padding: 15px; - padding-left: 265px; display: none; } #wrapper { + display: flex; background: none repeat scroll 0px 0px #FFFFFF; box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.2); - margin: auto; - max-width: 1150px; min-height: 100%;/*always display a scrollbar*/ } @@ -110,17 +183,25 @@ input { content:'▼' } + +#installed-plugins thead tr th:nth-child(3) { + width: 15%; +} + table { border: 1px solid #ddd; border-radius: 3px; border-spacing: 0; width: 100%; margin: 20px 0; - position:relative; /* Allows us to position the loading indicator relative to the table */ } -table thead tr { - background: #eee; + + + + +#available-plugins th:first-child, #available-plugins th:nth-child(2){ + text-align: center; } td, th { @@ -223,6 +304,7 @@ pre { height: auto; border-right: none; width: auto; + float: left; } table { @@ -484,6 +566,76 @@ pre { } .search-field { - width: 50%; - padding: 5px; + position: relative; +} + +.search-field input { + border-color: transparent; + border-radius: 20px; + height: 2.5rem; + width: 100vh; + padding: 5px 5px 5px 30px; +} + +.search-field input:focus { + outline: none; +} + +.search-field svg { + position: absolute; + left: 3px; + bottom: -3px; +} + + +.search-field svg { + color: gray +} + +table { + margin: 25px 0; + font-size: 0.9em; + font-family: sans-serif; + min-width: 400px; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); +} + +th:first-child { + border-top-left-radius: 10px; +} + +th:last-child { + border-top-right-radius: 10px; +} + +table thead tr { + font-size: 25px; + background-color: var(--etherpad-color); + color: #ffffff; + text-align: left; +} + +table tbody tr { + border-bottom: 1px solid #dddddd; +} + +table tr:nth-child(even) td{ + background-color: lightgray; +} + +table tr td { + padding: 12px 15px; +} + +table tbody tr:nth-of-type(even) { + background-color: #f3f3f3; +} + +table tbody tr:last-of-type { + border-bottom: 2px solid #009879; +} + +table tbody tr.active-row { + font-weight: bold; + color: #009879; } diff --git a/admin/src/pages/HomePage.tsx b/admin/src/pages/HomePage.tsx index c43585d0a..0ea1a26d4 100644 --- a/admin/src/pages/HomePage.tsx +++ b/admin/src/pages/HomePage.tsx @@ -3,6 +3,9 @@ import {useEffect, useMemo, useState} from "react"; import {InstalledPlugin, PluginDef, SearchParams} from "./Plugin.ts"; import {useDebounce} from "../utils/useDebounce.ts"; import {Trans, useTranslation} from "react-i18next"; +import {SearchField} from "../components/SearchField.tsx"; +import {Download, Trash} from "lucide-react"; +import {IconButton} from "../components/IconButton.tsx"; export const HomePage = () => { @@ -128,12 +131,12 @@ export const HomePage = () => {

- +
- + @@ -145,10 +148,7 @@ export const HomePage = () => { { plugin.updatable ? - : - + : } title={} onClick={() => uninstallPlugin(plugin.name)}/> } @@ -158,19 +158,16 @@ export const HomePage = () => {

+ {setSearchTerm(v.target.value)}} placeholder={t('admin_plugins.available_search.placeholder')} value={searchTerm}/> - { - setSearchTerm(v.target.value) - }}/> - -
+
- + @@ -181,7 +178,7 @@ export const HomePage = () => { })} diff --git a/admin/src/pages/PadPage.tsx b/admin/src/pages/PadPage.tsx index 5c11755d6..abb934df5 100644 --- a/admin/src/pages/PadPage.tsx +++ b/admin/src/pages/PadPage.tsx @@ -5,6 +5,9 @@ import {PadSearchQuery, PadSearchResult} from "../utils/PadSearch.ts"; import {useDebounce} from "../utils/useDebounce.ts"; import {determineSorting} from "../utils/sorting.ts"; import * as Dialog from "@radix-ui/react-dialog"; +import {IconButton} from "../components/IconButton.tsx"; +import {Trash2} from "lucide-react"; +import {SearchField} from "../components/SearchField.tsx"; export const PadPage = ()=>{ const settingsSocket = useStore(state=>state.settingsSocket) @@ -98,8 +101,7 @@ export const PadPage = ()=>{

- setSearchTerm(v.target.value)} - placeholder={t('ep_admin_pads:ep_adminpads2_search-heading')}/> + setSearchTerm(v.target.value)} placeholder={t('ep_admin_pads:ep_adminpads2_search-heading')}/>
{plugin.version} {plugin.time} - + } onClick={() => installPlugin(plugin.name)} title={}/>
@@ -144,13 +146,11 @@ export const PadPage = ()=>{ diff --git a/admin/src/pages/SettingsPage.tsx b/admin/src/pages/SettingsPage.tsx index b72507c3a..2706ffa38 100644 --- a/admin/src/pages/SettingsPage.tsx +++ b/admin/src/pages/SettingsPage.tsx @@ -1,10 +1,11 @@ import {useStore} from "../store/store.ts"; import {isJSONClean} from "../utils/utils.ts"; import {Trans} from "react-i18next"; +import {IconButton} from "../components/IconButton.tsx"; +import {RotateCw, Save} from "lucide-react"; export const SettingsPage = ()=>{ const settingsSocket = useStore(state=>state.settingsSocket) - const settings = useStore(state=>state.settings) return
@@ -13,7 +14,8 @@ export const SettingsPage = ()=>{ useStore.getState().setSettings(v.target.value) }}/>
- - + }}/>
- -
diff --git a/package.json b/package.json index 99cb89c88..d9bdf8cd3 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,9 @@ "dependencies": { "ep_etherpad-lite": "workspace:./src" }, + "devDependencies": { + "admin": "workspace:./admin" + }, "engines": { "node": ">=18.18.2", "npm": ">=6.14.0", diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 4d8f70bb3..3d3e285e0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - src + - admin diff --git a/src/tests/frontend-new/admin-spec/adminsettings.spec.ts b/src/tests/frontend-new/admin-spec/adminsettings.spec.ts index ad3a0c441..adeb10f47 100644 --- a/src/tests/frontend-new/admin-spec/adminsettings.spec.ts +++ b/src/tests/frontend-new/admin-spec/adminsettings.spec.ts @@ -1,5 +1,6 @@ import {expect, test} from "@playwright/test"; import {loginToAdmin, restartEtherpad, saveSettings} from "../helper/adminhelper"; +import exp from "node:constants"; test.beforeEach(async ({ page })=>{ await loginToAdmin(page, 'admin', 'changeme1');
{pad.revisionNumber}
- - + }}/> + } title="view" onClick={()=>window.open(`/p/${pad.padName}`, '_blank')}/>