mirror of
https://github.com/jakobkordez/s5_practice.git
synced 2025-05-15 16:20:31 +00:00
Redesign WIP
This commit is contained in:
parent
10c15949c5
commit
601b2b944e
@ -1,13 +1,9 @@
|
||||
const withPwa = require('next-pwa')({
|
||||
dest: 'public',
|
||||
sw: 'service-worker.js',
|
||||
});
|
||||
// const withPwa = require('next-pwa')({
|
||||
// dest: 'public',
|
||||
// sw: 'service-worker.js',
|
||||
// });
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
experimental: {
|
||||
appDir: true,
|
||||
},
|
||||
}
|
||||
const nextConfig = {}
|
||||
|
||||
module.exports = withPwa(nextConfig);
|
||||
module.exports = nextConfig;
|
||||
|
19
package.json
19
package.json
@ -10,26 +10,29 @@
|
||||
"format": "prettier --write ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "18.14.0",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"@types/node": "^20.4.1",
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
"bulma": "^0.9.4",
|
||||
"eslint": "8.34.0",
|
||||
"eslint-config-next": "^13.3.0",
|
||||
"next": "^13.4.2",
|
||||
"eslint": "^8.44.0",
|
||||
"eslint-config-next": "^13.4.9",
|
||||
"next": "^13.4.9",
|
||||
"next-pwa": "^5.6.0",
|
||||
"node-sass": "^8.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-katex": "^3.0.1",
|
||||
"typescript": "4.9.5",
|
||||
"typescript": "^5.1.6",
|
||||
"zustand": "^4.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-katex": "^3.0.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"prettier": "^2.8.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"postcss": "^8.4.25",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"sass": "^1.58.3"
|
||||
}
|
||||
}
|
||||
|
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
module.exports = {
|
||||
plugins: [require('prettier-plugin-tailwindcss')],
|
||||
singleQuote: true,
|
||||
}
|
@ -69,7 +69,7 @@ export default function IzpitQuiz() {
|
||||
<>
|
||||
{state === QuizState.Ready && (
|
||||
<div className="is-flex">
|
||||
<button className="button is-primary mx-auto" onClick={load}>
|
||||
<button className="button is-primary" onClick={load}>
|
||||
Začni
|
||||
</button>
|
||||
</div>
|
||||
@ -121,7 +121,7 @@ export default function IzpitQuiz() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h1 className="is-size-3 my-3 has-text-centered">Napačni odgovori</h1>
|
||||
<h1 className="is-size-3 has-text-centered my-3">Napačni odgovori</h1>
|
||||
|
||||
{questions?.map(
|
||||
(question, qi) =>
|
||||
|
@ -45,7 +45,7 @@ export default function RootLayout({
|
||||
<body>
|
||||
<Header />
|
||||
|
||||
<main className="container">{children}</main>
|
||||
<main>{children}</main>
|
||||
|
||||
<AnalyticsWrapper />
|
||||
</body>
|
||||
|
@ -2,7 +2,8 @@ import Link from 'next/link';
|
||||
|
||||
const povezave = [
|
||||
{
|
||||
label: 'Priročnik za radioamaterje (3. izdaja)',
|
||||
label:
|
||||
'Priročnik za radioamaterje (3. izdaja - vsebuje napake in mankajo vsebine)',
|
||||
href: 'http://www.homemade.net/ra/prirocnik_novi.pdf',
|
||||
},
|
||||
{
|
||||
@ -29,21 +30,63 @@ const povezave = [
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="section content">
|
||||
<h1>Pozdravljen!</h1>
|
||||
<p>
|
||||
Na podstrani <Link href="/priprave">Priprave</Link> so vaje za pripravo
|
||||
na izpit. Vprašanja so razdeljena po kategorijah, pravilni odgovori pa
|
||||
se razkrivajo sproti.
|
||||
</p>
|
||||
<>
|
||||
<div className="w-full bg-dark text-darker">
|
||||
<div className="container flex flex-col gap-6 py-6">
|
||||
<div className="flex flex-col gap-6 text-xl font-bold md:flex-row">
|
||||
<Link
|
||||
href="#kako-zaceti"
|
||||
className="grow rounded-2xl bg-white/90 p-4 text-center shadow"
|
||||
>
|
||||
Seznam vprašanj
|
||||
</Link>
|
||||
<Link
|
||||
href="/priprave"
|
||||
className="grow rounded-2xl bg-white/90 p-4 text-center shadow"
|
||||
>
|
||||
Vadi vprašanja
|
||||
</Link>
|
||||
<Link
|
||||
href="/izpit-sim"
|
||||
className="grow rounded-2xl bg-white/90 p-4 text-center shadow"
|
||||
>
|
||||
Reši preizkusni izpit
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Na podstrani <Link href="/izpit-sim">Simulator izpita</Link> lahko
|
||||
preizkusiš svoje znanje. Vprašanja so generirana kot bi bila na
|
||||
resničnem izpitu. Pravilni odgovori se razkrijejo šele po koncu.
|
||||
</p>
|
||||
<div className="container flex flex-col gap-10 py-10">
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">Kaj je radioamaterstvo?</h3>
|
||||
</div>
|
||||
|
||||
<h2>Uporabne povezave</h2>
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">
|
||||
Katera kategorija je prava zame?
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">Kaj povzema izpit?</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">Kako začeti?</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">
|
||||
Vsebine za pripravo na izpit
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">Vaja pred izpitom</h3>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="mb-3 text-2xl font-bold">Uporabne povezave</h3>
|
||||
<ul className="list-inside list-disc">
|
||||
{povezave.map(({ label, href }) => (
|
||||
<li key={label}>
|
||||
@ -52,5 +95,7 @@ export default function Home() {
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -6,13 +6,5 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default function Priprave() {
|
||||
return (
|
||||
<div className="section">
|
||||
<div className="content">
|
||||
<h1>Priprave na izpit</h1>
|
||||
</div>
|
||||
|
||||
<VajaQuiz />
|
||||
</div>
|
||||
);
|
||||
return <VajaQuiz />;
|
||||
}
|
||||
|
@ -83,12 +83,20 @@ export default function VajaQuiz() {
|
||||
}, [questions.length, selectedCategory]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="field has-addons mb-5">
|
||||
<div className="control is-expanded">
|
||||
<div className="select is-fullwidth">
|
||||
<div className="mb-10 flex flex-col gap-10">
|
||||
<div className="bg-dark text-white">
|
||||
<div className="container flex flex-col gap-6 py-8">
|
||||
<h1 className="text-3xl font-bold">Priprava na izpit</h1>
|
||||
|
||||
<div>
|
||||
<label htmlFor="category" className="mb-2 block font-medium">
|
||||
Izberi kategorijo
|
||||
</label>
|
||||
<div className="flex flex-row gap-3">
|
||||
<select
|
||||
id="category"
|
||||
name="category"
|
||||
className="w-full flex-1 rounded-lg border border-gray-400 bg-white p-2.5 text-darker placeholder-gray-400 focus:border-blue-500 focus:ring-blue-500"
|
||||
value={selectedCategory}
|
||||
onChange={(e) => {
|
||||
const selectedCategory = e.target.value;
|
||||
@ -103,20 +111,20 @@ export default function VajaQuiz() {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="control">
|
||||
<button
|
||||
className={`button is-primary ${isLoading ? 'is-loading' : ''}`}
|
||||
onClick={() => load(selectedCategory)}
|
||||
className="rounded-lg bg-primary px-5 py-2.5 font-medium text-white disabled:opacity-70"
|
||||
disabled={isLoading}
|
||||
onClick={!isLoading ? () => load(selectedCategory) : undefined}
|
||||
>
|
||||
Naloži
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mx-auto flex max-w-xl flex-col gap-12">
|
||||
{questions.slice(0, displayed).map((question, qi) => (
|
||||
<QuestionCard
|
||||
key={qi}
|
||||
@ -136,17 +144,25 @@ export default function VajaQuiz() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="buttons mt-5 is-justify-content-end">
|
||||
<div className="mx-auto w-full max-w-xl">
|
||||
<div className="flex flex-row justify-end gap-3">
|
||||
{questions.length > displayed && (
|
||||
<button className="button is-primary is-rounded" onClick={loadMore}>
|
||||
<button
|
||||
className="rounded-lg bg-primary px-5 py-2.5 font-medium text-white"
|
||||
onClick={loadMore}
|
||||
>
|
||||
Naloži več
|
||||
</button>
|
||||
)}
|
||||
<button className="button is-primary is-rounded" onClick={scrollToTop}>
|
||||
<button
|
||||
className="rounded-lg bg-primary px-5 py-2.5 font-medium text-white"
|
||||
onClick={scrollToTop}
|
||||
>
|
||||
Na vrh
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -18,74 +18,12 @@ export default function Header() {
|
||||
const pathname = usePathname();
|
||||
|
||||
return (
|
||||
<section className="hero is-primary">
|
||||
<div className="hero-body">
|
||||
<div className="container">
|
||||
<div className="is-flex is-align-items-center">
|
||||
<figure className="image is-96x96">
|
||||
<Image
|
||||
src="/logo/logo_192.png"
|
||||
alt="Logo"
|
||||
height={96}
|
||||
width={96}
|
||||
style={{ height: '100%', width: 'auto', margin: 'auto' }}
|
||||
/>
|
||||
</figure>
|
||||
<div className="ml-4">
|
||||
<h1 className="title is-size-3">Radioamaterski izpit</h1>
|
||||
<h6 className="subtitle">Pripravil: Jakob [S52KJ]</h6>
|
||||
</div>
|
||||
<a
|
||||
role="button"
|
||||
className={`navbar-burger ${navbar ? 'is-active' : ''}`}
|
||||
aria-label="menu"
|
||||
onClick={() => setNavbar(!navbar)}
|
||||
>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hero-foot">
|
||||
<div className="container">
|
||||
<nav className="navbar">
|
||||
<div className={`navbar-menu ${navbar ? 'is-active' : ''}`}>
|
||||
<div className="navbar-start">
|
||||
{nav.map(({ href, label }) => (
|
||||
<Link
|
||||
key={href}
|
||||
className={`navbar-item ${
|
||||
href == pathname ? 'is-active' : ''
|
||||
}`}
|
||||
href={href}
|
||||
onClick={() => setNavbar(false)}
|
||||
>
|
||||
{label}
|
||||
<section className="bg-darker py-6 font-bold text-white">
|
||||
<div className="container flex flex-row items-center justify-start gap-8">
|
||||
<Image src="/logo/logo_192.png" alt="Logo" height={32} width={32} />
|
||||
<Link href="/">
|
||||
<h1 className="text-4xl">Radioamaterski izpit</h1>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className="navbar-end">
|
||||
<Link
|
||||
className="navbar-item is-flex"
|
||||
href="http://www.hamradio.si/"
|
||||
>
|
||||
<span className="icon mr-2">
|
||||
<Image
|
||||
src="/logo/zrs_logo_white.svg"
|
||||
alt="ZRS Logo"
|
||||
height={32}
|
||||
width={32}
|
||||
/>
|
||||
</span>
|
||||
<span>ZRS</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
@ -17,15 +17,15 @@ export default function QuestionCard({
|
||||
onClick,
|
||||
}: QuestionCardProps) {
|
||||
return (
|
||||
<div className="box">
|
||||
<p>{question.id}</p>
|
||||
|
||||
<div className="title is-4">
|
||||
<h3>{question.question}</h3>
|
||||
<div className="flex flex-col gap-5">
|
||||
<div className="text-xl text-gray-700">
|
||||
<span className="font-bold text-primary">
|
||||
A{question.id.toString().padStart(3, '0')}:{' '}
|
||||
</span>
|
||||
{question.question}
|
||||
</div>
|
||||
|
||||
{question.image && (
|
||||
<figure className="image">
|
||||
<Image
|
||||
className={styles.image}
|
||||
src={`/question_images/${question.image}`}
|
||||
@ -33,10 +33,9 @@ export default function QuestionCard({
|
||||
height={500}
|
||||
width={500}
|
||||
/>
|
||||
</figure>
|
||||
)}
|
||||
|
||||
<div className="buttons mt-5">
|
||||
<div className="flex flex-col gap-2">
|
||||
{question.answers.map((answer, i) => (
|
||||
<Answer
|
||||
key={i}
|
||||
@ -70,20 +69,29 @@ function Answer({
|
||||
isSelected,
|
||||
onClick,
|
||||
}: AnswerProps) {
|
||||
let className = `button is-fullwidth ${styles.answer}`;
|
||||
if (!onClick) className += ' is-static';
|
||||
if (isSelected) {
|
||||
if (reveal) {
|
||||
if (isCorrect) className += ' is-success is-light';
|
||||
else className += ' is-danger is-light';
|
||||
} else {
|
||||
className += ' is-info';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={className} onClick={onClick}>
|
||||
{String.fromCharCode(65 + index) + '. '}
|
||||
<button
|
||||
className={`flex w-full flex-row items-center gap-5 rounded border px-6 py-2 ${
|
||||
!isSelected
|
||||
? 'border-gray-300'
|
||||
: !reveal
|
||||
? 'border-sky-500 bg-sky-100'
|
||||
: isCorrect
|
||||
? 'border-green-500 bg-green-100'
|
||||
: 'border-red-600 bg-red-100'
|
||||
}`}
|
||||
disabled={!onClick}
|
||||
onClick={onClick}
|
||||
>
|
||||
{!reveal && <input type="radio" checked={isSelected} readOnly />}
|
||||
<div
|
||||
className={`border-r py-2 pr-5 text-sm font-bold ${
|
||||
!isSelected ? 'border-gray-200' : 'border-inherit'
|
||||
}`}
|
||||
>
|
||||
{String.fromCharCode(65 + index)}
|
||||
</div>
|
||||
<div className="text-left text-lg text-gray-600">
|
||||
{answer.startsWith('$') ? (
|
||||
<span className="ml-2">
|
||||
<InlineMath math={answer.slice(1, answer.length - 1)} />
|
||||
@ -91,6 +99,7 @@ function Answer({
|
||||
) : (
|
||||
answer
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@ -3,19 +3,14 @@ $container-max-width: 1200px;
|
||||
$section-padding: 2rem 1.5rem;
|
||||
$body-font-size: 1.1em;
|
||||
|
||||
@import 'bulma/sass/utilities/_all.sass';
|
||||
@import 'bulma/sass/base/_all.sass';
|
||||
@import 'bulma/sass/elements/_all.sass';
|
||||
@import 'bulma/sass/form/_all.sass';
|
||||
@import 'bulma/sass/components/_all.sass';
|
||||
@import 'bulma/sass/layout/_all.sass';
|
||||
@import 'bulma/sass/grid/_all.sass';
|
||||
@import 'bulma/sass/helpers/_all.sass';
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
@import 'katex/dist/katex.min.css';
|
||||
|
||||
.navbar {
|
||||
@include until(1024px) {
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
// .navbar {
|
||||
// @include until(1024px) {
|
||||
// min-height: 0;
|
||||
// }
|
||||
// }
|
||||
|
26
tailwind.config.js
Normal file
26
tailwind.config.js
Normal file
@ -0,0 +1,26 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
darker: "#222831",
|
||||
dark: "#393E46",
|
||||
primary: "#00ADB5",
|
||||
light: "#EEEEEE",
|
||||
}
|
||||
},
|
||||
container: {
|
||||
center: true,
|
||||
screens: {
|
||||
sm: "640px",
|
||||
md: "768px",
|
||||
lg: "1024px",
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user