From 6665deef2db22a8805af7d8d58406151457c1a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Ramiro=20Zu=C3=B1iga?= Date: Thu, 24 Jul 2025 23:02:45 -0600 Subject: [PATCH 1/2] cards to links --- src/routes/+page.svelte | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 26116fc..384c10d 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -124,30 +124,30 @@

Why Us?

From 1f1edfbc515f4d14b812a53a899b45ffa9dad309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Ramiro=20Zu=C3=B1iga?= Date: Fri, 25 Jul 2025 00:15:16 -0600 Subject: [PATCH 2/2] Modals --- components.json | 16 +++ src/lib/components/UI/Modal.svelte | 88 +++++++++++++++ .../components/UI/dialog/dialog-close.svelte | 7 ++ .../UI/dialog/dialog-content.svelte | 43 +++++++ .../UI/dialog/dialog-description.svelte | 17 +++ .../components/UI/dialog/dialog-footer.svelte | 20 ++++ .../components/UI/dialog/dialog-header.svelte | 20 ++++ .../UI/dialog/dialog-overlay.svelte | 20 ++++ .../components/UI/dialog/dialog-title.svelte | 17 +++ .../UI/dialog/dialog-trigger.svelte | 7 ++ src/lib/components/UI/dialog/index.ts | 37 ++++++ src/lib/utils.ts | 13 +++ src/routes/+page.svelte | 105 +++++++++++++++--- 13 files changed, 392 insertions(+), 18 deletions(-) create mode 100644 components.json create mode 100644 src/lib/components/UI/Modal.svelte create mode 100644 src/lib/components/UI/dialog/dialog-close.svelte create mode 100644 src/lib/components/UI/dialog/dialog-content.svelte create mode 100644 src/lib/components/UI/dialog/dialog-description.svelte create mode 100644 src/lib/components/UI/dialog/dialog-footer.svelte create mode 100644 src/lib/components/UI/dialog/dialog-header.svelte create mode 100644 src/lib/components/UI/dialog/dialog-overlay.svelte create mode 100644 src/lib/components/UI/dialog/dialog-title.svelte create mode 100644 src/lib/components/UI/dialog/dialog-trigger.svelte create mode 100644 src/lib/components/UI/dialog/index.ts create mode 100644 src/lib/utils.ts diff --git a/components.json b/components.json new file mode 100644 index 0000000..c5d91b4 --- /dev/null +++ b/components.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src/app.css", + "baseColor": "slate" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": true, + "registry": "https://shadcn-svelte.com/registry" +} diff --git a/src/lib/components/UI/Modal.svelte b/src/lib/components/UI/Modal.svelte new file mode 100644 index 0000000..1c3953e --- /dev/null +++ b/src/lib/components/UI/Modal.svelte @@ -0,0 +1,88 @@ + + + (showModal = false)} + onclick={(e) => { if (e.target === dialog) dialog.close(); }} + class="bg-green-600 text-white w-90vw lg:w-[70vw]" +> +
+
+ + +
+

+ {@render header?.()} +

