Skip to content

Commit

Permalink
Add Markdown editor component and integrate it into AdventureModal
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmorley15 committed Dec 17, 2024
1 parent 7d609d0 commit dd08a6f
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 20 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"dependencies": {
"@lukulent/svelte-umami": "^0.0.3",
"emoji-picker-element": "^1.26.0",
"marked": "^15.0.4",
"qrcode": "^1.5.4",
"svelte-i18n": "^4.0.1",
"svelte-maplibre": "^0.9.8"
Expand Down
10 changes: 10 additions & 0 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions frontend/src/lib/components/AdventureModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import { appVersion } from '$lib/config';
import CategoryDropdown from './CategoryDropdown.svelte';
import { findFirstValue } from '$lib';
import MarkdownEditor from './MarkdownEditor.svelte';
let wikiError: string = '';
Expand Down Expand Up @@ -577,15 +578,10 @@
</div>
<div>
<label for="description">{$t('adventures.description')}</label><br />
<textarea
id="description"
name="description"
bind:value={adventure.description}
class="textarea textarea-bordered w-full h-32"
></textarea>
<MarkdownEditor bind:text={adventure.description} />
<div class="mt-2">
<div class="tooltip tooltip-right" data-tip={$t('adventures.wiki_desc')}>
<button type="button" class="btn btn-neutral" on:click={generateDesc}
<button type="button" class="btn btn-neutral mt-2" on:click={generateDesc}
>{$t('adventures.generate_desc')}</button
>
</div>
Expand Down
80 changes: 80 additions & 0 deletions frontend/src/lib/components/MarkdownEditor.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script lang="ts">
import { marked } from 'marked'; // Import the markdown parser
import { t } from 'svelte-i18n';
export let text: string | null | undefined = ''; // Markdown text
let is_preview: boolean = false; // Toggle between Edit and Preview mode
// Function to parse markdown to HTML
const renderMarkdown = (markdown: string) => {
return marked(markdown);
};
// References for scroll syncing
let editorRef: HTMLTextAreaElement | null = null;
let previewRef: HTMLElement | null = null;
// Sync scrolling between editor and preview
const syncScroll = () => {
if (editorRef && previewRef) {
const ratio = editorRef.scrollTop / (editorRef.scrollHeight - editorRef.clientHeight);
previewRef.scrollTop = ratio * (previewRef.scrollHeight - previewRef.clientHeight);
}
};
</script>

<div class="join justify-center mt-2">
<button
type="button"
class="join-item btn btn-sm btn-outline"
on:click={() => (is_preview = false)}
class:btn-active={!is_preview}
>
{$t('transportation.edit')}
</button>
<button
type="button"
class="join-item btn btn-sm btn-outline"
on:click={() => (is_preview = true)}
class:btn-active={is_preview}
>
{$t('adventures.preview')}
</button>
</div>

<div class="flex flex-col mt-4 gap-4">
<!-- Markdown Editor -->
{#if !is_preview}
<textarea
class="textarea textarea-bordered resize-none h-64 w-full"
bind:this={editorRef}
bind:value={text}
placeholder={$t('adventures.md_instructions')}
on:scroll={syncScroll}
></textarea>
{/if}

<!-- Markdown Preview -->
{#if is_preview}
<article
class="prose overflow-auto h-96 max-w-full w-full p-4 border border-base-300 rounded-lg bg-base-300"
bind:this={previewRef}
>
{@html renderMarkdown(text || '')}
</article>
{/if}
</div>

<style>
/* Optional: Smooth scrolling for synced scroll effect */
textarea,
article {
scroll-behavior: smooth;
}
/* Force both editor and preview to have equal width */
textarea,
article {
width: 100%;
}
</style>
4 changes: 3 additions & 1 deletion frontend/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "Emoji-Picker",
"hide": "Verstecken",
"show": "Zeigen",
"download_calendar": "Kalender herunterladen"
"download_calendar": "Kalender herunterladen",
"md_instructions": "Schreiben Sie hier Ihren Abschlag...",
"preview": "Vorschau"
},
"home": {
"desc_1": "Entdecken, planen und erkunden Sie mit Leichtigkeit",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@
"hide": "Hide",
"emoji_picker": "Emoji Picker",
"download_calendar": "Download Calendar",
"preview": "Preview",
"md_instructions": "Write your markdown here...",
"days": "days",
"activities": {
"general": "General 🌍",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@
"emoji_picker": "Selector de emojis",
"hide": "Esconder",
"show": "Espectáculo",
"download_calendar": "Descargar Calendario"
"download_calendar": "Descargar Calendario",
"md_instructions": "Escriba su descuento aquí...",
"preview": "Avance"
},
"worldtravel": {
"all": "Todo",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "Sélecteur d'émoticônes",
"hide": "Cacher",
"show": "Montrer",
"download_calendar": "Télécharger le calendrier"
"download_calendar": "Télécharger le calendrier",
"md_instructions": "Écrivez votre démarque ici...",
"preview": "Aperçu"
},
"home": {
"desc_1": "Découvrez, planifiez et explorez en toute simplicité",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "Selettore di emoji",
"hide": "Nascondere",
"show": "Spettacolo",
"download_calendar": "Scarica Calendario"
"download_calendar": "Scarica Calendario",
"md_instructions": "Scrivi qui il tuo ribasso...",
"preview": "Anteprima"
},
"home": {
"desc_1": "Scopri, pianifica ed esplora con facilità",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "Emoji-kiezer",
"hide": "Verbergen",
"show": "Show",
"download_calendar": "Agenda downloaden"
"download_calendar": "Agenda downloaden",
"md_instructions": "Schrijf hier uw korting...",
"preview": "Voorbeeld"
},
"home": {
"desc_1": "Ontdek, plan en verken met gemak",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@
"emoji_picker": "Wybór emoji",
"hide": "Ukrywać",
"show": "Pokazywać",
"download_calendar": "Pobierz Kalendarz"
"download_calendar": "Pobierz Kalendarz",
"md_instructions": "Napisz tutaj swoją przecenę...",
"preview": "Zapowiedź"
},
"worldtravel": {
"country_list": "Lista krajów",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "Emoji-väljare",
"hide": "Dölja",
"show": "Visa",
"download_calendar": "Ladda ner kalender"
"download_calendar": "Ladda ner kalender",
"md_instructions": "Skriv din avskrivning här...",
"preview": "Förhandsvisning"
},
"home": {
"desc_1": "Upptäck, planera och utforska med lätthet",
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@
"emoji_picker": "表情符号选择器",
"hide": "隐藏",
"show": "展示",
"download_calendar": "下载日历"
"download_calendar": "下载日历",
"md_instructions": "在这里写下你的标记...",
"preview": "预览"
},
"home": {
"desc_1": "轻松发现、规划和探索",
Expand Down
16 changes: 11 additions & 5 deletions frontend/src/routes/adventures/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import Lost from '$lib/assets/undraw_lost.svg';
import { DefaultMarker, MapLibre, Popup } from 'svelte-maplibre';
import { t } from 'svelte-i18n';
import { marked } from 'marked'; // Import the markdown parser
const renderMarkdown = (markdown: string) => {
return marked(markdown);
};
export let data: PageData;
console.log(data);
Expand Down Expand Up @@ -244,11 +249,12 @@
{/if}
</div>
{#if adventure.description}
<div class="grid gap-2">
<p class="text-sm text-muted-foreground" style="white-space: pre-wrap;">
{adventure.description}
</p>
</div>
<p class="text-sm text-muted-foreground" style="white-space: pre-wrap;"></p>
<article
class="prose overflow-auto h-full max-w-full p-4 border border-base-300 rounded-lg"
>
{@html renderMarkdown(adventure.description)}
</article>
{/if}
</div>
</div>
Expand Down

0 comments on commit dd08a6f

Please sign in to comment.