From d973145affdfd55d44bf185944a96dbfcbc9687f Mon Sep 17 00:00:00 2001 From: michasdev Date: Mon, 20 Apr 2026 01:29:04 -0300 Subject: [PATCH] feat: add footer and some fixes --- apps/web/www/index.html | 4 +- .../www/src/components/layout/root-layout.tsx | 4 +- apps/web/www/src/components/shared/footer.tsx | 110 ++++++++++++++++++ apps/web/www/src/components/shared/navbar.tsx | 4 +- apps/web/www/src/components/ui/button.tsx | 6 +- .../home/components/call-to-action.tsx | 2 +- apps/web/www/src/features/home/home.tsx | 4 +- .../src/features/home/sections/hero/hero.tsx | 2 +- 8 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 apps/web/www/src/components/shared/footer.tsx diff --git a/apps/web/www/index.html b/apps/web/www/index.html index 2f0d3a8..20d8eec 100644 --- a/apps/web/www/index.html +++ b/apps/web/www/index.html @@ -4,9 +4,9 @@ - MildStack - Free Open Source LocalStack Alternative + MildStack: Free Open Source LocalStack Alternative - + diff --git a/apps/web/www/src/components/layout/root-layout.tsx b/apps/web/www/src/components/layout/root-layout.tsx index 476c79a..7dfaf5b 100644 --- a/apps/web/www/src/components/layout/root-layout.tsx +++ b/apps/web/www/src/components/layout/root-layout.tsx @@ -4,7 +4,7 @@ import { Navbar } from '@/components/shared/navbar'; export const RootLayout: React.FC = () => { return ( -
+
{/* Navbar Container */}
{/* Enable pointer events on Navbar itself while keeping wrapper pointer-events-none so we can interact with background */} @@ -14,7 +14,7 @@ export const RootLayout: React.FC = () => {
{/* Page Content */} -
+
diff --git a/apps/web/www/src/components/shared/footer.tsx b/apps/web/www/src/components/shared/footer.tsx new file mode 100644 index 0000000..91cdabc --- /dev/null +++ b/apps/web/www/src/components/shared/footer.tsx @@ -0,0 +1,110 @@ +import { + Grid2X2Plus, +} from 'lucide-react'; +import mildstack from '@/assets/logos/mildstack-logo-full-white.png'; + +export function Footer() { + const year = new Date().getFullYear(); + + const website = [ + { + title: 'Home', + href: '#', + }, + { + title: 'Features', + href: '#', + }, + { + title: 'Services', + href: '#', + }, + { + title: 'Docs', + href: '#', + } + ]; + + const resources = [ + { + title: 'Blog', + href: '#', + }, + { + title: 'Help Center', + href: '#', + }, + { + title: 'Contact Support', + href: '#', + }, + { + title: 'Community', + href: '#', + }, + { + title: 'Security', + href: '#', + }, + ]; + + const socialLinks = [ + { + icon: , + link: 'https://github.com/michasdev/mildstack', + }, + ]; + return ( +
+
+
+
+
+ + MildStack Logo + +

+ Mildstack: Run AWS services locally. Free, lightweight, and open-source. +
+ The definitive LocalStack alternative. +

+
+ {socialLinks.map((item, i) => ( + + {item.icon} + + ))} +
+
+
+ + Resources + +
+ {website.map(({ href, title }, i) => ( + + {title} + + ))} +
+
+
+
+
+

+ © MildStack {year}. MIT Licensed. View Repository. +

+
+
+
+ ); +} \ No newline at end of file diff --git a/apps/web/www/src/components/shared/navbar.tsx b/apps/web/www/src/components/shared/navbar.tsx index 2caf721..9997a2d 100644 --- a/apps/web/www/src/components/shared/navbar.tsx +++ b/apps/web/www/src/components/shared/navbar.tsx @@ -3,7 +3,7 @@ import { motion, AnimatePresence, useScroll, useMotionValueEvent } from 'motion/ import { Star, Download, Menu, X } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; -import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.svg' +import logoFullWhite from '@/assets/logos/mildstack-logo-full-white.png' const NAV_LINKS = [ { label: 'Home', variant: 'outline' }, @@ -85,7 +85,7 @@ export const Navbar: React.FC = () => { transition={{ duration: 0.5 }} className={cn( "px-4 backdrop-blur-3xl rounded-full py-4 flex justify-between items-center transition-all duration-300", - scrolled ? 'bg-background/80 border border-white/10 shadow-2xl shadow-white/5' : 'bg-background/50' + scrolled ? 'bg-background/80 border shadow-2xl shadow-white/5' : 'bg-background/50' )} >
diff --git a/apps/web/www/src/components/ui/button.tsx b/apps/web/www/src/components/ui/button.tsx index 66bbb89..3d74df3 100644 --- a/apps/web/www/src/components/ui/button.tsx +++ b/apps/web/www/src/components/ui/button.tsx @@ -8,7 +8,7 @@ import { cn } from "@/lib/utils"; import { Spinner } from "@/components/ui/spinner"; export const buttonVariants = cva( - "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-loading:select-none data-loading:text-transparent sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0", + "relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-lg border font-medium text-base outline-none transition-shadow before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-64 data-loading:select-none data-loading:text-transparent sm:text-sm [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5 [&_svg]:shrink-0", { defaultVariants: { size: "default", @@ -23,11 +23,11 @@ export const buttonVariants = cva( "icon-xl": "size-11 sm:size-10 [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5", "icon-xs": - "size-7 rounded-md before:rounded-[calc(var(--radius-md)-1px)] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5", + "size-7 rounded-md before:rounded-[inherit] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5", lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9", sm: "h-8 gap-1.5 px-[calc(--spacing(2.5)-1px)] sm:h-7", xl: "h-11 px-[calc(--spacing(4)-1px)] text-lg sm:h-10 sm:text-base [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5", - xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[calc(var(--radius-md)-1px)] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5", + xs: "h-7 gap-1 rounded-md px-[calc(--spacing(2)-1px)] text-sm before:rounded-[inherit] sm:h-6 sm:text-xs [&_svg:not([class*='size-'])]:size-4 sm:[&_svg:not([class*='size-'])]:size-3.5", }, variant: { default: diff --git a/apps/web/www/src/features/home/components/call-to-action.tsx b/apps/web/www/src/features/home/components/call-to-action.tsx index 8fe0a43..5d79a19 100644 --- a/apps/web/www/src/features/home/components/call-to-action.tsx +++ b/apps/web/www/src/features/home/components/call-to-action.tsx @@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button"; export function CallToAction() { return ( -
+
{ return ( <> -
+
+