+
+ {@render children?.()} +
+
+ +
+ +
+ + diff --git a/src/lib/components/UI/dialog/dialog-close.svelte b/src/lib/components/UI/dialog/dialog-close.svelte new file mode 100644 index 0000000..840b2f6 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/UI/dialog/dialog-content.svelte b/src/lib/components/UI/dialog/dialog-content.svelte new file mode 100644 index 0000000..99cc73b --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-content.svelte @@ -0,0 +1,43 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + + Close + + {/if} + + diff --git a/src/lib/components/UI/dialog/dialog-description.svelte b/src/lib/components/UI/dialog/dialog-description.svelte new file mode 100644 index 0000000..3845023 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/UI/dialog/dialog-footer.svelte b/src/lib/components/UI/dialog/dialog-footer.svelte new file mode 100644 index 0000000..e7ff446 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/UI/dialog/dialog-header.svelte b/src/lib/components/UI/dialog/dialog-header.svelte new file mode 100644 index 0000000..fc90cd9 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/UI/dialog/dialog-overlay.svelte b/src/lib/components/UI/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..f81ad83 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/UI/dialog/dialog-title.svelte b/src/lib/components/UI/dialog/dialog-title.svelte new file mode 100644 index 0000000..067e55e --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/UI/dialog/dialog-trigger.svelte b/src/lib/components/UI/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..9d1e801 --- /dev/null +++ b/src/lib/components/UI/dialog/dialog-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/UI/dialog/index.ts b/src/lib/components/UI/dialog/index.ts new file mode 100644 index 0000000..dce1d9d --- /dev/null +++ b/src/lib/components/UI/dialog/index.ts @@ -0,0 +1,37 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +const Root = DialogPrimitive.Root; +const Portal = DialogPrimitive.Portal; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..55b3a91 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,13 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChild = T extends { child?: any } ? Omit : T; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type WithoutChildren = T extends { children?: any } ? Omit : T; +export type WithoutChildrenOrChild = WithoutChildren>; +export type WithElementRef = T & { ref?: U | null }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 384c10d..dd5d9a1 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -12,8 +12,12 @@ import { languageTag } from '$lib/paraglide/runtime'; import { fly } from 'svelte/transition'; import { ChartColumnIncreasing, Sprout, CircleDollarSign, Shield, RadioTower, Route } from '@lucide/svelte'; - + import Modal from '$lib/components/UI/Modal.svelte'; // let submittingEmail = $state(false); + let showModalAffordable = $state(false); + let showModalService = $state(false); + let showModalHardware = $state(false); + let showModalCoverage = $state(false); let loaded = $state(true); // Set to true since we no longer need to wait for canvas initialization @@ -78,7 +82,8 @@ -
+

{m.home_solutions_title()}

{m.home_solutions_subtitle()}

@@ -124,30 +129,94 @@

Why Us?

- + + + {#snippet header()} + Affordable Pricing + {/snippet} + {#snippet children()} + +

Our pricing model is designed with farmers in mind, offering flexible plans that scale with your needs. + Whether you're managing a small family farm or a large agricultural enterprise, our IoT crop monitoring + solutions provide exceptional value without hidden costs. We offer straightforward subscription tiers, + one-time purchase options for hardware, and no long-term contracts, ensuring you only pay for what you need. + Compared to industry standards, our solutions deliver premium features at a fraction of the cost, empowering + you to maximize yields while minimizing expenses.

+ Stack of coins representing affordable pricing + {/snippet} +
+
+ + {#snippet header()} + End-to-End Service + {/snippet} + {#snippet children()} + +

Our end-to-end service ensures your IoT crop monitoring system is up and running with minimal effort on your + part. From initial consultation to final setup, our expert team handles everything—site assessment, hardware + installation, software configuration, and system testing. We provide on-site training to ensure your team is + confident in using the system. Post-installation, our dedicated support team is available 24/7 to address any + questions or issues, guaranteeing a hassle-free experience and a fully operational solution tailored to your + farm's unique needs.

+ Technician working on equipment for end-to-end service + {/snippet} +
+
+ + {#snippet header()} + Long Lasting Hardware + {/snippet} + {#snippet children()} + +

Our IoT devices are engineered for durability and reliability in the harshest agricultural environments. + Constructed with weather-resistant materials, our sensors and monitoring equipment are designed to endure + extreme temperatures, moisture, and dust, ensuring consistent performance year-round. With a focus on + longevity, our hardware requires minimal maintenance, reducing downtime and operational costs. Each device + undergoes rigorous testing to meet the highest quality standards, providing you with a dependable solution + that supports your farm’s productivity for years to come.

+ Close-up of durable IoT hardware components + {/snippet} +
+
+ + {#snippet header()} + The Best Signal Coverage + {/snippet} + {#snippet children()} + +

Our IoT crop monitoring systems leverage cutting-edge connectivity technology to ensure seamless data + transmission across your entire farm, no matter the size or terrain. With advanced signal amplification and + low-power wide-area network (LPWAN) technology, our devices provide unmatched coverage, even in remote or + challenging environments. Powered by long-lasting, low-maintenance batteries, our systems minimize the need + for frequent replacements, ensuring continuous monitoring and real-time insights into soil health, moisture + levels, and crop conditions, all accessible from your smartphone or computer.

+ Radio tower ensuring superior signal coverage + {/snippet} +