Skip to content
Snippets Groups Projects
Verified Commit e522077f authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: login/logout buttons

parent b2e0993d
No related branches found
No related tags found
No related merge requests found
Pipeline #48589 passed
......@@ -4,6 +4,7 @@ import {
RefineSnackbarProvider,
ThemedLayoutV2,
ThemedTitleV2,
ThemedSiderV2,
notificationProvider
} from '@refinedev/mui'
import routerProvider from '@refinedev/nextjs-router'
......@@ -24,6 +25,9 @@ import dataProvider from '../src/providers/dataProvider'
import { appWithTranslation, useTranslation } from 'next-i18next'
import logo from '../src/components/fdo_logo'
import { API_URL } from '../src/constants'
import StorageIcon from '@mui/icons-material/Storage'
import FactCheckIcon from '@mui/icons-material/FactCheck'
import LightbulbIcon from '@mui/icons-material/Lightbulb'
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
noLayout?: boolean
......@@ -52,6 +56,7 @@ const App = (props: React.PropsWithChildren) => {
const authProvider: AuthBindings = {
login: async () => {
console.log('login')
signIn('keycloak', {
callbackUrl: to ? to.toString() : '/info',
redirect: true
......@@ -62,9 +67,10 @@ const App = (props: React.PropsWithChildren) => {
}
},
logout: async () => {
console.log('logout')
signOut({
redirect: true,
callbackUrl: '/login'
callbackUrl: '/info'
})
return {
......@@ -72,12 +78,14 @@ const App = (props: React.PropsWithChildren) => {
}
},
onError: async (error) => {
console.log('onError')
console.error(error)
return {
error
}
},
check: async () => {
console.log('check')
if (status === 'unauthenticated') {
return {
authenticated: false,
......@@ -90,9 +98,11 @@ const App = (props: React.PropsWithChildren) => {
}
},
getPermissions: async () => {
console.log('getPermissions')
return null
},
getIdentity: async () => {
console.log('getIdentity')
if (data?.user) {
const { user } = data
return {
......@@ -128,18 +138,32 @@ const App = (props: React.PropsWithChildren) => {
name: 'fdo',
list: '/fdo',
show: '/fdo/show/:id',
create: '/fdo'
create: '/fdo',
meta: {
icon: logo
}
}, {
name: 'repositories',
list: '/repositories',
show: '/repositories/show/:id'
}, {
name: 'info',
show: '/info'
show: '/repositories/show/:id',
meta: {
icon: <StorageIcon/>
}
}, {
name: 'profiles',
list: '/profiles',
show: '/profiles/show/:id'
show: '/profiles/show/:id',
meta: {
icon: <FactCheckIcon/>
}
}, {
name: 'info',
// show: '/info',
list: '/info',
meta: {
label: 'About',
icon: <LightbulbIcon/>
}
}]}
>
{props.children}
......@@ -164,13 +188,18 @@ function MyApp ({
return (
<ThemedLayoutV2
Header={() => <Header sticky />}
Title={({ collapsed }) => (
<ThemedTitleV2
collapsed={collapsed}
text="FDO Manager"
icon={logo}
/>
)}
Sider={() => <ThemedSiderV2
render={({ dashboard, logout, items, collapsed }) => {
return <>{dashboard}{items}</>
}}
Title={({ collapsed }) => (
<ThemedTitleV2
collapsed={collapsed}
text="FDO Manager"
icon={logo}
/>
)}
/>}
>
<Component {...pageProps} />
</ThemedLayoutV2>
......
......@@ -45,9 +45,7 @@ export const authOptions = {
},
async redirect ({ url, baseUrl }: any) {
console.log('### redirect', url, baseUrl, '### ### ###')
return url.startsWith(baseUrl)
? Promise.resolve(url)
: Promise.resolve(baseUrl)
return Promise.resolve(url)
},
async jwt ({ token, user, account, profile, isNewUser }: any) {
console.log('### jwt', token, user, account, profile, isNewUser, '### ### ###')
......
......@@ -8,7 +8,7 @@ import { GetServerSideProps } from 'next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import { useOne, useShow, useApiUrl } from '@refinedev/core'
import { Show } from '@refinedev/mui'
import { List } from '@refinedev/mui'
import Link from '@mui/material/Link'
const Item = styled(Paper)(({ theme }) => ({
......@@ -22,11 +22,10 @@ const Item = styled(Paper)(({ theme }) => ({
const Info = () => {
const { queryResult: { data, isLoading } } = useShow({ resource: 'info', id: '' })
console.log('info', data, isLoading)
const apiUrl = useApiUrl()
return (
<Show>
<List title="About">
<Box>
<Stack>
<Item>FDO Manager WebUI Version: {FDO_MANAGER_WEBUI_VERSION}</Item>
......@@ -35,7 +34,7 @@ const Info = () => {
<Item>FDO Manager SDK Version: {data?.data?.fdoSdkVersion}</Item>
</Stack>
</Box>
</Show>
</List>
)
}
......
import * as React from 'react'
import Button from '@mui/material/Button'
import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import Avatar from '@mui/material/Avatar'
import { useGetIdentity, useLogout, useLogin, useTranslate } from '@refinedev/core'
interface IUser {
name: string
avatar: string
}
const Login = () => {
const t = useTranslate()
const { mutate: login } = useLogin()
return (
<Button
style={{ width: '140px' }}
// size="large"
variant="contained"
onClick={() => { login({}) }}
>
{t('pages.login.signin', 'Sign in')}
</Button>
)
}
const UserMenu = ({ user }: any) => {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null)
const open = Boolean(anchorEl)
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget)
}
const handleClose = () => {
setAnchorEl(null)
}
const { mutate: logout } = useLogout()
return (
<>
<Stack
direction="row"
gap="16px"
alignItems="center"
justifyContent="center"
>
{user?.name && (
<Button
id="user-button"
aria-controls={open ? 'user-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
sx={{ padding: '0' }}
onClick={handleClick}
>
<Typography
sx={{
display: {
xs: 'none',
sm: 'inline-block'
}
}}
variant="subtitle2"
>
{user?.name}
</Typography>
</Button>
)}
<Avatar src={user?.avatar} alt={user?.name} />
</Stack>
<Menu
id="user-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
'aria-labelledby': 'user-button'
}}
>
{/* <MenuItem onClick={handleClose}>Profile</MenuItem> */}
{/* <MenuItem onClick={handleClose}>My account</MenuItem> */}
<MenuItem onClick={() => { logout() }}>Logout</MenuItem>
</Menu>
</>
)
}
export default function UserComponent () {
const { data: user } = useGetIdentity<IUser>()
return (user?.name ? <UserMenu user={user}/> : <Login/>)
}
......@@ -10,16 +10,11 @@ import Select from '@mui/material/Select'
import Stack from '@mui/material/Stack'
import Toolbar from '@mui/material/Toolbar'
import Typography from '@mui/material/Typography'
import { useGetIdentity } from '@refinedev/core'
import { HamburgerMenu, type RefineThemedLayoutV2HeaderProps } from '@refinedev/mui'
import { HamburgerMenu, RefineThemedLayoutV2HeaderProps } from '@refinedev/mui'
import Link from 'next/link'
import { useRouter } from 'next/router'
import React, { useContext } from 'react'
interface IUser {
name: string
avatar: string
}
import UserComponent from './UserComponent'
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
sticky = true
......@@ -27,8 +22,6 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
const { mode, setMode } = useContext(ColorModeContext)
const { locale: currentLocale, locales, pathname, query } = useRouter()
const { data: user } = useGetIdentity<IUser>()
return (
<AppBar position={sticky ? 'sticky' : 'relative'}>
<Toolbar>
......@@ -102,29 +95,7 @@ export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({
{mode === 'dark' ? <LightModeOutlined /> : <DarkModeOutlined />}
</IconButton>
{(user?.avatar || user?.name) && (
<Stack
direction="row"
gap="16px"
alignItems="center"
justifyContent="center"
>
{user?.name && (
<Typography
sx={{
display: {
xs: 'none',
sm: 'inline-block'
}
}}
variant="subtitle2"
>
{user?.name}
</Typography>
)}
<Avatar src={user?.avatar} alt={user?.name} />
</Stack>
)}
<UserComponent/>
</Stack>
</Stack>
</Toolbar>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment