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

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32">
<title>KYCnot.me logo with badge</title> <title>KYCnot.me logo with badge</title>
<path fill="#0080FF" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" /> <path fill="#00bfff" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
<path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" /> <path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" />
<path fill="#3BDB78" fill-rule="evenodd" <path fill="#3BDB78" fill-rule="evenodd"
d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z" d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z"

Before

Width:  |  Height:  |  Size: 619 B

After

Width:  |  Height:  |  Size: 619 B

View File

@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32">
<title>KYCnot.me logo with badge</title> <title>KYCnot.me logo with badge</title>
<path fill="#0080FF" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" /> <path fill="#fff" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
<path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" /> <path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" />
<path fill="#FF0040" fill-rule="evenodd" <path fill="#FF0040" fill-rule="evenodd"
d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z" d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z"

Before

Width:  |  Height:  |  Size: 619 B

After

Width:  |  Height:  |  Size: 616 B

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32">
<title>KYCnot.me logo with badge</title>
<path fill="#000" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
<path fill="#fff" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" />
<path fill="#FF0040" fill-rule="evenodd"
d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z"
clip-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 613 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="#ff0040" viewBox="0 0 32 32" height="32" width="32">
<title>KYCnot.me logo</title>
<path fill="#fff" d="M4 4h24v24H4z" />
<path fill-rule="evenodd"
d="M32 28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h24a4 4 0 0 1 4 4v24ZM7 6a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h7v-3c0-.6-.4-1-1-1h-6a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7Zm15 16v3c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3Zm-4-4v3c0 .6.4 1 1 1h3v-3c0-.6-.4-1-1-1h-3Zm1-12a1 1 0 0 0-1 1v3c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V7c0-.6-.4-1-1-1h-3Z"
clip-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 607 B

View File

@@ -1,13 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32">
<title>KYCnot.me logo with badge</title> <title>KYCnot.me logo with badge</title>
<style> <path fill="#fff" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
@media (prefers-color-scheme: light) {
.a {
fill: #0080ff;
}
}
</style>
<path fill="#ff0040" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
<path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" /> <path fill="#040505" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" />
<path fill="#00ffff" class="a" fill-rule="evenodd" <path fill="#00ffff" class="a" fill-rule="evenodd"
d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z" d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z"

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 626 B

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32">
<title>KYCnot.me logo with badge</title>
<path fill="#000" d="M32 8a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z" />
<path fill="#fff" d="M12.7 4A12 12 0 0 0 28 19.3V28H4V4h8.7Z" />
<path fill="#0080ff" class="a" fill-rule="evenodd"
d="M15 0a12 12 0 0 0-1.4 14H11a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h6.4l.6.4V21c0 .6.4 1 1 1h3v-2.2A12 12 0 0 0 32 17V28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h11Zm7 25c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3v3Z"
clip-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 623 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32" height="32" width="32">
<title>KYCnot.me logo</title>
<path fill="#fff" class="b" d="M4 4h24v24H4z" />
<path fill="#0080ff" class="a" fill-rule="evenodd"
d="M32 28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h24a4 4 0 0 1 4 4v24ZM7 6a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h7v-3c0-.6-.4-1-1-1h-6a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7Zm15 16v3c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3Zm-4-4v3c0 .6.4 1 1 1h3v-3c0-.6-.4-1-1-1h-3Zm1-12a1 1 0 0 0-1 1v3c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V7c0-.6-.4-1-1-1h-3Z"
clip-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 639 B

View File

@@ -1,18 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32" height="32" width="32"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 32 32" height="32" width="32">
<title>KYCnot.me logo</title> <title>KYCnot.me logo</title>
<style>
@media (prefers-color-scheme: light) {
.a {
fill: #0080ff;
}
.b {
fill: #fff;
}
}
</style>
<path fill="#040505" class="b" d="M4 4h24v24H4z" /> <path fill="#040505" class="b" d="M4 4h24v24H4z" />
<path fill="#00ffff" class="" fill-rule="evenodd" <path fill="#00ffff" class="a" fill-rule="evenodd"
d="M32 28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h24a4 4 0 0 1 4 4v24ZM7 6a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h7v-3c0-.6-.4-1-1-1h-6a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7Zm15 16v3c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3Zm-4-4v3c0 .6.4 1 1 1h3v-3c0-.6-.4-1-1-1h-3Zm1-12a1 1 0 0 0-1 1v3c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V7c0-.6-.4-1-1-1h-3Z" d="M32 28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h24a4 4 0 0 1 4 4v24ZM7 6a1 1 0 0 0-1 1v18c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-6c0-.6.4-1 1-1h7v-3c0-.6-.4-1-1-1h-6a1 1 0 0 1-1-1V7c0-.6-.4-1-1-1H7Zm15 16v3c0 .6.4 1 1 1h2c.6 0 1-.4 1-1v-2c0-.6-.4-1-1-1h-3Zm-4-4v3c0 .6.4 1 1 1h3v-3c0-.6-.4-1-1-1h-3Zm1-12a1 1 0 0 0-1 1v3c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V7c0-.6-.4-1-1-1h-3Z"
clip-rule="evenodd" /> clip-rule="evenodd" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 793 B

After

Width:  |  Height:  |  Size: 642 B

View File

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

View File

@@ -100,7 +100,7 @@ const ogImageUrl = makeOgImageUrl(ogImage, Astro.url)
<!-- PWA --> <!-- PWA -->
{pwaAssetsHead.themeColor && <meta name="theme-color" content={pwaAssetsHead.themeColor.content} />} {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} />} {pwaInfo && <Fragment set:html={pwaInfo.webManifest.linkTag} />}
<DynamicFavicon /> <DynamicFavicon />

View File

@@ -25,10 +25,11 @@ function addBadgeIfUnread(href: string) {
{ {
DEPLOYMENT_MODE === 'production' && ( 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 <link
rel="icon" rel="icon"
type="image/svg+xml" type="image/svg+xml"
sizes="any"
href={addBadgeIfUnread('/favicon-lightmode.svg')} href={addBadgeIfUnread('/favicon-lightmode.svg')}
media="(prefers-color-scheme: light)" media="(prefers-color-scheme: light)"
/> />
@@ -37,12 +38,30 @@ function addBadgeIfUnread(href: string) {
} }
{ {
DEPLOYMENT_MODE === 'development' && ( 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' && ( 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( export const zodUrlOptionalProtocol = z.preprocess(
cleanUrl, 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', message: 'Invalid URL',
}) })
) )
@@ -42,7 +42,7 @@ export const zodContactMethod = z.preprocess(
.trim() .trim()
.refine( .refine(
(value) => (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 value
), ),
{ {

View File

@@ -1141,8 +1141,21 @@ const apiCalls = await Astro.locals.banners.try(
<input type="hidden" name="serviceId" value={service.id} /> <input type="hidden" name="serviceId" value={service.id} />
<InputText <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" name="label"
description="Leave empty to auto-generate"
inputProps={{ inputProps={{
value: method.label, value: method.label,
placeholder: contactMethodInfo.formattedValue, placeholder: contactMethodInfo.formattedValue,
@@ -1150,16 +1163,6 @@ const apiCalls = await Astro.locals.banners.try(
error={contactMethodUpdateInputErrors.label} 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 /> <InputSubmitButton label="Update" icon="ri:save-line" hideCancel />
</form> </form>
</div> </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"> <form method="POST" action={actions.admin.service.contactMethod.add} class="space-y-2">
<input type="hidden" name="serviceId" value={service.id} /> <input type="hidden" name="serviceId" value={service.id} />
<InputText label="Override Label" name="label" />
<InputText <InputText
label="Value" label="Value"
description={`Accepts: ${contactMethodUrlTypes.map((type) => type.labelPlural).join(', ')}`} description={`Accepts: ${contactMethodUrlTypes.map((type) => type.labelPlural).join(', ')}`}
@@ -1187,6 +1188,13 @@ const apiCalls = await Astro.locals.banners.try(
error={contactMethodAddInputErrors.value} 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 /> <InputSubmitButton label="Add" icon="ri:add-line" hideCancel />
</form> </form>
</FormSubSection> </FormSubSection>