remove emojis with real icons
All checks were successful
Test and deploy staging / staging (push) Successful in 1m46s
All checks were successful
Test and deploy staging / staging (push) Successful in 1m46s
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
|
||||
const projects = [
|
||||
{ name: 'catchemall', href: '/projects/catch-em-all', external: false },
|
||||
@@ -30,18 +32,22 @@
|
||||
rel="external"
|
||||
class="flex items-center justify-between gap-4 py-5 hover:text-[var(--site-muted)]"
|
||||
>
|
||||
<span>{project.name}</span><span aria-hidden="true" class="text-[var(--site-muted)]"
|
||||
>↗</span
|
||||
>
|
||||
<span>{project.name}</span><ExternalLink
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{:else}
|
||||
<a
|
||||
href={resolve(project.href)}
|
||||
class="flex items-center justify-between gap-4 py-5 hover:text-[var(--site-muted)]"
|
||||
>
|
||||
<span>{project.name}</span><span aria-hidden="true" class="text-[var(--site-muted)]"
|
||||
>↗</span
|
||||
>
|
||||
<span>{project.name}</span><ArrowRight
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{/if}
|
||||
</li>
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import { onMount, onDestroy, tick } from 'svelte';
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
import PawPrint from 'lucide-svelte/icons/paw-print';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
import type { Map as MaptilerMap, Marker as MaptilerMarker } from '@maptiler/sdk';
|
||||
|
||||
interface TrailPoint {
|
||||
@@ -223,7 +226,11 @@
|
||||
el.style.backgroundSize = 'cover';
|
||||
el.style.backgroundPosition = 'center';
|
||||
} else {
|
||||
el.textContent = '🐾';
|
||||
el.innerHTML =
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="4" r="2"/><circle cx="18" cy="8" r="2"/><circle cx="20" cy="16" r="2"/><path d="M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.84 1.045Q6.52 17.48 4.46 16.84A3.5 3.5 0 0 1 5.5 10Z"/></svg>';
|
||||
el.style.display = 'flex';
|
||||
el.style.alignItems = 'center';
|
||||
el.style.justifyContent = 'center';
|
||||
}
|
||||
|
||||
el.onclick = () => selectAnimal(feature);
|
||||
@@ -409,7 +416,8 @@
|
||||
<button
|
||||
onclick={() => (selected = null)}
|
||||
aria-label="Close animal details"
|
||||
class="absolute top-3 right-3 rounded bg-black px-3 py-1 text-white">✕</button
|
||||
class="absolute top-3 right-3 flex h-8 w-8 items-center justify-center rounded bg-black text-white"
|
||||
><X size={18} aria-hidden="true" /></button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -450,9 +458,9 @@
|
||||
</div>
|
||||
<a
|
||||
href={resolve(`/projects/animaldex/register?animalId=${selected.animalId}`)}
|
||||
class="mt-5 inline-block text-base underline underline-offset-4"
|
||||
class="mt-5 inline-flex items-center gap-1 text-base underline underline-offset-4"
|
||||
>
|
||||
i saw this animal too ↗
|
||||
i saw this animal too <ArrowRight size={16} aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,7 +486,7 @@
|
||||
class="h-12 w-12 rounded object-cover"
|
||||
/>{:else}<span
|
||||
class="flex h-12 w-12 items-center justify-center rounded bg-[var(--site-surface)]"
|
||||
>🐾</span
|
||||
><PawPrint size={24} aria-hidden="true" /></span
|
||||
>{/if}
|
||||
<span class="min-w-0">
|
||||
<span class="block font-medium">{animal.animalName || animal.species}</span>
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
import type { PageData } from './$types';
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import Bot from 'lucide-svelte/icons/bot';
|
||||
import Check from 'lucide-svelte/icons/check';
|
||||
import MapPin from 'lucide-svelte/icons/map-pin';
|
||||
import PawPrint from 'lucide-svelte/icons/paw-print';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
@@ -40,8 +46,10 @@
|
||||
</div>
|
||||
{:else}
|
||||
<section class="mx-auto max-w-4xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a href={resolve('/projects/animaldex')} class="text-base text-[var(--site-muted)]"
|
||||
>← animaldex</a
|
||||
<a
|
||||
href={resolve('/projects/animaldex')}
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> animaldex</a
|
||||
>
|
||||
<div class="mt-5 mb-8 flex flex-wrap items-end justify-between gap-4">
|
||||
<h1 class="text-4xl font-semibold tracking-tight">animaldex admin</h1>
|
||||
@@ -65,7 +73,9 @@
|
||||
{#if item.photoUrl}
|
||||
<img src={item.photoUrl} alt="" class="h-full w-full object-cover" />
|
||||
{:else}
|
||||
<div class="flex h-full items-center justify-center text-2xl">🐾</div>
|
||||
<div class="flex h-full items-center justify-center">
|
||||
<PawPrint size={28} aria-hidden="true" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
@@ -81,8 +91,8 @@
|
||||
</span>
|
||||
</div>
|
||||
{#if item.aiBreedSuggestion}
|
||||
<p class="mt-1 text-base text-[var(--site-muted)]">
|
||||
🤖 AI: {item.aiBreedSuggestion} ({Math.round(
|
||||
<p class="mt-1 flex items-center gap-1 text-base text-[var(--site-muted)]">
|
||||
<Bot size={16} aria-hidden="true" /> AI: {item.aiBreedSuggestion} ({Math.round(
|
||||
(item.aiBreedConfidence ?? 0) * 100
|
||||
)}%)
|
||||
</p>
|
||||
@@ -97,8 +107,9 @@
|
||||
})}
|
||||
{#if item.reporterName}· by {item.reporterName}{/if}
|
||||
</p>
|
||||
<p class="mt-0.5 text-base text-[var(--site-muted)]">
|
||||
📍 {item.sightingLat.toFixed(5)}, {item.sightingLng.toFixed(5)}
|
||||
<p class="mt-0.5 flex items-center gap-1 text-base text-[var(--site-muted)]">
|
||||
<MapPin size={16} aria-hidden="true" />
|
||||
{item.sightingLat.toFixed(5)}, {item.sightingLng.toFixed(5)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -106,16 +117,22 @@
|
||||
<button
|
||||
onclick={() => moderate(item.animalId, 'accept')}
|
||||
disabled={actionLoading !== null || status === 'accepted'}
|
||||
class="flex-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
class="inline-flex flex-1 items-center justify-center gap-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
>
|
||||
{actionLoading === `animals-${item.animalId}-accept` ? '…' : '✓ Accept'}
|
||||
{#if actionLoading === `animals-${item.animalId}-accept`}…{:else}<Check
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/> Accept{/if}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => moderate(item.animalId, 'deny')}
|
||||
disabled={actionLoading !== null || status === 'denied'}
|
||||
class="flex-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
class="inline-flex flex-1 items-center justify-center gap-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
>
|
||||
{actionLoading === `animals-${item.animalId}-deny` ? '…' : '✕ Deny'}
|
||||
{#if actionLoading === `animals-${item.animalId}-deny`}…{:else}<X
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/> Deny{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
|
||||
const animalId = $derived($page.url.searchParams.get('animalId'));
|
||||
const isNewSighting = $derived(!!animalId);
|
||||
@@ -240,7 +242,8 @@
|
||||
<section class="mx-auto max-w-3xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a
|
||||
href={resolve('/projects/animaldex')}
|
||||
class="text-base text-[var(--site-muted)] hover:text-[var(--site-text)]">← animaldex</a
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)] hover:text-[var(--site-text)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> animaldex</a
|
||||
>
|
||||
<h1 class="mt-5 text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
{isNewSighting ? 'add a sighting' : 'add an animal'}
|
||||
@@ -278,7 +281,7 @@
|
||||
onclick={() => removePhoto(i)}
|
||||
aria-label={`Remove photo ${i + 1}`}
|
||||
class="absolute top-1 right-1 flex h-5 w-5 items-center justify-center rounded-full bg-black/60 text-xs text-white"
|
||||
>✕</button
|
||||
><X size={12} aria-hidden="true" /></button
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import Check from 'lucide-svelte/icons/check';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import { horses, race, type Horse } from '$lib/derby/data';
|
||||
import { scenarios } from '$lib/derby/practice';
|
||||
import { races } from '$lib/derby/races';
|
||||
@@ -497,7 +499,9 @@
|
||||
<ol class="steps">
|
||||
{#each steps as st, i (st.title)}
|
||||
<li class:done={st.done}>
|
||||
<span class="step-n">{st.done ? '✓' : i + 1}</span>
|
||||
<span class="step-n"
|
||||
>{#if st.done}<Check size={16} aria-hidden="true" />{:else}{i + 1}{/if}</span
|
||||
>
|
||||
<div>
|
||||
<a href={st.href}>{st.title}</a>
|
||||
<p>{st.detail}</p>
|
||||
@@ -969,7 +973,9 @@
|
||||
</ul>
|
||||
<div class="source-links">
|
||||
{#each race.sources as s (s.href)}
|
||||
<a href={s.href} target="_blank" rel="noreferrer">{s.label} ↗</a>
|
||||
<a href={s.href} target="_blank" rel="noreferrer"
|
||||
>{s.label} <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1915,6 +1921,9 @@
|
||||
margin-top: 16px;
|
||||
}
|
||||
.source-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 0.76rem;
|
||||
border: 1px solid #07100c;
|
||||
border-radius: 99px;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from 'svelte';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import { races, type Runner } from '$lib/derby/races';
|
||||
import { betValue, fairOdds, formatTime, placings } from '$lib/derby/model';
|
||||
import {
|
||||
@@ -708,7 +709,9 @@
|
||||
</ul>
|
||||
<div class="source-links">
|
||||
{#each race.sources as s (s.href)}
|
||||
<a href={s.href} target="_blank" rel="noreferrer">{s.label} ↗</a>
|
||||
<a href={s.href} target="_blank" rel="noreferrer"
|
||||
>{s.label} <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1518,6 +1521,9 @@
|
||||
margin-top: 16px;
|
||||
}
|
||||
.source-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 0.76rem;
|
||||
border: 1px solid #07100c;
|
||||
border-radius: 99px;
|
||||
|
||||
Reference in New Issue
Block a user