Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🦋 Currency calculator CMS #1612 #1617

Merged
merged 6 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/lib/components/CmsDesign.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import CountdownWidget from './CountdownWidget.svelte';
import GalleryWidget from './GalleryWidget/GalleryWidget.svelte';
import { page } from '$app/stores';
import CurrencyCalculator from './CurrencyCalculator.svelte';

export let products: CmsProduct[];
export let pictures: CmsPicture[];
Expand Down Expand Up @@ -181,6 +182,8 @@
: ''}{token.height ? `height: ${token.height}px;` : ''}"
/>
<PictureComponent picture={pictureById[token.slug]} class="my-5 lg:hidden block" />
{:else if token.type === 'currencyCalculatorWidget'}
<CurrencyCalculator />
{:else if token.type === 'html'}
<div class="my-5">
<!-- eslint-disable svelte/no-at-html-tags -->
Expand Down Expand Up @@ -255,6 +258,8 @@
/>
{:else if token.type === 'pictureWidget'}
<PictureComponent picture={pictureById[token.slug]} class="my-5" />
{:else if token.type === 'currencyCalculatorWidget'}
<CurrencyCalculator />
{:else if token.type === 'html'}
<div class="my-5">
<!-- eslint-disable svelte/no-at-html-tags -->
Expand Down
52 changes: 52 additions & 0 deletions src/lib/components/CurrencyCalculator.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts">
import { CURRENCIES } from '$lib/types/Currency';
import { toCurrency } from '$lib/utils/toCurrency';
import type { Currency } from '$lib/types/Currency';

$: firstCurrencyAmount = 1;
$: firstCurrency = 'BTC' as Currency;
$: secondCurrency = 'EUR' as Currency;
$: secondCurrencyAmount = toCurrency(secondCurrency, firstCurrencyAmount, firstCurrency);
</script>

<div class="flex justify-center mx-auto max-w-3xl bg-gray-800 p-4 rounded-md">
<div
class="flex items-center bg-gray-900 text-white rounded-md focus-within:ring-2 focus-within:ring-blue-500 m-1"
>
<input
type="number"
class="form-input p-2 bg-transparent text-left text-white focus:outline-none"
bind:value={firstCurrencyAmount}
min="0"
/>
<select
class="p-2 bg-gray-700 text-white border-l border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
bind:value={firstCurrency}
>
{#each CURRENCIES as currency}
<option value={currency} selected={currency === firstCurrency}>{currency}</option>
{/each}
</select>
</div>

<span class="text-gray-400 text-3xl m-1">→</span>

<div
class="flex items-center bg-gray-900 text-white rounded-md focus-within:ring-2 focus-within:ring-blue-500 m-1"
>
<input
type="text"
class="form-input p-2 bg-transparent text-left text-white focus:outline-none"
bind:value={secondCurrencyAmount}
readonly
/>
<select
class="p-2 bg-gray-700 text-white border-l border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
bind:value={secondCurrency}
>
{#each CURRENCIES as currency}
<option value={currency} selected={currency === secondCurrency}>{currency}</option>
{/each}
</select>
</div>
</div>
12 changes: 6 additions & 6 deletions src/lib/components/ProductForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -1016,9 +1016,9 @@
conf={{ plugins: TINYMCE_PLUGINS, toolbar: TINYMCE_TOOLBAR }}
/>
<p class="text-gray-700 my-3">
To include tags, add a paragraph with only <code class="font-mono">[Tag=slug]</code>,
where
<code class="font-mono">slug</code> is the slug of your tag
To include currency calculator, add a paragraph with only <code class="font-mono"
>[CurrencyCalculator=currency-calculator]</code
>
</p>
<textarea
name="contentBefore"
Expand Down Expand Up @@ -1047,9 +1047,9 @@
conf={{ plugins: TINYMCE_PLUGINS, toolbar: TINYMCE_TOOLBAR }}
/>
<p class="text-gray-700 my-3">
To include tags, add a paragraph with only <code class="font-mono">[Tag=slug]</code>,
where
<code class="font-mono">slug</code> is the slug of your tag
To include currency calculator, add a paragraph with only <code class="font-mono"
>[CurrencyCalculator=currency-calculator]</code
>
</p>
<textarea
name="contentAfter"
Expand Down
17 changes: 15 additions & 2 deletions src/lib/server/cms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ type TokenObject =
slug: string;
display: string | undefined;
raw: string;
};
}
| { type: 'currencyCalculatorWidget'; slug: string; raw: string };

export async function cmsFromContent(
{ content, mobileContent }: { content: string; mobileContent?: string },
locals: Partial<PickDeep<App.Locals, 'user.roleId' | 'language' | 'email' | 'sso'>>
Expand All @@ -98,6 +100,7 @@ export async function cmsFromContent(
/\[TagProducts=(?<slug>[\p{L}\d_-]+)(?:[?\s]display=(?<display>[a-z0-9-]+))?\]/giu;
const GALLERY_WIDGET_REGEX =
/\[Gallery=(?<slug>[\p{L}\d_-]+)(?:[?\s]display=(?<display>[a-z0-9-]+))?\]/giu;
const CURRENCY_CALCULATOR_WIDGET_REGEX = /\[CurrencyCalculator=(?<slug>[a-z0-9-]+)\]/giu;

const productSlugs = new Set<string>();
const challengeSlugs = new Set<string>();
Expand All @@ -109,6 +112,7 @@ export async function cmsFromContent(
const countdownFormSlugs = new Set<string>();
const tagProductsSlugs = new Set<string>();
const gallerySlugs = new Set<string>();
const currencyCalculatorSlugs = new Set<string>();

const tokens: {
desktop: Array<TokenObject>;
Expand Down Expand Up @@ -138,7 +142,8 @@ export async function cmsFromContent(
...matchAndSort(content, PICTURE_WIDGET_REGEX, 'pictureWidget'),
...matchAndSort(content, COUNTDOWN_WIDGET_REGEX, 'countdownWidget'),
...matchAndSort(content, TAG_PRODUCTS_REGEX, 'tagProducts'),
...matchAndSort(content, GALLERY_WIDGET_REGEX, 'galleryWidget')
...matchAndSort(content, GALLERY_WIDGET_REGEX, 'galleryWidget'),
...matchAndSort(content, CURRENCY_CALCULATOR_WIDGET_REGEX, 'currencyCalculatorWidget')
].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
for (const match of matches) {
const html = trimPrefix(trimSuffix(content.slice(index, match.index), '<p>'), '</p>');
Expand Down Expand Up @@ -245,6 +250,14 @@ export async function cmsFromContent(
raw: match[0]
});
break;
case 'currencyCalculatorWidget':
currencyCalculatorSlugs.add(match.groups.slug);
token.push({
type: 'currencyCalculatorWidget',
slug: match.groups.slug,
raw: match[0]
});
break;
}
}
index = match.index + match[0].length;
Expand Down
Loading