diff options
| author | Yuval Adam <_@yuv.al> | 2025-05-21 09:12:30 +0200 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2025-05-21 09:12:30 +0200 |
| commit | ac07b73384de511e04542e9ac3a500eb81f92b92 (patch) | |
| tree | aecb57c4111a9fdef6929871ce41cf60e3bb6918 /src | |
| parent | 366a7501a3dccde4fc9b65817da9062912d3cf1c (diff) | |
Extract common layout
Diffstat (limited to 'src')
| -rw-r--r-- | src/layouts/Layout.astro | 123 | ||||
| -rw-r--r-- | src/pages/404.astro | 61 | ||||
| -rw-r--r-- | src/pages/index.astro | 204 |
3 files changed, 196 insertions, 192 deletions
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro new file mode 100644 index 0000000..d4d4e7e --- /dev/null +++ b/src/layouts/Layout.astro @@ -0,0 +1,123 @@ +--- +import "../styles/global.css"; + +import { GOOGLE_ANALYTICS_ID } from "../config"; + +export interface Props { + title: string; + description?: string; + ogImage?: string; + ogImageAlt?: string; + noindex?: boolean; +} + +const { + title, + description, + ogImage = "https://cidr.xyz/og.webp", + ogImageAlt = "Color-coded octets illustrating an IP range and CIDR mask", + noindex = false, +} = Astro.props; +--- + +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" type="image/x-icon" href="/ico/favicon.ico" /> + <link + rel="apple-touch-icon" + sizes="180x180" + href="/ico/apple-touch-icon.png" + /> + <link + rel="icon" + type="image/png" + sizes="192x192" + href="/ico/icon-192.png" + /> + <link + rel="icon" + type="image/png" + sizes="512x512" + href="/ico/icon-512.png" + /> + <link rel="manifest" href="/manifest.json" /> + <meta name="theme-color" content="#0066cc" /> + <meta name="viewport" content="width=device-width" /> + <title>{title}</title> + {description && <meta name="description" content={description} />} + + <meta + name="robots" + content={noindex ? "noindex, follow" : "index, follow"} + /> + <link rel="canonical" href="https://cidr.xyz" /> + + { + !noindex && ( + <> + <meta property="og:title" content={title} /> + {description && ( + <meta property="og:description" content={description} /> + )} + <meta property="og:type" content="website" /> + <meta property="og:url" content="https://cidr.xyz" /> + <meta property="og:site_name" content="CIDR.xyz" /> + <meta property="og:image" content={ogImage} /> + <meta property="og:image:type" content="image/webp" /> + <meta property="og:image:width" content="1200" /> + <meta property="og:image:height" content="630" /> + <meta property="og:image:alt" content={ogImageAlt} /> + + <meta name="twitter:card" content="summary_large_image" /> + <meta name="twitter:title" content={title} /> + {description && ( + <meta + name="twitter:description" + content={description} + /> + )} + <meta name="twitter:image" content={ogImage} /> + </> + ) + } + + <script + async + src={`https://www.googletagmanager.com/gtag/js?id=${GOOGLE_ANALYTICS_ID}`} + ></script> + <script define:vars={{ GOOGLE_ANALYTICS_ID }} is:inline> + window.dataLayer = window.dataLayer || []; + function gtag() { + dataLayer.push(arguments); + } + gtag("js", new Date()); + gtag("config", GOOGLE_ANALYTICS_ID); + </script> + + <slot name="head" /> + </head> + <body> + <div + class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100 p-2" + > + <div class="max-w-6xl w-full sm:p-8 p-2 min-h-[800px]"> + <slot /> + </div> + <footer class="text-xs my-4 pb-3 text-center"> + <p> + Created by <a + href="https://yuv.al" + class="text-blue-600 hover:underline">Yuval Adam</a + >, operated by <a + href="https://magicmonad.com" + class="text-blue-600 hover:underline">Magic Monad</a + >. Open source available on <a + href="https://github.com/yuvadm/cidr.xyz" + class="text-blue-600 hover:underline">Github</a + >. + </p> + </footer> + </div> + </body> +</html> diff --git a/src/pages/404.astro b/src/pages/404.astro index 8750eff..c9c70ca 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,53 +1,22 @@ --- -import { GOOGLE_ANALYTICS_ID } from "../config"; - -import "../styles/global.css"; +import Layout from "../layouts/Layout.astro"; const title = "404 - Page Not Found"; --- -<html lang="en"> - <head> - <meta charset="utf-8" /> - <link rel="icon" type="image/ico" href="/favicon.ico" /> - <meta name="viewport" content="width=device-width" /> - <title>{title}</title> - <meta name="robots" content="noindex, follow" /> - - <script - async - src={`https://www.googletagmanager.com/gtag/js?id=${GOOGLE_ANALYTICS_ID}`} - ></script> - <script define:vars={{ GOOGLE_ANALYTICS_ID }} is:inline> - window.dataLayer = window.dataLayer || []; - function gtag() { - dataLayer.push(arguments); - } - gtag("js", new Date()); - gtag("config", GOOGLE_ANALYTICS_ID); - </script> - </head> +<Layout title={title} noindex={true}> + <h1 + class="my-3 sm:my-1 text-center sm:text-left text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl" + > + 404 - Page Not Found + </h1> - <body> - <div - class="min-h-screen flex flex-col items-center justify-center bg-gray-100 p-2" + <div class="my-6 text-lg leading-8 text-slate-900"> + <p class="mb-8"> + The page you're looking for doesn't exist. + </p> + <a href="/" class="text-blue-600 hover:underline" + >← Back to IP / CIDR Calculator</a > - <div class="max-w-6xl w-full sm:p-8 p-2"> - <h1 - class="my-3 sm:my-1 text-center sm:text-left text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl" - > - 404 - Page Not Found - </h1> - - <div class="my-6 text-lg leading-8 text-slate-900"> - <p class="mb-8"> - The page you're looking for doesn't exist. - </p> - <a href="/" class="text-blue-600 hover:underline" - >← Back to IP / CIDR Calculator</a - > - </div> - </div> - </div> - </body> -</html> + </div> +</Layout> diff --git a/src/pages/index.astro b/src/pages/index.astro index 1b86070..ef13cf6 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,15 +1,10 @@ --- +import Layout from "../layouts/Layout.astro"; import Cidr from "../components/Cidr"; import { faqs } from "../content/faqs.ts"; -import "../styles/global.css"; -import { GOOGLE_ANALYTICS_ID } from "../config"; - -const metadata = { - title: "Interactive visual CIDR and IP range calculator", - description: - "Instantly compute and visualize CIDR subnets, IP ranges and masks. Free online tool for accurate network design, planning and IT education.", -}; +const title = "Interactive visual CIDR and IP range calculator"; +const description = "Instantly compute and visualize CIDR subnets, IP ranges and masks. Free online tool for accurate network design, planning and IT education."; const faqJsonLd = { "@context": "https://schema.org", @@ -22,146 +17,63 @@ const faqJsonLd = { }; --- -<html lang="en"> - <head> - <meta charset="utf-8" /> - <link rel="icon" type="image/x-icon" href="/ico/favicon.ico" /> - <link - rel="apple-touch-icon" - sizes="180x180" - href="/ico/apple-touch-icon.png" - /> - <link - rel="icon" - type="image/png" - sizes="192x192" - href="/ico/icon-192.png" - /> - <link - rel="icon" - type="image/png" - sizes="512x512" - href="/ico/icon-512.png" - /> - <link rel="manifest" href="/manifest.json" /> - <meta name="theme-color" content="#0066cc" /> - <meta name="viewport" content="width=device-width" /> - <title>{metadata.title}</title> - <meta name="description" content={metadata.description} /> - - <meta name="robots" content="index, follow" /> - <link rel="canonical" href="https://cidr.xyz" /> +<Layout title={title} description={description}> + <h1 + class="my-3 sm:my-1 text-center sm:text-left text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl" + > + IP / CIDR Calculator + </h1> + <h2 class="pt-1 text-xl text-center sm:text-left text-gray-600"> + Visualize and Calculate Network Ranges with IPv4 CIDR Blocks + </h2> - <meta property="og:title" content={metadata.title} /> - <meta property="og:description" content={metadata.description} /> - <meta property="og:type" content="website" /> - <meta property="og:url" content="https://cidr.xyz" /> - <meta property="og:site_name" content="CIDR.xyz" /> - <meta property="og:image" content="https://cidr.xyz/og.webp" /> - <meta property="og:image:type" content="image/webp" /> - <meta property="og:image:width" content="1200" /> - <meta property="og:image:height" content="630" /> - <meta - property="og:image:alt" - content="Color-coded octets illustrating an IP range and CIDR mask" - /> + <Cidr client:load /> - <meta name="twitter:card" content="summary_large_image" /> - <meta name="twitter:title" content={metadata.title} /> - <meta name="twitter:description" content={metadata.description} /> - <meta name="twitter:image" content="https://cidr.xyz/og.webp" /> + <section + id="faq-section" + class="mx-auto mt-12 max-w-3xl px-4 sm:px-0" + > + <h2 id="faq" class="mb-4 text-2xl font-bold"> + CIDR & Subnetting FAQ + </h2> - <script - async - src={`https://www.googletagmanager.com/gtag/js?id=${GOOGLE_ANALYTICS_ID}`} - ></script> - <script define:vars={{ GOOGLE_ANALYTICS_ID }} is:inline> - window.dataLayer = window.dataLayer || []; - function gtag() { - dataLayer.push(arguments); + <dl class="space-y-2"> + { + faqs.map(({ q, a }) => ( + <details class="group rounded-lg bg-white shadow-sm open:shadow-md transition"> + <summary + class="flex cursor-pointer list-none items-center justify-between + rounded-lg px-4 py-3 font-semibold text-gray-900 + hover:bg-gray-50" + > + {q} + <svg + class="h-5 w-5 transform text-gray-400 transition group-open:rotate-180" + xmlns="http://www.w3.org/2000/svg" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M19 9l-7 7-7-7" + /> + </svg> + </summary> + <dd class="px-4 pb-4 pt-1 text-gray-700"> + {a} + </dd> + </details> + )) } - gtag("js", new Date()); - gtag("config", GOOGLE_ANALYTICS_ID); - </script> - </head> - <body> - <div - class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100 p-2" - > - <div class="max-w-6xl w-full sm:p-8 p-2 min-h-[800px]"> - <h1 - class="my-3 sm:my-1 text-center sm:text-left text-4xl font-bold tracking-tight text-gray-900 sm:text-6xl" - > - IP / CIDR Calculator - </h1> - <h2 class="pt-1 text-xl text-center sm:text-left text-gray-600"> - Visualize and Calculate Network Ranges with IPv4 CIDR Blocks - </h2> - - <Cidr client:load /> - - <section - id="faq-section" - class="mx-auto mt-12 max-w-3xl px-4 sm:px-0" - > - <h2 id="faq" class="mb-4 text-2xl font-bold"> - CIDR & Subnetting FAQ - </h2> - - <dl class="space-y-2"> - { - faqs.map(({ q, a }) => ( - <details class="group rounded-lg bg-white shadow-sm open:shadow-md transition"> - <summary - class="flex cursor-pointer list-none items-center justify-between - rounded-lg px-4 py-3 font-semibold text-gray-900 - hover:bg-gray-50" - > - {q} - <svg - class="h-5 w-5 transform text-gray-400 transition group-open:rotate-180" - xmlns="http://www.w3.org/2000/svg" - fill="none" - viewBox="0 0 24 24" - stroke="currentColor" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M19 9l-7 7-7-7" - /> - </svg> - </summary> - <dd class="px-4 pb-4 pt-1 text-gray-700"> - {a} - </dd> - </details> - )) - } - </dl> - </section> + </dl> + </section> - <script - type="application/ld+json" - is:inline - set:html={JSON.stringify(faqJsonLd, null, 2)} - /> - </div> - <footer class="text-xs my-4 pb-3 text-center"> - <p> - Created by <a - href="https://yuv.al" - class="text-blue-600 hover:underline">Yuval Adam</a - >, operated by <a - href="https://magicmonad.com" - class="text-blue-600 hover:underline">Magic Monad</a - >. Open source available on <a - href="https://github.com/yuvadm/cidr.xyz" - class="text-blue-600 hover:underline">Github</a - >. - </p> - </footer> - </div> - </body> -</html> + <script + type="application/ld+json" + is:inline + set:html={JSON.stringify(faqJsonLd, null, 2)} + /> +</Layout> |
