Base frame for login version
This commit is contained in:
parent
8744b3ce99
commit
f1c5852f65
10 changed files with 154 additions and 16 deletions
89
package-lock.json
generated
89
package-lock.json
generated
|
|
@ -11,8 +11,10 @@
|
|||
"@fortawesome/free-brands-svg-icons": "^7.0.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.0.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.3",
|
||||
"oidc-react": "^4.0.1",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router-dom": "^7.8.1",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -2055,6 +2057,15 @@
|
|||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
|
||||
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/cosmiconfig": {
|
||||
"version": "8.3.6",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
|
||||
|
|
@ -3670,6 +3681,15 @@
|
|||
"node": ">=4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jwt-decode": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
|
||||
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||
|
|
@ -3930,6 +3950,31 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/oidc-client-ts": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.3.0.tgz",
|
||||
"integrity": "sha512-t13S540ZwFOEZKLYHJwSfITugupW4uYLwuQSSXyKH/wHwZ+7FvgHE7gnNJh1YQIZ1Yd1hKSRjqeXGSUtS0r9JA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jwt-decode": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/oidc-react": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/oidc-react/-/oidc-react-4.0.1.tgz",
|
||||
"integrity": "sha512-UjsSRlg/mux5dYb7hR1NvL0bcCVTShIRh/hzFU6h64RJ4jqFlZL6CD5cu1YuUS2MNurMGboiG9SHuYI59ZSBEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"oidc-client-ts": "^3.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^16.8.0 || || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
||||
|
|
@ -4188,6 +4233,44 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.1.tgz",
|
||||
"integrity": "sha512-5cy/M8DHcG51/KUIka1nfZ2QeylS4PJRs6TT8I4PF5axVsI5JUxp0hC0NZ/AEEj8Vw7xsEoD7L/6FY+zoYaOGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cookie": "^1.0.1",
|
||||
"set-cookie-parser": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.1.tgz",
|
||||
"integrity": "sha512-NkgBCF3sVgCiAWIlSt89GR2PLaksMpoo3HDCorpRfnCEfdtRPLiuTf+CNXvqZMI5SJLZCLpVCvcZrTdtGW64xQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-router": "7.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
|
|
@ -4368,6 +4451,12 @@
|
|||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
|
|
|
|||
|
|
@ -13,8 +13,10 @@
|
|||
"@fortawesome/free-brands-svg-icons": "^7.0.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^7.0.0",
|
||||
"@fortawesome/react-fontawesome": "^0.2.3",
|
||||
"oidc-react": "^4.0.1",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-router-dom": "^7.8.1",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
import './app.css';
|
||||
import ButtonGroup from "./buttons/buttonGroup.tsx";
|
||||
import SocialButtons from "./buttons/Socials.tsx";
|
||||
import { useAuth } from 'oidc-react';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
const auth = useAuth();
|
||||
|
||||
console.log(auth.userData);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Octubre</h1>
|
||||
<h2>Home of projects</h2>
|
||||
|
|
@ -14,6 +19,8 @@ function App() {
|
|||
This is a linking page. Click on one of the buttons to go to the specified project, website or subdomain.
|
||||
</p>
|
||||
|
||||
{auth.userData && <p>You are logged in!</p>}
|
||||
|
||||
<div className="buttonGroup">
|
||||
<ButtonGroup
|
||||
buttons={[["Home", "https://home.octubre.be", "Home Automation Platform using Home Assistant"], ["Cloud", "https://cloud.octubre.be", "Personal Office Infrastructure using Nextcloud"], ["Media", "https://media.octubre.be", "Multimedia management solution using Immich"], ["Blog", "https://blog.octubre.be", "Blog about this hobby project and it's development roadmap"], ["Me", "https://me.octubre.be", "My portfolio page including Github Projects"], ["Chat", "https://chat.octubre.be", "Federated chat instance using Matrix & Element"], ["Log 👷", "https://log.octubre.be", "Update log linked to the blog - Under construction"], ["Status", "https://status.octubre.be", "External status page of the different Octubre services"], ["Git", "https://git.octubre.be", "Forgejo based gitserver, alternative for my Github account"],["Fandom", "https://fandom.octubre.be", 'Website dedicated to fanart & creations about things I like'], ["Archive", "https://archive.octubre.be", "Separate website to host old, no longer maintained packages & websites"], ["Dev", "https://dev.octubre.be", "Development subdomain for alfa & beta releases"]]}/>
|
||||
|
|
|
|||
|
|
@ -3,37 +3,39 @@ import styles from './Button.module.css';
|
|||
import * as React from "react";
|
||||
|
||||
interface ButtonProps {
|
||||
note: string;
|
||||
note?: string;
|
||||
onClick: () => void;
|
||||
clicked?: boolean;
|
||||
title: string;
|
||||
right?: boolean;
|
||||
text?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const Button: React.FC<ButtonProps> = ({
|
||||
note,
|
||||
note = '',
|
||||
onClick,
|
||||
title,
|
||||
right = false,
|
||||
text = '',
|
||||
style,
|
||||
}) => {
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const controlButtonNote = right ? styles.controlButtonNoteRight : styles.controlButtonNote;
|
||||
|
||||
return (
|
||||
<div className={styles.controlButtonContainer}>
|
||||
<div className={styles.controlButtonContainer} style={style}>
|
||||
<button
|
||||
aria-label={note}
|
||||
className={styles.controlButton}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
onClick={onClick}
|
||||
|
||||
>
|
||||
{/*<FontAwesomeIcon icon={faIcon} style={{color: clicked ? '#c084fc' : '#ffffff'}}/>*/}
|
||||
{text}
|
||||
</button>
|
||||
{isHovered &&
|
||||
{isHovered && note!='' &&
|
||||
<span className={controlButtonNote}>
|
||||
<div className={styles.tooltipHeader}>
|
||||
<span className={styles.tooltipTitle}>{title}</span>
|
||||
|
|
|
|||
7
src/header/Header.module.css
Normal file
7
src/header/Header.module.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.Header{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
width: 100%;
|
||||
text-align: right; /* override parent's center */
|
||||
gap: 1rem;
|
||||
}
|
||||
22
src/header/Header.tsx
Normal file
22
src/header/Header.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import styles from './themeSwitch.module.css';
|
||||
import styles2 from './Header.module.css';
|
||||
import ThemeSwitch from "./themeSwitch.tsx";
|
||||
import { useAuth } from 'oidc-react';
|
||||
|
||||
const Header = () => {
|
||||
const auth = useAuth(); // ✅ use the hook at the top level
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={styles2.Header}>
|
||||
<ThemeSwitch />
|
||||
<button className={styles.button} onClick={() => auth.signIn()}>
|
||||
Log in
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
|
||||
|
|
@ -3,15 +3,10 @@
|
|||
color: var(--foreground-color);
|
||||
background-color: var(--on-background-color-primary);
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: background 0.3s, color 0.3s;
|
||||
|
||||
top: 1vh;
|
||||
right: 1vw;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
|
|
@ -8,7 +8,7 @@ const ThemeToggleButton = () => {
|
|||
const [theme, toggleTheme] = useTheme();
|
||||
|
||||
return (
|
||||
<button className={styles.button} onClick={toggleTheme} aria-label="Toggle dark mode">
|
||||
<button className={styles.button} onClick={toggleTheme} aria-label="Toggle dark mode">
|
||||
{theme === 'dark' ? (
|
||||
<FontAwesomeIcon icon={faSun}/>
|
||||
) : (
|
||||
22
src/main.tsx
22
src/main.tsx
|
|
@ -2,11 +2,25 @@ import { StrictMode } from 'react'
|
|||
import { createRoot } from 'react-dom/client'
|
||||
import App from './app.tsx'
|
||||
import './main.css'
|
||||
import ThemeToggleButton from "./theme/themeSwitch.tsx";
|
||||
import {AuthProvider} from 'oidc-react';
|
||||
import Header from "./header/Header.tsx";
|
||||
|
||||
const oidcConfig = {
|
||||
onSignIn: () => {
|
||||
// Redirect?
|
||||
},
|
||||
authority: 'https://auth.octubre.be',
|
||||
clientId: '', // TODO Paste Client ID & set to Public
|
||||
redirect_uri: 'https://octubre.be',
|
||||
autoSignIn: false,
|
||||
autoSignOut: false
|
||||
};
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<ThemeToggleButton/>
|
||||
<App/>
|
||||
</StrictMode>,
|
||||
<AuthProvider {...oidcConfig}>
|
||||
<Header/>
|
||||
<App/>
|
||||
</AuthProvider>
|
||||
</StrictMode>
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue