Add dracaena and common issues section

main
trivernis 6 months ago
parent 7d10404744
commit ae6d3f818f
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

69
package-lock.json generated

@ -9,7 +9,9 @@
"version": "0.0.1",
"dependencies": {
"fp-ts": "^2.16.1",
"io-ts": "^2.2.20"
"io-ts": "^2.2.20",
"slugify": "^1.6.6",
"svelte-markdown": "^0.4.0"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^2.0.0",
@ -30,7 +32,6 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
"integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@ -404,7 +405,6 @@
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@ -418,7 +418,6 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
"integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
@ -427,7 +426,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
@ -435,14 +433,12 @@
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.20",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
"integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@ -749,8 +745,12 @@
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
},
"node_modules/@types/marked": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.2.tgz",
"integrity": "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg=="
},
"node_modules/@types/pug": {
"version": "2.0.9",
@ -780,7 +780,6 @@
"version": "8.11.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
"integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
@ -805,7 +804,6 @@
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
"dev": true,
"dependencies": {
"dequal": "^2.0.3"
}
@ -814,7 +812,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
"integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==",
"dev": true,
"dependencies": {
"dequal": "^2.0.3"
}
@ -984,7 +981,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
"integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
"@types/estree": "^1.0.1",
@ -1068,7 +1064,6 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"dev": true,
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
@ -1131,7 +1126,6 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -1234,7 +1228,6 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0"
}
@ -1578,7 +1571,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
"integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==",
"dev": true,
"dependencies": {
"@types/estree": "*"
}
@ -1595,8 +1587,7 @@
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"dev": true
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="
},
"node_modules/lorem-ipsum": {
"version": "2.0.8",
@ -1630,7 +1621,6 @@
"version": "0.30.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz",
"integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==",
"dev": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
@ -1638,11 +1628,21 @@
"node": ">=12"
}
},
"node_modules/marked": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz",
"integrity": "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 16"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"dev": true
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
},
"node_modules/merge2": {
"version": "1.4.1",
@ -1841,7 +1841,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
"integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^3.0.0",
@ -2285,6 +2284,14 @@
"node": ">= 10"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/sorcery": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz",
@ -2304,7 +2311,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -2365,7 +2371,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.3.tgz",
"integrity": "sha512-sqmG9KC6uUc7fb3ZuWoxXvqk6MI9Uu4ABA1M0fYDgTlFYu1k02xp96u6U9+yJZiVm84m9zge7rrA/BNZdFpOKw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
@ -2419,6 +2424,18 @@
"svelte": "^3.19.0 || ^4.0.0"
}
},
"node_modules/svelte-markdown": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/svelte-markdown/-/svelte-markdown-0.4.0.tgz",
"integrity": "sha512-d8xYJoPhhiLn/tFrO54V5p22q2+I7It8w3CpTv+O+h99LlgehxK9XwdISVBl2aNcLbLX128Nz/vu7GScWhVZjw==",
"dependencies": {
"@types/marked": "^5.0.1",
"marked": "^5.1.2"
},
"peerDependencies": {
"svelte": "^4.0.0"
}
},
"node_modules/svelte-preprocess": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.0.tgz",

@ -26,6 +26,8 @@
"type": "module",
"dependencies": {
"fp-ts": "^2.16.1",
"io-ts": "^2.2.20"
"io-ts": "^2.2.20",
"slugify": "^1.6.6",
"svelte-markdown": "^0.4.0"
}
}

@ -0,0 +1,46 @@
slug = "dracaena-fragrans"
name = "Dracaena Fragrans"
bin_name = "Dracaena Fragrans"
[image]
remote = "https://upload.wikimedia.org/wikipedia/commons/6/64/Dracaena_fragrans_a1.jpg"
source = "https://commons.wikimedia.org/wiki/File:Dracaena_fragrans_a1.jpg"
alt = """
Dracaena Fragrans. \
A plant with long leaves with a dark green middle part and \
yellow edges on the leaves. The plant grows a green stalk with \
leaves on it."""
[temp]
death = 10
lower = 18
upper = 25
[site]
description = """
Dracaena Fragrans grows best in a shade with at most some direct sun exposure. It can grow in normal humidity. If Dracaena Fragrans gets too much light, its leaves will be scorced. If it get's too little light newly grown leaves will be smaller.
"""
light = "shade, some sun"
humidity = "normal"
[care]
description = """
Dracaena Fragrans needs to be watered every twelve days when the top layer starts to dry out. But on't let the soil dry out completely. To increase humidity mist the plant weekly. It can be fertilized ever month with common fertilizer.
"""
water_schedule = "12 days"
mist_schedule = "week"
fertilize_schedule = "month"
[common_issues]
description = """
### Root Rot
Signs for root rot might be yellow and dull leaves. In that case check the
roots for any visible rot (mushy roots are an indicator). The plant can be saved
by cutting away the rotten roots.
### Pests
Frequently Check the underside of leaves for any infestations.
"""

