Release 202506091053

This commit is contained in:
pluja
2025-06-09 10:53:52 +00:00
parent 87f0f36aa1
commit 3ccd7fd395
13 changed files with 81 additions and 42 deletions

View File

@@ -307,7 +307,7 @@ export const adminServiceActions = {
input: z.object({
id: z.number().int().positive(),
label: z.string().min(1).max(50).nullable(),
value: z.string().url(),
value: zodContactMethod,
serviceId: z.number().int().positive(),
}),
handler: async (input) => {

View File

@@ -100,7 +100,7 @@ const ogImageUrl = makeOgImageUrl(ogImage, Astro.url)
<!-- PWA -->
{pwaAssetsHead.themeColor && <meta name="theme-color" content={pwaAssetsHead.themeColor.content} />}
{pwaAssetsHead.links.map((link) => <link {...link} />)}
{pwaAssetsHead.links.filter((link) => link.rel !== 'icon').map((link) => <link {...link} />)}
{pwaInfo && <Fragment set:html={pwaInfo.webManifest.linkTag} />}
<DynamicFavicon />

View File

@@ -25,10 +25,11 @@ function addBadgeIfUnread(href: string) {
{
DEPLOYMENT_MODE === 'production' && (
<>
<link rel="icon" type="image/svg+xml" href={addBadgeIfUnread('/favicon.svg')} />
<link rel="icon" type="image/svg+xml" sizes="any" href={addBadgeIfUnread('/favicon.svg')} />
<link
rel="icon"
type="image/svg+xml"
sizes="any"
href={addBadgeIfUnread('/favicon-lightmode.svg')}
media="(prefers-color-scheme: light)"
/>
@@ -37,12 +38,30 @@ function addBadgeIfUnread(href: string) {
}
{
DEPLOYMENT_MODE === 'development' && (
<link rel="icon" type="image/svg+xml" href={addBadgeIfUnread('/favicon-dev.svg')} />
<>
<link rel="icon" type="image/svg+xml" sizes="any" href={addBadgeIfUnread('/favicon-dev.svg')} />
<link
rel="icon"
type="image/svg+xml"
sizes="any"
href={addBadgeIfUnread('/favicon-dev-lightmode.svg')}
media="(prefers-color-scheme: light)"
/>
</>
)
}
{
DEPLOYMENT_MODE === 'staging' && (
<link rel="icon" type="image/svg+xml" href={addBadgeIfUnread('/favicon-stage.svg')} />
<>
<link rel="icon" type="image/svg+xml" sizes="any" href={addBadgeIfUnread('/favicon-stage.svg')} />
<link
rel="icon"
type="image/svg+xml"
sizes="any"
href={addBadgeIfUnread('/favicon-stage-lightmode.svg')}
media="(prefers-color-scheme: light)"
/>
</>
)
}

View File

@@ -21,7 +21,7 @@ const cleanUrl = (input: unknown) => {
export const zodUrlOptionalProtocol = z.preprocess(
cleanUrl,
z.string().refine((value) => /^(https?):\/\/(?=.*\.[a-z0-9]{2,})[^\s$.?#].[^\s]*$/i.test(value), {
z.string().refine((value) => /^(https?:\/\/)?[a-z0-9]+(\.[a-z0-9])*(\.[a-z0-9]{2,}).*$/i.test(value), {
message: 'Invalid URL',
})
)
@@ -42,7 +42,7 @@ export const zodContactMethod = z.preprocess(
.trim()
.refine(
(value) =>
/^((https?):\/\/(?=.*\.[a-z0-9]{2,})[^\s$.?#].[^\s]|([\d\s+\-_/()[\]*#.,]|ext|x){7,}|[0-9\s+-_\\/()[\]*#.]|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})*$/i.test(
/^((https?:\/\/)?[a-z0-9]+(\.[a-z0-9])*(\.[a-z0-9]{2,}).*|([\d\s+\-_/()[\]*#.,]|ext|x){7,}|[0-9\s+-_\\/()[\]*#.]|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})*$/i.test(
value
),
{

View File

@@ -1141,8 +1141,21 @@ const apiCalls = await Astro.locals.banners.try(
<input type="hidden" name="serviceId" value={service.id} />
<InputText
label="Override Label (Optional)"
label="Value"
description={`Accepts: ${contactMethodUrlTypes.map((type) => type.labelPlural).join(', ')}`}
name="value"
inputProps={{
required: true,
value: method.value,
placeholder: 'contact@example.com',
}}
error={contactMethodUpdateInputErrors.value}
/>
<InputText
label="Label"
name="label"
description="Leave empty to auto-generate"
inputProps={{
value: method.label,
placeholder: contactMethodInfo.formattedValue,
@@ -1150,16 +1163,6 @@ const apiCalls = await Astro.locals.banners.try(
error={contactMethodUpdateInputErrors.label}
/>
<InputText
label="Value (with protocol)"
name="value"
inputProps={{
value: method.value,
placeholder: 'e.g., mailto:contact@example.com or https://t.me/example',
}}
error={contactMethodUpdateInputErrors.value}
/>
<InputSubmitButton label="Update" icon="ri:save-line" hideCancel />
</form>
</div>
@@ -1174,8 +1177,6 @@ const apiCalls = await Astro.locals.banners.try(
<form method="POST" action={actions.admin.service.contactMethod.add} class="space-y-2">
<input type="hidden" name="serviceId" value={service.id} />
<InputText label="Override Label" name="label" />
<InputText
label="Value"
description={`Accepts: ${contactMethodUrlTypes.map((type) => type.labelPlural).join(', ')}`}
@@ -1187,6 +1188,13 @@ const apiCalls = await Astro.locals.banners.try(
error={contactMethodAddInputErrors.value}
/>
<InputText
label="Label"
description="Leave empty to auto-generate"
name="label"
inputProps={{ placeholder: 'Auto-generated' }}
/>
<InputSubmitButton label="Add" icon="ri:add-line" hideCancel />
</form>
</FormSubSection>