Refactoring to Typescript...
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import Router from 'preact-router'
|
||||
import { route } from 'preact-router'
|
||||
import { useEffect } from 'preact/hooks'
|
||||
import { AdminPage } from './pages/Admin.jsx'
|
||||
import { AdminPage } from './pages/Admin'
|
||||
|
||||
import { HomePage } from './pages/Home.jsx'
|
||||
import { LoginPage } from './pages/Login.jsx'
|
||||
import { ProblemPage } from './pages/Problem.jsx'
|
||||
import { ProfilePage } from './pages/Profile.jsx'
|
||||
import { HomePage } from './pages/Home'
|
||||
import { LoginPage } from './pages/Login'
|
||||
import { ProblemPage } from './pages/Problem'
|
||||
import { ProfilePage } from './pages/Profile'
|
||||
|
||||
const Redirect = ({ to }) => {
|
||||
const Redirect = ({ to }: { default: boolean; to: string }) => {
|
||||
useEffect(() => {
|
||||
route(to, true)
|
||||
}, [])
|
||||
@@ -20,7 +20,7 @@ const Redirect = ({ to }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export const App = ({ url }) => {
|
||||
export const App = ({ url }: { url?: string }) => {
|
||||
return (
|
||||
<Router url={url}>
|
||||
<HomePage path="/" />
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Link } from 'preact-router/match'
|
||||
import { isAdministrator, USER_ROLE_ADMIN, USER_ROLE_MODERATOR } from '../../shared/constants.js'
|
||||
|
||||
const ROLE_LABEL = {
|
||||
admin: 'Admin',
|
||||
moderator: 'Moderatore',
|
||||
[USER_ROLE_ADMIN]: 'Admin',
|
||||
[USER_ROLE_MODERATOR]: 'Moderatore',
|
||||
}
|
||||
|
||||
export const Header = ({ user, noLogin }) => (
|
||||
@@ -13,7 +14,7 @@ export const Header = ({ user, noLogin }) => (
|
||||
<nav>
|
||||
{user ? (
|
||||
<>
|
||||
{user.role !== 'student' && (
|
||||
{isAdministrator(user.role) && (
|
||||
<div class="nav-item">
|
||||
<Link activeClassName="active" href="/admin">
|
||||
Pannello Admin
|
||||
@@ -22,8 +23,8 @@ export const Header = ({ user, noLogin }) => (
|
||||
)}
|
||||
<div class="nav-item">
|
||||
<Link activeClassName="active" href="/profile">
|
||||
@{user.username}
|
||||
{user.role !== 'student' && <> ({ROLE_LABEL[user.role]})</>}
|
||||
@{user.id}
|
||||
{isAdministrator(user.role) && <> ({ROLE_LABEL[user.role]})</>}
|
||||
</Link>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Markdown } from './Markdown.jsx'
|
||||
|
||||
export const Problem = ({ id, content, createdBy }) => {
|
||||
export const Problem = ({ id, content, solutionsCount }) => {
|
||||
return (
|
||||
<div class="problem">
|
||||
<div class="problem-header">
|
||||
@@ -11,6 +11,11 @@ export const Problem = ({ id, content, createdBy }) => {
|
||||
<div class="problem-content">
|
||||
<Markdown source={content} />
|
||||
</div>
|
||||
{solutionsCount > 0 && (
|
||||
<div class="problem-footer">
|
||||
{solutionsCount} soluzion{solutionsCount === 1 ? 'e' : 'i'}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { refToUserId } from '../../shared/db-refs.js'
|
||||
import { Markdown } from './Markdown.jsx'
|
||||
|
||||
export const Solution = ({ userId, problemId, content }) => {
|
||||
export const Solution = ({ sentBy, forProblem, content }) => {
|
||||
const userId = refToUserId(sentBy)
|
||||
const problemId = refToUserId(forProblem)
|
||||
|
||||
return (
|
||||
<div class="solution">
|
||||
<div class="solution-header">
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import { hydrate } from 'preact'
|
||||
import { App } from './App.jsx'
|
||||
|
||||
hydrate(<App />, document.body)
|
||||
@@ -0,0 +1,4 @@
|
||||
import { hydrate } from 'preact'
|
||||
import { App } from './App'
|
||||
|
||||
// hydrate(<App />, document.body)
|
||||
@@ -1,13 +1,15 @@
|
||||
import renderToString from 'preact-render-to-string'
|
||||
import { App } from './App.jsx'
|
||||
import { MetadataContext } from './hooks.jsx'
|
||||
// import { App } from './App'
|
||||
import { MetadataContext } from './hooks'
|
||||
|
||||
export function render(url) {
|
||||
import { RenderedPage } from '../shared/ssr'
|
||||
|
||||
export default (url: string): RenderedPage => {
|
||||
const metadata = {}
|
||||
|
||||
const html = renderToString(
|
||||
<MetadataContext.Provider value={metadata}>
|
||||
<App url={url} />
|
||||
{/* <App url={url} /> */}
|
||||
</MetadataContext.Provider>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { route } from 'preact-router'
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import { isAdministrator, isStudent } from '../../shared/constants.js'
|
||||
import { server } from '../api.jsx'
|
||||
import { Header } from '../components/Header.jsx'
|
||||
import { MarkdownEditor } from '../components/MarkdownEditor.jsx'
|
||||
@@ -27,7 +28,7 @@ export const AdminPage = ({}) => {
|
||||
const [user] = useCurrentUser(user => {
|
||||
if (!user) {
|
||||
route('/login', true)
|
||||
} else if (user.role !== 'admin' && user.role !== 'moderator') {
|
||||
} else if (isStudent(user.role)) {
|
||||
route('/', true)
|
||||
}
|
||||
})
|
||||
@@ -10,6 +10,8 @@ export const HomePage = () => {
|
||||
const [user] = useCurrentUser()
|
||||
const [problems] = useReadResource('/api/problems', [])
|
||||
|
||||
console.log(problems)
|
||||
|
||||
return (
|
||||
<main class="page-home">
|
||||
<Header {...{ user }} />
|
||||
@@ -13,7 +13,7 @@ export const LoginPage = () => {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username,
|
||||
id: username,
|
||||
}),
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ export const ProblemPage = ({ id }) => {
|
||||
|
||||
const sendSolution = async () => {
|
||||
await server.post('/api/solution', {
|
||||
problemId: id,
|
||||
forProblem: id,
|
||||
content: source,
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ export const ProfilePage = ({}) => {
|
||||
route('/login', true)
|
||||
}
|
||||
|
||||
setSolutions(await server.get(`/api/solutions?user=${user.username}`))
|
||||
setSolutions(await server.get(`/api/solutions?user=${user.id}`))
|
||||
})
|
||||
|
||||
const handleLogout = () => {
|
||||
@@ -27,8 +27,8 @@ export const ProfilePage = ({}) => {
|
||||
<Header {...{ user }} />
|
||||
<div class="subtitle">Le tue soluzioni</div>
|
||||
<div class="solution-list">
|
||||
{solutions.map(({ problemId, content }) => (
|
||||
<Solution {...{ problemId, content }} />
|
||||
{solutions.map(({ forProblem, content }) => (
|
||||
<Solution {...{ forProblem, content }} />
|
||||
))}
|
||||
</div>
|
||||
<div class="subtitle">Altro</div>
|
||||
+16
-9
@@ -22,7 +22,7 @@ body {
|
||||
|
||||
font-family: 'Lato', sans-serif;
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
|
||||
line-height: 1;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ input[type='text'] {
|
||||
cursor: pointer;
|
||||
font-family: 'Lato';
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
|
||||
border: 1px solid #c8c8c8;
|
||||
@@ -102,7 +102,7 @@ input[type='text'] {
|
||||
|
||||
font-family: 'Lato';
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ button {
|
||||
|
||||
font-family: 'Lato';
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
color: #555;
|
||||
|
||||
border: 1px solid #c8c8c8;
|
||||
@@ -199,7 +199,7 @@ $heading-scale: 1.25;
|
||||
.text-body {
|
||||
font-family: 'EB Garamond', serif;
|
||||
font-weight: 400;
|
||||
font-size: 21px;
|
||||
font-size: 18px;
|
||||
|
||||
line-height: 1.41;
|
||||
|
||||
@@ -232,7 +232,7 @@ main {
|
||||
gap: 2rem;
|
||||
|
||||
.subtitle {
|
||||
font-size: 24px;
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +301,9 @@ header {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
|
||||
.nav-item {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
@@ -327,7 +330,7 @@ header {
|
||||
background: #ffffff;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
gap: 0.5rem;
|
||||
|
||||
.problem-header {
|
||||
@@ -336,7 +339,7 @@ header {
|
||||
gap: 0.25rem;
|
||||
|
||||
.problem-title {
|
||||
font-size: 24px;
|
||||
font-size: 22px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
@@ -344,6 +347,10 @@ header {
|
||||
.problem-content {
|
||||
@extend .text-body;
|
||||
}
|
||||
|
||||
.problem-footer {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.solution {
|
||||
@@ -420,7 +427,7 @@ header {
|
||||
|
||||
textarea {
|
||||
font-family: 'DM Mono', monospace;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
|
||||
resize: none;
|
||||
overflow-y: hidden;
|
||||
|
||||
Reference in New Issue
Block a user