@ -1,9 +1,12 @@
import aloeVera from "$lib/assets/plants/aloe-vera.toml";
import monsteraDeliciosa from "$lib/assets/plants/monstera-deliciosa.toml";
import { isLeft } from "fp-ts/lib/Either";
import * as t from "io-ts";
import { PathReporter } from "io-ts/lib/PathReporter";
const plantModules = import.meta.glob("$lib/assets/plants/*.toml", {
import: "default",
eager: true,
});
const PlantDataTS = t.type({
slug: t.string,
name: t.string,
@ -34,21 +37,27 @@ const PlantDataTS = t.type({
light: t.string,
humidity: t.union([t.string, t.undefined]),
}),
common_issues: t.union([
t.type({
description: t.string,
}),
t.undefined,
]),
});
export type PlantData = t.TypeOf<typeof PlantDataTS>;
type PlantMap = { [key: PlantData["slug"]]: PlantData };
export const plants: PlantMap = [aloeVera, monsteraDeliciosa].reduce(
(acc, cur) => {
export const plants: PlantMap = Object.values(plantModules).reduce(
(acc: PlantMap, cur) => {
const decoded = PlantDataTS.decode(cur);
if (isLeft(decoded)) {
throw Error(
`Invalid plant data ${PathReporter.report(decoded).join("\n")}`,
);
}
acc[cur.slug] = decoded.right;
acc[decoded.right.slug] = decoded.right;
return acc;
},
{} as PlantMap,

@ -2,7 +2,9 @@
import type { PageData } from "./$types";
import Badge from "./Badge.svelte";
import PlantImage from "./PlantImage.svelte";
import Section from "./Section.svelte";
import TempBar from "./TempBar.svelte";
import SvelteMarkdown from "svelte-markdown";
export let data: PageData;
</script>
@ -10,53 +12,59 @@
<div class="card">
<h1>{data.name} (<i>{data.bin_name}</i>)</h1>
<PlantImage image={data.image} />
<section>
<a href="#site"><h2 id="site">Site</h2></a>
<TempBar temp={data.temp} />
<Section title="Site">
<div slot="subheading">
<TempBar temp={data.temp} />
<Badge
icon="sun"
text={data.site.light}
alt="Prefers {data.site.light} lighting conditions."
/>
{#if data.site.humidity}
<Badge
icon="drop"
text={data.site.humidity}
alt="Prefers {data.site.light} humidity."
icon="sun"
text={data.site.light}
alt="Prefers {data.site.light} lighting conditions."
/>
{/if}
{#if data.site.humidity}
<Badge
icon="drop"
text={data.site.humidity}
alt="Prefers {data.site.light} humidity."
/>
{/if}
</div>
<p>
{@html data.site.description}
<SvelteMarkdown source={data.site.description} />
</p>
</section>
<section>
<a href="#care"><h2 id="care">Care</h2></a>
<Badge
icon="drizzle"
text="every {data.care.water_schedule}"
alt="Water every {data.care.water_schedule}."
/>
{#if data.care.mist_schedule}
</Section>
<Section title="Care">
<div slot="subheading">
<Badge
icon="mist"
text="every {data.care.mist_schedule}"
alt="Mist every {data.care.mist_schedule}."
icon="drizzle"
text="every {data.care.water_schedule}"
alt="Water every {data.care.water_schedule}."
/>
{/if}
{#if data.care.clean_schedule}
<Badge
icon="brush-2"
text="every {data.care.clean_schedule}"
alt="Clean every {data.care.clean_schedule}."
/>
{/if}
{#if data.care.mist_schedule}
<Badge
icon="mist"
text="every {data.care.mist_schedule}"
alt="Mist every {data.care.mist_schedule}."
/>
{/if}
{#if data.care.clean_schedule}
<Badge
icon="brush-2"
text="every {data.care.clean_schedule}"
alt="Clean every {data.care.clean_schedule}."
/>
{/if}
</div>
<p>{data.care.description}</p>
</section>
<SvelteMarkdown source={data.care.description} />
</Section>
{#if data.common_issues != null}
<Section title="Common Issues">
<SvelteMarkdown source={data.common_issues.description} />
</Section>
{/if}
</div>

@ -0,0 +1,11 @@
<script lang="ts">
import slugify from "slugify";
export let title: string;
export let slug: string = slugify(title, { lower: true });
</script>
<section>
<a href="#{slug}"><h2 id={slug}>{title}</h2></a>
<slot name="subheading" />
<slot />
</section>
Loading…
Cancel
Save