diff --git a/client/components/Header.tsx b/client/components/Header.tsx index e65af02..06dae1f 100644 --- a/client/components/Header.tsx +++ b/client/components/Header.tsx @@ -3,10 +3,10 @@ import { Link } from 'preact-router/match' import { isAdministrator } from '../../shared/model' import { prependBaseUrl } from '../../shared/utils' -import { useCurrentUser } from '../hooks/useCurrentUser' +import { useLoggedInUser } from '../hooks/useCurrentUser' export const Header = ({}) => { - const [user] = useCurrentUser() + const [user] = useLoggedInUser() return (
diff --git a/client/components/Solution.tsx b/client/components/Solution.tsx index 4c7a01d..6f564e8 100644 --- a/client/components/Solution.tsx +++ b/client/components/Solution.tsx @@ -3,7 +3,7 @@ import { JSX } from 'preact/jsx-runtime' import { ProblemId, Solution as SolutionModel, SolutionId, SolutionStatus, UserId } from '../../shared/model' import { prependBaseUrl } from '../../shared/utils' import { server } from '../api' -import { useCurrentUser } from '../hooks/useCurrentUser' +import { useLoggedInUser } from '../hooks/useCurrentUser' import { Markdown } from './Markdown' const STATUS_SELECT_OPTIONS: Record = { @@ -37,7 +37,7 @@ export const Solution = ({ setSolution, refreshSolution, }: Props) => { - const [user] = useCurrentUser() + const [user] = useLoggedInUser() const markAsCorrect = async () => { setSolution?.(prevSolution => ({ ...prevSolution, status: 'correct' })) diff --git a/client/hooks/useCurrentUser.tsx b/client/hooks/useCurrentUser.tsx index e331bd2..55b0f60 100644 --- a/client/hooks/useCurrentUser.tsx +++ b/client/hooks/useCurrentUser.tsx @@ -16,7 +16,7 @@ const UserContext = createContext(null) type CurrentUserHook = () => [User | null, boolean] -export const useCurrentUser: CurrentUserHook = () => { +export const useLoggedInUser: CurrentUserHook = () => { const userContext = useContext(UserContext) if (!userContext) { return [null, false] diff --git a/client/pages/AdminPage.tsx b/client/pages/AdminPage.tsx index 274a290..b2160b2 100644 --- a/client/pages/AdminPage.tsx +++ b/client/pages/AdminPage.tsx @@ -10,7 +10,7 @@ import { MarkdownEditor } from '../components/MarkdownEditor' import { Select } from '../components/Select' import { Solution } from '../components/Solution' import { useListResource } from '../hooks' -import { useCurrentUser } from '../hooks/useCurrentUser' +import { useLoggedInUser } from '../hooks/useCurrentUser' const CreateProblem = ({}) => { const [source, setSource] = useState('') @@ -55,7 +55,7 @@ const CreateProblem = ({}) => { type SortOrder = 'latest' | 'oldest' export const AdminPage = ({}) => { - const [user, ready] = useCurrentUser() + const [user, ready] = useLoggedInUser() if (!ready) { return <> } @@ -134,7 +134,7 @@ export const AdminPage = ({}) => { <>
Controlli speciali solo per Admin
- + {/* TODO: make this work */}
@@ -145,7 +145,9 @@ export const AdminPage = ({}) => { {users.map(user => ( <> -
{user.id}
+
{user.fullName}
{user.role}
diff --git a/client/pages/ProblemPage.tsx b/client/pages/ProblemPage.tsx index b54f2af..8d3b457 100644 --- a/client/pages/ProblemPage.tsx +++ b/client/pages/ProblemPage.tsx @@ -8,7 +8,7 @@ import { MarkdownEditor } from '../components/MarkdownEditor' import { Problem } from '../components/Problem' import { Solution } from '../components/Solution' import { MetadataContext, useListResource, useResource, ServerContext, DatabaseContext, useServerAsyncCallback } from '../hooks' -import { useCurrentUser } from '../hooks/useCurrentUser' +import { useLoggedInUser } from '../hooks/useCurrentUser' type RouteProps = { id: string @@ -27,7 +27,7 @@ export const ProblemPage = ({ id }: RouteProps) => { }) } - const [user] = useCurrentUser() + const [user] = useLoggedInUser() const [source, setSource] = useState('') diff --git a/client/pages/ProfilePage.tsx b/client/pages/ProfilePage.tsx index ea310e0..8cf47e9 100644 --- a/client/pages/ProfilePage.tsx +++ b/client/pages/ProfilePage.tsx @@ -5,10 +5,10 @@ import { prependBaseUrl } from '../../shared/utils' import { Header } from '../components/Header' import { Solution } from '../components/Solution' import { useResource } from '../hooks' -import { useCurrentUser, useUserFunctions } from '../hooks/useCurrentUser' +import { useLoggedInUser, useUserFunctions } from '../hooks/useCurrentUser' export const ProfilePage = ({}) => { - const [user, ready] = useCurrentUser() + const [user, ready] = useLoggedInUser() if (!ready) { return <> } diff --git a/client/pages/UserPage.tsx b/client/pages/UserPage.tsx index efc164e..5766fda 100644 --- a/client/pages/UserPage.tsx +++ b/client/pages/UserPage.tsx @@ -1,28 +1,36 @@ -import { isAdministrator, Solution as SolutionModel, SolutionStat } from '../../shared/model' +import { route } from 'preact-router' +import { isAdministrator, Solution as SolutionModel, SolutionStat, SolutionStatMap, User } from '../../shared/model' import { sortByStringKey } from '../../shared/utils' import { prependBaseUrl } from '../../shared/utils' import { Header } from '../components/Header' import { Solution } from '../components/Solution' import { useResource } from '../hooks' -import { useCurrentUser } from '../hooks/useCurrentUser' +import { useLoggedInUser } from '../hooks/useCurrentUser' type RouteProps = { uid: string } export const UserPage = ({ uid }: RouteProps) => { - const [user, ready] = useCurrentUser() - if (!ready) { - return <> - } + // ottengo l'utente loggato, se è un admin le soluzioni devono mostrare i controlli speciali per admin + const [currentUser] = useLoggedInUser() + + // ottengo le info sull'utente di questa pagina + const [user] = useResource(`/api/user/${uid}`, null, user => { + if (!user) { + route(prependBaseUrl(`/error?message=${encodeURIComponent(`Non c'è ancora nessun utente con username "${uid}"`)}`), true) + } + }) - const [stats] = useResource>(`/api/stats`, null) + // ottengo gli stat per l'utente di questa pagina + const [stats] = useResource(`/api/stats`, null) if (!stats) { return <> } const userStats = stats[uid] + // ottengo le soluzioni pubbliche dell'utente di questa pagina const [solutions, refreshSolutions] = useResource(`/api/solutions?user=${uid}&public`, []) const sortedSolutions = sortByStringKey(solutions, s => s.createdAt, false) @@ -48,7 +56,7 @@ export const UserPage = ({ uid }: RouteProps) => { ))}
diff --git a/server/routes.ts b/server/routes.ts index 106a8af..426e001 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -405,29 +405,29 @@ export async function createApiRouter(): Promise<[Router, DatabaseConnection]> { }) r.get('/api/user/:id', async (req, res) => { - const user = await getRequestUser(req) + // const user = await getRequestUser(req) - // intanto l'utente deve essere loggato - if (!user) { - res.sendStatus(StatusCodes.UNAUTHORIZED) - return - } + // // intanto l'utente deve essere loggato + // if (!user) { + // res.sendStatus(StatusCodes.UNAUTHORIZED) + // return + // } - // solo gli amministratori possono usare questa route - if (!isAdministrator(user.role)) { - res.sendStatus(StatusCodes.UNAUTHORIZED) - return - } + // // solo gli amministratori possono usare questa route + // if (!isAdministrator(user.role)) { + // res.sendStatus(StatusCodes.UNAUTHORIZED) + // return + // } - const requestedUser = await getUser(db, req.params.id) + const user = await getUser(db, req.params.id) // l'utente richiesto magari deve esistere - if (!requestedUser) { + if (!user) { res.sendStatus(404) return } - res.json(requestedUser) + res.json(user) }) return [r, createDatabaseWrapper(db)] diff --git a/shared/model.ts b/shared/model.ts index 2f78a4f..6e36708 100644 --- a/shared/model.ts +++ b/shared/model.ts @@ -57,6 +57,8 @@ export type SolutionStatus = 'pending' | 'correct' | 'wrong' export type SolutionId = Id +export type SolutionStatMap = Record + export type SolutionStat = { sentSolutionsCount: number correctSolutionsCount: number