Migliorato editor con preview markdown e latex #1

Merged
aziis98 merged 2 commits from dev into main 2 years ago

@ -29,7 +29,7 @@ export const MarkdownEditor = ({ placeholder, source, setSource }: Props) => {
return ( return (
<div class="markdown-editor"> <div class="markdown-editor">
<div class="editor"> <div class="editor">
<h1>Editor</h1> <div class="label">Editor</div>
<textarea <textarea
onInput={e => setSource(e.target instanceof HTMLTextAreaElement ? e.target.value : '')} onInput={e => setSource(e.target instanceof HTMLTextAreaElement ? e.target.value : '')}
value={source} value={source}
@ -39,7 +39,7 @@ export const MarkdownEditor = ({ placeholder, source, setSource }: Props) => {
></textarea> ></textarea>
</div> </div>
<div class="preview"> <div class="preview">
<h1>Preview</h1> <div class="label">Preview</div>
<div class="preview-content"> <div class="preview-content">
{source.trim().length ? <Markdown source={source} /> : <div class="placeholder">{placeholder}</div>} {source.trim().length ? <Markdown source={source} /> : <div class="placeholder">{placeholder}</div>}
</div> </div>

@ -36,19 +36,23 @@ const CreateProblem = ({}) => {
} }
return ( return (
<> <div class="create-problem-form">
<div class="problem-title"> <div class="col">
<label>Titolo</label> <label for="create-problem-title">Titolo</label>
<input <input
type="text" type="text"
id="create-problem-title"
value={title} value={title}
onInput={e => setTitle(e.target instanceof HTMLInputElement ? e.target.value : '')} onInput={e => setTitle(e.target instanceof HTMLInputElement ? e.target.value : '')}
placeholder="Problema..." placeholder="Problema..."
/> />
</div> </div>
<MarkdownEditor placeholder="Scrivi un nuovo problema..." {...{ source, setSource }} /> <div class="col">
<label>Testo</label>
<MarkdownEditor placeholder="Scrivi un nuovo problema..." {...{ source, setSource }} />
</div>
<button onClick={handleCreateProblem}>Aggiungi Problema</button> <button onClick={handleCreateProblem}>Aggiungi Problema</button>
</> </div>
) )
} }

@ -1,4 +1,4 @@
$device-s-width: 640px; $device-s-width: 925px;
$device-m-width: 1200px; $device-m-width: 1200px;
:root { :root {
@ -234,6 +234,29 @@ hr {
border-bottom: 2px dotted #555; border-bottom: 2px dotted #555;
} }
.math {
max-width: 100%;
overflow-x: auto;
}
.math.math-inline {
display: inline-grid;
}
@media screen and (min-width: $device-m-width) {
.math {
max-width: 100%;
overflow-x: auto;
}
}
@media screen and (max-width: $device-m-width) {
.math {
max-width: calc(100vw - 3.5rem);
overflow-x: auto;
}
}
.math-inline { .math-inline {
font-size: 95%; font-size: 95%;
} }
@ -285,10 +308,19 @@ $heading-scale: 1.25;
display: flex; display: flex;
gap: 0.5rem; gap: 0.5rem;
align-items: center; align-items: center;
}
.col {
width: 100%;
display: flex;
gap: 0.5rem;
align-items: center;
@media screen and (max-width: $device-s-width), (pointer: coarse) { label {
flex-direction: column; align-self: start;
width: 100%; display: grid;
place-content: center;
} }
} }
@ -336,10 +368,18 @@ main {
.title { .title {
font-size: 32px; font-size: 32px;
@media screen and (max-width: $device-s-width), (pointer: coarse) {
text-align: center;
}
} }
.subtitle { .subtitle {
font-size: 28px; font-size: 28px;
@media screen and (max-width: $device-s-width), (pointer: coarse) {
text-align: center;
}
} }
.info { .info {
@ -759,27 +799,45 @@ header {
} }
.markdown-editor { .markdown-editor {
display: grid; display: flex;
width: 100%; flex-direction: row;
grid-template-columns: repeat(2, 1fr);
gap: 1rem; box-shadow: -2px 4px 6px 1px #00000018, 0 0 4px 0px #00000010;
border-radius: 0.25rem;
background: #ffffff;
// gap: 1rem;
.editor, .editor,
.preview { .preview {
width: 100%; width: 100%;
max-width: 70ch; max-width: 60ch;
min-width: 25ch;
flex: 0 1 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 1rem; .label {
display: flex;
align-self: start;
font-size: 16px;
font-weight: 400;
padding: 0.5rem;
}
} }
.editor { .editor {
justify-self: end; justify-self: end;
.label {
right: 0;
}
textarea { textarea {
font-family: 'DM Mono', monospace; font-family: 'DM Mono', monospace;
font-size: 16px; font-size: 16px;
@ -787,13 +845,23 @@ header {
resize: none; resize: none;
overflow-y: hidden; overflow-y: hidden;
min-height: 8rem; min-height: 12rem;
box-shadow: none;
border-radius: unset;
background: none;
} }
} }
.preview { .preview {
justify-self: start; justify-self: start;
border-left: 1px solid #ddd;
.label {
left: 0;
}
.placeholder { .placeholder {
color: #666; color: #666;
} }
@ -805,9 +873,32 @@ header {
padding: 1rem; padding: 1rem;
box-shadow: -2px 4px 6px 1px #00000018, 0 0 4px 0px #00000010; word-break: break-word;
border-radius: 0.25rem; }
background: #ffffff; }
@media screen and (max-width: $device-m-width), (pointer: coarse) {
flex-direction: column;
max-width: 100%;
.editor textarea,
.preview .preview-content {
padding: 0.75rem;
}
.editor {
textarea {
min-height: 3rem;
}
}
.preview {
border-left: none;
border-top: 1px solid #ddd;
.preview-content {
min-height: 4rem;
}
} }
} }
} }
@ -817,8 +908,13 @@ header {
// //
main.page-admin { main.page-admin {
.problem-title { .create-problem-form {
@extend .row; display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
} }
.users-table { .users-table {
@ -888,11 +984,6 @@ main.page-admin {
padding: 0.75rem; padding: 0.75rem;
} }
.markdown-editor {
grid-template-columns: auto;
grid-template-rows: auto auto;
}
.form { .form {
width: 100%; width: 100%;
padding: 1rem; padding: 1rem;
@ -907,10 +998,10 @@ main.page-admin {
} }
} }
textarea, // textarea,
.markdown-editor .preview .preview-content { // .markdown-editor .preview .preview-content {
padding: 0.75rem; // padding: 0.75rem;
} // }
.solution { .solution {
.solution-content { .solution-content {
@ -923,13 +1014,13 @@ main.page-admin {
} }
@media screen and (max-width: $device-m-width), (pointer: coarse) { @media screen and (max-width: $device-m-width), (pointer: coarse) {
.markdown-editor { // .markdown-editor {
grid-template-columns: auto; // grid-template-columns: auto;
grid-template-rows: auto auto; // grid-template-rows: auto auto;
.preview, // .preview,
.editor { // .editor {
justify-self: center; // justify-self: center;
} // }
} // }
} }

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PHC | Problemi</title> <title>PHC | Problemi</title>
<link rel="icon" type="image/png" href="/favicon/android-chrome-512x512.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

Binary file not shown.

@ -0,0 +1,6 @@
This favicon was generated using the following font:
- Font Title: Lato
- Font Author: Copyright (c) 2010-2011 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.
- Font Source: http://fonts.gstatic.com/s/lato/v23/S6uyw4BMUTPHvxk6XweuBCY.ttf
- Font License: SIL Open Font License, 1.1 (http://scripts.sil.org/OFL))

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
Loading…
Cancel
Save