perf: Lucide subpath imports to split 748 KB icon chunk

Barrel `from '@lucide/svelte'` imports pulled every referenced icon into
one shared 748 KB client chunk. Switch every call site to per-icon
subpaths (`@lucide/svelte/icons/<kebab-name>`) so Vite tree-shakes each
icon independently. Also logs the TODO list for the perf audit so we
don't lose track.

- 46 files, 106 unique icons
- single `Minus as MinusIcon` alias preserved
- Lucide-internal aliases (`AlertTriangle`, `BarChart3`) resolve through
  Lucide's own re-export shims; no behavioral change
This commit is contained in:
2026-04-23 14:52:39 +02:00
parent ebc59cbf6b
commit abb59f46a6
48 changed files with 1582 additions and 57 deletions
+18
View File
@@ -1,5 +1,21 @@
# TODO
## Perf (audit 2026-04-23)
Order = impact. Font items + app.html preload intentionally skipped.
- [x] 1. Lucide subpath imports — convert `from '@lucide/svelte'` barrel imports to `@lucide/svelte/icons/<kebab-name>` so Vite tree-shakes per-icon (current 748 KB shared chunk)
- [ ] 2. Chart.js dynamic import in `FitnessChart.svelte` (drop 244 KB from non-stats fitness routes)
- [ ] 3. Recipe `all_brief` endpoint — drop `JSON.parse(JSON.stringify(...))`, move shuffle client-side, enable caching
- [ ] 4. Favorites page — drop unnecessary `all_brief` fetch (verify consumer first)
- [ ] 5. Replace redundant `locals.auth()` with `locals.session` across recipe/calendar/fitness loaders
- [ ] 6. Stream fitness stats loader — return promises for slow panels
- [ ] 7. Overview endpoint — add `.select(...)` projection, cap timeseries window
- [ ] 8. Calendar payload trim — drop `name` from `yearDays`, pre-filter `feastDots` server-side
- [ ] 9. History sessions endpoint — slim exercise payload for list view
- [ ] 10. `Cache-Control` headers on stable API endpoints (all_brief, calendar, exercises metadata)
- [ ] 11. Search — debounce 200 ms + server-side pre-normalized `_searchKey`
## Features
[x] on /fitness/measure, fill "Past measurements" in SSR only for the last 10 measurements. anything further should be fetched client side on mount to decreae initial page load time. use a "show more" button and paginate measurments.
[x] on /fitness/measure (resp. their associated logging API routes), consolidate measurements by day. If we want to log another measurement, overwriting an old one, show a warning to indicate this. disparate measurements (e.g., weight and bodyfat) should not show this warning but simply be merged into one log entry for that day.
@@ -8,6 +24,8 @@
[x] BF graph (with trend line like weight graph) on /fitness/stats page. Emphasize relative changes, not absolute numbers in design (as we cannot trust those) (e.g., use start day of overview as 0% and then show +/- x % on the graph)
[x] Workshop better names than "Measure" for the /fitness/measure route. It's about body data points (i.e., non-food related). What's a better, short name than "Measure" to capture the logging of weight, body composition, body part measurements, and period tracking?
[x] on /fitness/stats/histoy/<part> for body measurement graphs, make the range reasonable. e.g., if we have 1 cm change, do not fill the entire y-height with 1 cm. Use reasonable padding for low ranges (i think we do something like htis already on the weight graph?)
[ ] Make the Period ended button a lot more prominent
[ ] swap heart emoji on recipe favorites to lucide icon
## Refactor Recipe Search Component
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "homepage",
"version": "1.46.11",
"version": "1.46.12",
"private": true,
"type": "module",
"scripts": {
+3 -2
View File
@@ -1,6 +1,7 @@
<script>
import { ChevronLeft, ChevronRight, Calendar } from '@lucide/svelte';
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import Calendar from '@lucide/svelte/icons/calendar';
let { value = $bindable(''), lang = 'en', min = '', max = '' } = $props();
let open = $state(false);
+5 -2
View File
@@ -1,7 +1,10 @@
<script lang="ts">
import type { Snippet, Component } from 'svelte';
import { Lock, Ban, SearchX, TriangleAlert, CircleAlert } from '@lucide/svelte';
import Lock from '@lucide/svelte/icons/lock';
import Ban from '@lucide/svelte/icons/ban';
import SearchX from '@lucide/svelte/icons/search-x';
import TriangleAlert from '@lucide/svelte/icons/triangle-alert';
import CircleAlert from '@lucide/svelte/icons/circle-alert';
interface BibleQuote {
text: string;
reference: string;
+3 -1
View File
@@ -1,6 +1,8 @@
<script>
import { themeStore } from '$lib/stores/theme.svelte';
import { Sun, Moon, SunMoon } from '@lucide/svelte';
import Sun from '@lucide/svelte/icons/sun';
import Moon from '@lucide/svelte/icons/moon';
import SunMoon from '@lucide/svelte/icons/sun-moon';
</script>
<style>
+1 -1
View File
@@ -1,5 +1,5 @@
<script>
import { X } from '@lucide/svelte';
import X from '@lucide/svelte/icons/x';
import { getToasts } from '$lib/js/toast.svelte';
const toasts = getToasts();
@@ -2,7 +2,9 @@
import { browser } from '$app/environment';
import { getAngelusStreak, getCurrentTimeSlot, type TimeSlot } from '$lib/stores/angelusStreak.svelte';
import StreakAura from '$lib/components/faith/StreakAura.svelte';
import { Coffee, Sun, Moon } from '@lucide/svelte';
import Coffee from '@lucide/svelte/icons/coffee';
import Sun from '@lucide/svelte/icons/sun';
import Moon from '@lucide/svelte/icons/moon';
import { tick, onMount } from 'svelte';
let burst = $state(false);
@@ -1,7 +1,14 @@
<script>
import { getFilterOptionsAll, searchAllExercises } from '$lib/data/exercisedb';
import { translateTerm } from '$lib/data/exercises';
import { Search, X, Cable, Cog, Dumbbell, PersonStanding, Shapes, Weight } from '@lucide/svelte';
import Search from '@lucide/svelte/icons/search';
import X from '@lucide/svelte/icons/x';
import Cable from '@lucide/svelte/icons/cable';
import Cog from '@lucide/svelte/icons/cog';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import PersonStanding from '@lucide/svelte/icons/person-standing';
import Shapes from '@lucide/svelte/icons/shapes';
import Weight from '@lucide/svelte/icons/weight';
import { page } from '$app/stores';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
+4 -1
View File
@@ -2,7 +2,10 @@
import { page } from '$app/stores';
import { browser } from '$app/environment';
import { untrack } from 'svelte';
import { Heart, ExternalLink, ScanBarcode, X } from '@lucide/svelte';
import Heart from '@lucide/svelte/icons/heart';
import ExternalLink from '@lucide/svelte/icons/external-link';
import ScanBarcode from '@lucide/svelte/icons/scan-barcode';
import X from '@lucide/svelte/icons/x';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import MacroBreakdown from './MacroBreakdown.svelte';
@@ -1,7 +1,9 @@
<script>
import { detectFitnessLang } from '$lib/js/fitnessI18n';
import { page } from '$app/stores';
import { Beef, Droplet, Wheat } from '@lucide/svelte';
import Beef from '@lucide/svelte/icons/beef';
import Droplet from '@lucide/svelte/icons/droplet';
import Wheat from '@lucide/svelte/icons/wheat';
import RingGraph from './RingGraph.svelte';
/**
@@ -1,5 +1,8 @@
<script>
import { Coffee, Sun, Moon, Cookie } from '@lucide/svelte';
import Coffee from '@lucide/svelte/icons/coffee';
import Sun from '@lucide/svelte/icons/sun';
import Moon from '@lucide/svelte/icons/moon';
import Cookie from '@lucide/svelte/icons/cookie';
import { t } from '$lib/js/fitnessI18n';
/** @type {{ value?: 'breakfast' | 'lunch' | 'dinner' | 'snack', lang?: 'en' | 'de', onchange?: (meal: 'breakfast' | 'lunch' | 'dinner' | 'snack') => void }} */
@@ -1,6 +1,12 @@
<script>
import { t } from '$lib/js/fitnessI18n';
import { Trash2, Plus, Pencil, UserPlus, X, ChevronLeft, ChevronRight } from '@lucide/svelte';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Plus from '@lucide/svelte/icons/plus';
import Pencil from '@lucide/svelte/icons/pencil';
import UserPlus from '@lucide/svelte/icons/user-plus';
import X from '@lucide/svelte/icons/x';
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import DatePicker from '$lib/components/DatePicker.svelte';
import { toast } from '$lib/js/toast.svelte';
import { confirm } from '$lib/js/confirmDialog.svelte';
@@ -1,5 +1,10 @@
<script>
import { Plus, ChevronDown, Sparkles, Beef, Droplet, Wheat } from '@lucide/svelte';
import Plus from '@lucide/svelte/icons/plus';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import Sparkles from '@lucide/svelte/icons/sparkles';
import Beef from '@lucide/svelte/icons/beef';
import Droplet from '@lucide/svelte/icons/droplet';
import Wheat from '@lucide/svelte/icons/wheat';
import { untrack } from 'svelte';
import { toast } from '$lib/js/toast.svelte';
import { t } from '$lib/js/fitnessI18n';
@@ -1,7 +1,12 @@
<script>
import { page } from '$app/stores';
import { getExerciseById, getExerciseMetrics } from '$lib/data/exercises';
import { Clock, Weight, Trophy, Route, Gauge, Flame } from '@lucide/svelte';
import Clock from '@lucide/svelte/icons/clock';
import Weight from '@lucide/svelte/icons/weight';
import Trophy from '@lucide/svelte/icons/trophy';
import Route from '@lucide/svelte/icons/route';
import Gauge from '@lucide/svelte/icons/gauge';
import Flame from '@lucide/svelte/icons/flame';
import { detectFitnessLang, fitnessSlugs } from '$lib/js/fitnessI18n';
const lang = $derived(detectFitnessLang($page.url.pathname));
+4 -1
View File
@@ -1,5 +1,8 @@
<script>
import { Check, X, Play, Square } from '@lucide/svelte';
import Check from '@lucide/svelte/icons/check';
import X from '@lucide/svelte/icons/x';
import Play from '@lucide/svelte/icons/play';
import Square from '@lucide/svelte/icons/square';
import { METRIC_LABELS } from '$lib/data/exercises';
import RestTimer from './RestTimer.svelte';
import { page } from '$app/stores';
@@ -1,6 +1,8 @@
<script>
import { Cloud, CloudOff, RefreshCw, AlertTriangle } from '@lucide/svelte';
import Cloud from '@lucide/svelte/icons/cloud';
import CloudOff from '@lucide/svelte/icons/cloud-off';
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
import AlertTriangle from '@lucide/svelte/icons/alert-triangle';
/** @type {{ status: string }} */
let { status } = $props();
</script>
@@ -1,6 +1,7 @@
<script>
import { getExerciseById } from '$lib/data/exercises';
import { EllipsisVertical, MapPin } from '@lucide/svelte';
import EllipsisVertical from '@lucide/svelte/icons/ellipsis-vertical';
import MapPin from '@lucide/svelte/icons/map-pin';
import { page } from '$app/stores';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
@@ -1,6 +1,5 @@
<script>
import { X } from '@lucide/svelte';
import X from '@lucide/svelte/icons/x';
let { src, poster = '', onClose } = $props();
/** @param {KeyboardEvent} e */
+2 -1
View File
@@ -1,6 +1,7 @@
<script>
import { goto } from '$app/navigation';
import { Play, Pause } from '@lucide/svelte';
import Play from '@lucide/svelte/icons/play';
import Pause from '@lucide/svelte/icons/pause';
import SyncIndicator from '$lib/components/fitness/SyncIndicator.svelte';
import { page } from '$app/stores';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
@@ -1,5 +1,6 @@
<script>
import { UtensilsCrossed, X } from '@lucide/svelte';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import X from '@lucide/svelte/icons/x';
import { toast } from '$lib/js/toast.svelte';
let {
@@ -4,8 +4,12 @@ import Pen from '$lib/assets/icons/Pen.svelte'
import Cross from '$lib/assets/icons/Cross.svelte'
import Plus from '$lib/assets/icons/Plus.svelte'
import Check from '$lib/assets/icons/Check.svelte'
import { Timer, Wheat, Croissant, Flame, CookingPot, UtensilsCrossed } from '@lucide/svelte';
import Timer from '@lucide/svelte/icons/timer';
import Wheat from '@lucide/svelte/icons/wheat';
import Croissant from '@lucide/svelte/icons/croissant';
import Flame from '@lucide/svelte/icons/flame';
import CookingPot from '@lucide/svelte/icons/cooking-pot';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import "$lib/css/action_button.css"
import { do_on_key } from '$lib/components/recipes/do_on_key.js'
@@ -1,5 +1,10 @@
<script>
import { Timer, Wheat, Croissant, Flame, CookingPot, UtensilsCrossed } from '@lucide/svelte';
import Timer from '@lucide/svelte/icons/timer';
import Wheat from '@lucide/svelte/icons/wheat';
import Croissant from '@lucide/svelte/icons/croissant';
import Flame from '@lucide/svelte/icons/flame';
import CookingPot from '@lucide/svelte/icons/cooking-pot';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
let { data } = $props();
// svelte-ignore state_referenced_locally
@@ -1,5 +1,6 @@
<script>
import { ChevronLeft, ChevronRight } from '@lucide/svelte';
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import { getStickerById } from '$lib/utils/stickers';
import {
startOfMonth, endOfMonth, startOfWeek, endOfWeek,
+14 -2
View File
@@ -1,6 +1,18 @@
<script>
import { X, Sparkles, Wind, Bath, UtensilsCrossed, CookingPot, WashingMachine,
Flower2, Droplets, Leaf, ShoppingCart, Trash2, Shirt, Brush } from '@lucide/svelte';
import X from '@lucide/svelte/icons/x';
import Sparkles from '@lucide/svelte/icons/sparkles';
import Wind from '@lucide/svelte/icons/wind';
import Bath from '@lucide/svelte/icons/bath';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import CookingPot from '@lucide/svelte/icons/cooking-pot';
import WashingMachine from '@lucide/svelte/icons/washing-machine';
import Flower2 from '@lucide/svelte/icons/flower-2';
import Droplets from '@lucide/svelte/icons/droplets';
import Leaf from '@lucide/svelte/icons/leaf';
import ShoppingCart from '@lucide/svelte/icons/shopping-cart';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Shirt from '@lucide/svelte/icons/shirt';
import Brush from '@lucide/svelte/icons/brush';
import ProfilePicture from '$lib/components/cospend/ProfilePicture.svelte';
import Toggle from '$lib/components/Toggle.svelte';
import DatePicker from '$lib/components/DatePicker.svelte';
@@ -8,7 +8,10 @@
import Header from '$lib/components/Header.svelte';
import UserHeader from '$lib/components/UserHeader.svelte';
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
import { LayoutDashboard, Wallet, RefreshCw, ShoppingCart } from '@lucide/svelte';
import LayoutDashboard from '@lucide/svelte/icons/layout-dashboard';
import Wallet from '@lucide/svelte/icons/wallet';
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
import ShoppingCart from '@lucide/svelte/icons/shopping-cart';
import { detectCospendLang, cospendRoot, cospendLabels } from '$lib/js/cospendI18n';
let { data, children } = $props();
@@ -2,7 +2,22 @@
import { onMount, onDestroy, untrack } from 'svelte';
import { getShoppingSync } from '$lib/js/shoppingSync.svelte';
import { SHOPPING_CATEGORIES } from '$lib/data/shoppingCategoryItems';
import { Plus, ListX, Apple, Beef, Milk, Croissant, Wheat, FlameKindling, GlassWater, Candy, Snowflake, SprayCan, Sparkles, Package, Search, Store } from '@lucide/svelte';
import Plus from '@lucide/svelte/icons/plus';
import ListX from '@lucide/svelte/icons/list-x';
import Apple from '@lucide/svelte/icons/apple';
import Beef from '@lucide/svelte/icons/beef';
import Milk from '@lucide/svelte/icons/milk';
import Croissant from '@lucide/svelte/icons/croissant';
import Wheat from '@lucide/svelte/icons/wheat';
import FlameKindling from '@lucide/svelte/icons/flame-kindling';
import GlassWater from '@lucide/svelte/icons/glass-water';
import Candy from '@lucide/svelte/icons/candy';
import Snowflake from '@lucide/svelte/icons/snowflake';
import SprayCan from '@lucide/svelte/icons/spray-can';
import Sparkles from '@lucide/svelte/icons/sparkles';
import Package from '@lucide/svelte/icons/package';
import Search from '@lucide/svelte/icons/search';
import Store from '@lucide/svelte/icons/store';
import SyncIndicator from '$lib/components/fitness/SyncIndicator.svelte';
import { flip } from 'svelte/animate';
import { slide } from 'svelte/transition';
@@ -10,7 +25,13 @@
import catalogData from '$lib/data/shoppingCatalog.json';
import iconCategoriesData from '$lib/data/shoppingIconCategories.json';
import { Share2, X, Copy, Check } from '@lucide/svelte';
import Share2 from '@lucide/svelte/icons/share-2';
import X from '@lucide/svelte/icons/x';
import Copy from '@lucide/svelte/icons/copy';
import Check from '@lucide/svelte/icons/check';
import { page } from '$app/stores';
import { detectCospendLang, t, locale, categoryName, formatTTL as formatTTLi18n, ttlOptions } from '$lib/js/cospendI18n';
@@ -27,7 +27,7 @@ import MysteryImageColumn from "./MysteryImageColumn.svelte";
import { mysteries, mysteriesLatin, mysteriesEnglish, mysteryTitles, mysteryTitlesEnglish, mysteryTitlesLatin, allMysteryImages, getLabels, getLabelsLatin, getMysteryForWeekday, BEAD_SPACING, DECADE_OFFSET, sectionPositions } from "./rosaryData.js";
import { isEastertide, getLiturgicalSeason } from "$lib/js/easter.svelte";
import { setupScrollSync } from "./rosaryScrollSync.js";
import { BookOpen } from "@lucide/svelte";
import BookOpen from '@lucide/svelte/icons/book-open';
let { data } = $props();
// Toggle for including Luminous mysteries (initialized from URL param or default)
@@ -1,5 +1,6 @@
<script>
import { ArrowDown, ArrowLeft } from '@lucide/svelte';
import ArrowDown from '@lucide/svelte/icons/arrow-down';
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
import { page } from '$app/stores';
/** @type {number | string | null} */
let expanded = $state(null);
@@ -45,7 +45,12 @@ onNavigate((navigation) => {
import UserHeader from '$lib/components/UserHeader.svelte';
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
import OfflineSyncButton from '$lib/components/OfflineSyncButton.svelte';
import { BookOpen, Heart, Leaf, LayoutGrid, Palette, Tag } from '@lucide/svelte';
import BookOpen from '@lucide/svelte/icons/book-open';
import Heart from '@lucide/svelte/icons/heart';
import Leaf from '@lucide/svelte/icons/leaf';
import LayoutGrid from '@lucide/svelte/icons/layout-grid';
import Palette from '@lucide/svelte/icons/palette';
import Tag from '@lucide/svelte/icons/tag';
let { data, children } = $props();
let user = $derived(data.session?.user);
+6 -1
View File
@@ -4,7 +4,12 @@
import Header from '$lib/components/Header.svelte';
import UserHeader from '$lib/components/UserHeader.svelte';
import LanguageSelector from '$lib/components/LanguageSelector.svelte';
import { BarChart3, Clock, Dumbbell, ListChecks, NotebookPen, UtensilsCrossed } from '@lucide/svelte';
import BarChart3 from '@lucide/svelte/icons/bar-chart-3';
import Clock from '@lucide/svelte/icons/clock';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import ListChecks from '@lucide/svelte/icons/list-checks';
import NotebookPen from '@lucide/svelte/icons/notebook-pen';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import { getWorkout } from '$lib/js/workout.svelte';
import { getWorkoutSync } from '$lib/js/workoutSync.svelte';
import WorkoutFab from '$lib/components/fitness/WorkoutFab.svelte';
@@ -1,6 +1,18 @@
<script>
import { page } from '$app/stores';
import { Pencil, Trash2, ChevronRight, Venus, Mars, Weight, Percent, Plus, Minus, X, Check, UserCog, Sparkles } from '@lucide/svelte';
import Pencil from '@lucide/svelte/icons/pencil';
import Trash2 from '@lucide/svelte/icons/trash-2';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import Venus from '@lucide/svelte/icons/venus';
import Mars from '@lucide/svelte/icons/mars';
import Weight from '@lucide/svelte/icons/weight';
import Percent from '@lucide/svelte/icons/percent';
import Plus from '@lucide/svelte/icons/plus';
import Minus from '@lucide/svelte/icons/minus';
import X from '@lucide/svelte/icons/x';
import Check from '@lucide/svelte/icons/check';
import UserCog from '@lucide/svelte/icons/user-cog';
import Sparkles from '@lucide/svelte/icons/sparkles';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
import { toast } from '$lib/js/toast.svelte';
import { confirm } from '$lib/js/confirmDialog.svelte';
@@ -1,7 +1,16 @@
<script>
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { Minus, Plus, X, ArrowLeft, ArrowRight, Check, Ruler, CopyPlus, TrendingUp, History } from '@lucide/svelte';
import Minus from '@lucide/svelte/icons/minus';
import Plus from '@lucide/svelte/icons/plus';
import X from '@lucide/svelte/icons/x';
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
import ArrowRight from '@lucide/svelte/icons/arrow-right';
import Check from '@lucide/svelte/icons/check';
import Ruler from '@lucide/svelte/icons/ruler';
import CopyPlus from '@lucide/svelte/icons/copy-plus';
import TrendingUp from '@lucide/svelte/icons/trending-up';
import History from '@lucide/svelte/icons/history';
import { fly, fade } from 'svelte/transition';
import { cubicOut } from 'svelte/easing';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
@@ -4,7 +4,7 @@
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
import { toast } from '$lib/js/toast.svelte';
import { confirm } from '$lib/js/confirmDialog.svelte';
import { Trash2 } from '@lucide/svelte';
import Trash2 from '@lucide/svelte/icons/trash-2';
import SaveFab from '$lib/components/SaveFab.svelte';
import DatePicker from '$lib/components/DatePicker.svelte';
@@ -1,6 +1,14 @@
<script>
import { page } from '$app/stores';
import { Search, Cable, Cog, Dumbbell, PersonStanding, Shapes, Weight, BicepsFlexed, Layers } from '@lucide/svelte';
import Search from '@lucide/svelte/icons/search';
import Cable from '@lucide/svelte/icons/cable';
import Cog from '@lucide/svelte/icons/cog';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import PersonStanding from '@lucide/svelte/icons/person-standing';
import Shapes from '@lucide/svelte/icons/shapes';
import Weight from '@lucide/svelte/icons/weight';
import BicepsFlexed from '@lucide/svelte/icons/biceps-flexed';
import Layers from '@lucide/svelte/icons/layers';
import { getFilterOptionsAll, searchAllExercises, isStretchType } from '$lib/data/exercisedb';
import { translateTerm } from '$lib/data/exercises';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
@@ -20,8 +20,7 @@
}
}
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { ChevronRight } from '@lucide/svelte';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
const lang = $derived(detectFitnessLang($page.url.pathname));
const s = $derived(fitnessSlugs(lang));
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
@@ -1,6 +1,7 @@
<script>
import { page as appPage } from '$app/stores';
import { ChevronLeft, ChevronRight } from '@lucide/svelte';
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import SessionCard from '$lib/components/fitness/SessionCard.svelte';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
@@ -1,7 +1,21 @@
<script>
import { goto, invalidateAll } from '$app/navigation';
import { page } from '$app/stores';
import { Clock, Weight, Trophy, Trash2, Pencil, Plus, Upload, Download, Route, X, RefreshCw, Gauge, Flame, Info, Mountain } from '@lucide/svelte';
import Clock from '@lucide/svelte/icons/clock';
import Weight from '@lucide/svelte/icons/weight';
import Trophy from '@lucide/svelte/icons/trophy';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Pencil from '@lucide/svelte/icons/pencil';
import Plus from '@lucide/svelte/icons/plus';
import Upload from '@lucide/svelte/icons/upload';
import Download from '@lucide/svelte/icons/download';
import Route from '@lucide/svelte/icons/route';
import X from '@lucide/svelte/icons/x';
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
import Gauge from '@lucide/svelte/icons/gauge';
import Flame from '@lucide/svelte/icons/flame';
import Info from '@lucide/svelte/icons/info';
import Mountain from '@lucide/svelte/icons/mountain';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { confirm } from '$lib/js/confirmDialog.svelte';
import { toast } from '$lib/js/toast.svelte';
@@ -1,7 +1,29 @@
<script>
import { page } from '$app/stores';
import { goto, invalidateAll } from '$app/navigation';
import { ChevronLeft, ChevronRight, Plus, Trash2, ChevronDown, Settings, Coffee, Sun, Moon, Cookie, Utensils, Info, UtensilsCrossed, AlertTriangle, Check, GlassWater, Pencil, Heart, Clock, Search, Beef, Droplet, Wheat } from '@lucide/svelte';
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
import ChevronRight from '@lucide/svelte/icons/chevron-right';
import Plus from '@lucide/svelte/icons/plus';
import Trash2 from '@lucide/svelte/icons/trash-2';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import Settings from '@lucide/svelte/icons/settings';
import Coffee from '@lucide/svelte/icons/coffee';
import Sun from '@lucide/svelte/icons/sun';
import Moon from '@lucide/svelte/icons/moon';
import Cookie from '@lucide/svelte/icons/cookie';
import Utensils from '@lucide/svelte/icons/utensils';
import Info from '@lucide/svelte/icons/info';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import AlertTriangle from '@lucide/svelte/icons/alert-triangle';
import Check from '@lucide/svelte/icons/check';
import GlassWater from '@lucide/svelte/icons/glass-water';
import Pencil from '@lucide/svelte/icons/pencil';
import Heart from '@lucide/svelte/icons/heart';
import Clock from '@lucide/svelte/icons/clock';
import Search from '@lucide/svelte/icons/search';
import Beef from '@lucide/svelte/icons/beef';
import Droplet from '@lucide/svelte/icons/droplet';
import Wheat from '@lucide/svelte/icons/wheat';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import AddButton from '$lib/components/AddButton.svelte';
import FoodSearch from '$lib/components/fitness/FoodSearch.svelte';
@@ -1,6 +1,11 @@
<script>
import { page } from '$app/stores';
import { ChevronDown, ExternalLink, Heart, Beef, Droplet, Wheat } from '@lucide/svelte';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import ExternalLink from '@lucide/svelte/icons/external-link';
import Heart from '@lucide/svelte/icons/heart';
import Beef from '@lucide/svelte/icons/beef';
import Droplet from '@lucide/svelte/icons/droplet';
import Wheat from '@lucide/svelte/icons/wheat';
import { toast } from '$lib/js/toast.svelte';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { NUTRIENT_META } from '$lib/data/dailyReferenceIntake';
@@ -1,7 +1,11 @@
<script>
import { page } from '$app/stores';
import { untrack } from 'svelte';
import { Plus, Trash2, Pencil, UtensilsCrossed, X } from '@lucide/svelte';
import Plus from '@lucide/svelte/icons/plus';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Pencil from '@lucide/svelte/icons/pencil';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import X from '@lucide/svelte/icons/x';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { toast } from '$lib/js/toast.svelte';
import { confirm } from '$lib/js/confirmDialog.svelte';
@@ -3,7 +3,17 @@
import { page } from '$app/stores';
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
import MuscleHeatmap from '$lib/components/fitness/MuscleHeatmap.svelte';
import { Dumbbell, Route, Flame, Weight, Beef, Droplet, Wheat, Scale, Target, Info, Ruler } from '@lucide/svelte';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import Route from '@lucide/svelte/icons/route';
import Flame from '@lucide/svelte/icons/flame';
import Weight from '@lucide/svelte/icons/weight';
import Beef from '@lucide/svelte/icons/beef';
import Droplet from '@lucide/svelte/icons/droplet';
import Wheat from '@lucide/svelte/icons/wheat';
import Scale from '@lucide/svelte/icons/scale';
import Target from '@lucide/svelte/icons/target';
import Info from '@lucide/svelte/icons/info';
import Ruler from '@lucide/svelte/icons/ruler';
import FitnessStreakAura from '$lib/components/fitness/FitnessStreakAura.svelte';
import PeriodTracker from '$lib/components/fitness/PeriodTracker.svelte';
import { onMount } from 'svelte';
@@ -1,6 +1,10 @@
<script>
import { page } from '$app/stores';
import { ArrowLeft, Ruler, TrendingUp, TrendingDown, Minus as MinusIcon } from '@lucide/svelte';
import ArrowLeft from '@lucide/svelte/icons/arrow-left';
import Ruler from '@lucide/svelte/icons/ruler';
import TrendingUp from '@lucide/svelte/icons/trending-up';
import TrendingDown from '@lucide/svelte/icons/trending-down';
import MinusIcon from '@lucide/svelte/icons/minus';
import { detectFitnessLang, t } from '$lib/js/fitnessI18n';
import FitnessChart from '$lib/components/fitness/FitnessChart.svelte';
import { bodyPartAccent } from '$lib/js/fitnessBodyParts';
@@ -2,7 +2,21 @@
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { Plus, Trash2, Play, Pencil, X, Save, CalendarClock, ChevronUp, ChevronDown, ArrowRight, MapPin, Dumbbell, Timer, BookOpen, Check } from '@lucide/svelte';
import Plus from '@lucide/svelte/icons/plus';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Play from '@lucide/svelte/icons/play';
import Pencil from '@lucide/svelte/icons/pencil';
import X from '@lucide/svelte/icons/x';
import Save from '@lucide/svelte/icons/save';
import CalendarClock from '@lucide/svelte/icons/calendar-clock';
import ChevronUp from '@lucide/svelte/icons/chevron-up';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import ArrowRight from '@lucide/svelte/icons/arrow-right';
import MapPin from '@lucide/svelte/icons/map-pin';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import Timer from '@lucide/svelte/icons/timer';
import BookOpen from '@lucide/svelte/icons/book-open';
import Check from '@lucide/svelte/icons/check';
import { getWorkout } from '$lib/js/workout.svelte';
import { getWorkoutSync } from '$lib/js/workoutSync.svelte';
import { flattenIntervals } from '$lib/js/gps.svelte';
@@ -1,7 +1,25 @@
<script>
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { Trash2, Play, Pause, Trophy, Clock, Dumbbell, Route, RefreshCw, Check, ChevronUp, ChevronDown, Flame, MapPin, Volume2, X, Timer, Plus, GripVertical, Repeat } from '@lucide/svelte';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Play from '@lucide/svelte/icons/play';
import Pause from '@lucide/svelte/icons/pause';
import Trophy from '@lucide/svelte/icons/trophy';
import Clock from '@lucide/svelte/icons/clock';
import Dumbbell from '@lucide/svelte/icons/dumbbell';
import Route from '@lucide/svelte/icons/route';
import RefreshCw from '@lucide/svelte/icons/refresh-cw';
import Check from '@lucide/svelte/icons/check';
import ChevronUp from '@lucide/svelte/icons/chevron-up';
import ChevronDown from '@lucide/svelte/icons/chevron-down';
import Flame from '@lucide/svelte/icons/flame';
import MapPin from '@lucide/svelte/icons/map-pin';
import Volume2 from '@lucide/svelte/icons/volume-2';
import X from '@lucide/svelte/icons/x';
import Timer from '@lucide/svelte/icons/timer';
import Plus from '@lucide/svelte/icons/plus';
import GripVertical from '@lucide/svelte/icons/grip-vertical';
import Repeat from '@lucide/svelte/icons/repeat';
import { detectFitnessLang, fitnessSlugs, t } from '$lib/js/fitnessI18n';
import { confirm } from '$lib/js/confirmDialog.svelte';
import { toast } from '$lib/js/toast.svelte';
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2,8 +2,8 @@
import { page } from '$app/stores';
import Header from '$lib/components/Header.svelte';
import UserHeader from '$lib/components/UserHeader.svelte';
import { ClipboardList, Trophy } from '@lucide/svelte';
import ClipboardList from '@lucide/svelte/icons/clipboard-list';
import Trophy from '@lucide/svelte/icons/trophy';
let { data, children } = $props();
let user = $derived(data.session?.user);
+20 -3
View File
@@ -3,9 +3,26 @@
import { confirm } from '$lib/js/confirmDialog.svelte';
import { formatDistanceToNow, isPast, isToday, differenceInDays, format } from 'date-fns';
import { de } from 'date-fns/locale';
import { Plus, Check, Pencil, Trash2, Tag, Users, RotateCcw, Calendar,
Sparkles, Wind, Bath, UtensilsCrossed, CookingPot, WashingMachine,
Flower2, Droplets, Leaf, ShoppingCart, Shirt, Brush } from '@lucide/svelte';
import Plus from '@lucide/svelte/icons/plus';
import Check from '@lucide/svelte/icons/check';
import Pencil from '@lucide/svelte/icons/pencil';
import Trash2 from '@lucide/svelte/icons/trash-2';
import Tag from '@lucide/svelte/icons/tag';
import Users from '@lucide/svelte/icons/users';
import RotateCcw from '@lucide/svelte/icons/rotate-ccw';
import Calendar from '@lucide/svelte/icons/calendar';
import Sparkles from '@lucide/svelte/icons/sparkles';
import Wind from '@lucide/svelte/icons/wind';
import Bath from '@lucide/svelte/icons/bath';
import UtensilsCrossed from '@lucide/svelte/icons/utensils-crossed';
import CookingPot from '@lucide/svelte/icons/cooking-pot';
import WashingMachine from '@lucide/svelte/icons/washing-machine';
import Flower2 from '@lucide/svelte/icons/flower-2';
import Droplets from '@lucide/svelte/icons/droplets';
import Leaf from '@lucide/svelte/icons/leaf';
import ShoppingCart from '@lucide/svelte/icons/shopping-cart';
import Shirt from '@lucide/svelte/icons/shirt';
import Brush from '@lucide/svelte/icons/brush';
import { fly, scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
import TaskForm from '$lib/components/tasks/TaskForm.svelte';
+1 -1
View File
@@ -6,7 +6,7 @@
import { de } from 'date-fns/locale';
import { scale } from 'svelte/transition';
import { flip } from 'svelte/animate';
import { Trash2 } from '@lucide/svelte';
import Trash2 from '@lucide/svelte/icons/trash-2';
import StickerCalendar from '$lib/components/tasks/StickerCalendar.svelte';
import StickerPopup from '$lib/components/tasks/StickerPopup.svelte';