diff options
| -rw-r--r-- | src/components/Navigation.tsx | 103 | ||||
| -rw-r--r-- | src/layouts/Layout.astro | 8 | ||||
| -rw-r--r-- | src/pages/embed-example.astro | 66 | ||||
| -rw-r--r-- | src/pages/embed.astro | 72 | ||||
| -rw-r--r-- | src/pages/index.astro | 24 | ||||
| -rw-r--r-- | src/pages/subnet-guide.astro (renamed from src/pages/cidr-calculator-subnet-guide.astro) | 10 |
6 files changed, 259 insertions, 24 deletions
diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx new file mode 100644 index 0000000..b5ef2a7 --- /dev/null +++ b/src/components/Navigation.tsx @@ -0,0 +1,103 @@ +import { useState, useEffect } from 'react'; + +export default function Navigation() { + const [isMenuOpen, setIsMenuOpen] = useState(false); + + // Close menu when window is resized to desktop size + useEffect(() => { + const handleResize = () => { + if (window.innerWidth >= 640 && isMenuOpen) { + setIsMenuOpen(false); + } + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [isMenuOpen]); + + const toggleMenu = () => { + setIsMenuOpen(!isMenuOpen); + }; + + return ( + <nav className="w-full max-w-6xl mx-auto mb-4 py-2 px-4"> + <div className="flex justify-between items-center"> + <a + href="/" + className="text-2xl font-bold flex items-center gap-2" + > + <img + src="/ico/icon-192.png" + alt="CIDR.xyz logo" + className="w-6 h-6" + /> + CIDR.xyz + </a> + + {/* Hamburger button for mobile */} + <button + onClick={toggleMenu} + className="sm:hidden flex items-center px-3 py-2 border rounded text-gray-700 border-gray-700 hover:text-blue-600 hover:border-blue-600" + aria-label="Toggle menu" + > + <svg className="fill-current h-4 w-4" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> + <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /> + </svg> + </button> + + {/* Desktop menu */} + <div className="hidden sm:flex space-x-6"> + <NavLinks /> + </div> + </div> + + {/* Mobile menu */} + <div className={`${isMenuOpen ? '' : 'hidden'} sm:hidden mt-4 pt-4 border-t border-gray-200`}> + <div className="flex flex-col space-y-3"> + <NavLinks mobile={true} /> + </div> + </div> + </nav> + ); +} + +// Separated NavLinks component for reuse +function NavLinks({ mobile = false }: { mobile?: boolean }) { + const linkClass = `text-gray-700 hover:text-blue-600 font-medium ${mobile ? 'py-2' : ''}`; + + return ( + <> + <a href="/" className={linkClass}> + CIDR Calculator + </a> + <a href="/subnet-guide" className={linkClass}> + Subnet Guide + </a> + <a href="/embed-example" className={linkClass}> + Embed + </a> + <a + href="https://github.com/yuvadm/cidr.xyz" + className={`${linkClass} flex items-center gap-1`} + target="_blank" + rel="noopener noreferrer" + > + Github + <svg + xmlns="http://www.w3.org/2000/svg" + className="h-4 w-4" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + strokeLinecap="round" + strokeLinejoin="round" + strokeWidth="2" + d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" + /> + </svg> + </a> + </> + ); +} diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index e85cfd3..a7f2b7b 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,6 +1,6 @@ --- import "../styles/global.css"; - +import Navigation from "../components/Navigation"; import { GOOGLE_ANALYTICS_ID } from "../config"; export interface Props { @@ -99,11 +99,14 @@ const { </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" > + <Navigation client:load /> <div class="max-w-6xl w-full sm:p-8 p-2 min-h-[800px]"> <slot /> </div> @@ -115,9 +118,6 @@ const { >, 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> diff --git a/src/pages/embed-example.astro b/src/pages/embed-example.astro new file mode 100644 index 0000000..f66feab --- /dev/null +++ b/src/pages/embed-example.astro @@ -0,0 +1,66 @@ +--- +import Layout from "../layouts/Layout.astro"; + +const title = "CIDR Calculator Widget Embed Example"; +const description = "Learn how to embed the CIDR calculator widget in your website"; +--- + +<Layout title={title} description={description}> + <h1 class="my-3 sm:my-1 text-center sm:text-left text-4xl font-extrabold tracking-tight text-gray-900 sm:text-6xl text-4xl"> + CIDR Calculator Widget + </h1> + <h2 class="pt-1 text-xl text-center sm:text-left text-gray-600 mb-8"> + Embed the CIDR Calculator in your website + </h2> + + <div class="prose max-w-none mb-8"> + <p> + You can embed the CIDR calculator widget in your website or application using an iframe. + Copy the code below and adjust the width and height as needed: + </p> + + <pre class="bg-gray-100 p-4 rounded-md overflow-x-auto"><code><iframe + src="https://cidr.xyz/embed" + width="100%" + height="600" + frameborder="0" + allowtransparency="true" + title="CIDR Calculator" + loading="lazy" +></iframe></code></pre> + + <h3>Live Example</h3> + <p>Here's how the embedded widget looks:</p> + </div> + + <div class="border border-gray-300 rounded-lg shadow-md mb-8"> + <iframe + src="/embed" + width="100%" + height="600" + frameborder="0" + allowtransparency="true" + title="CIDR Calculator" + loading="lazy" + ></iframe> + </div> + + <div class="prose max-w-none"> + <h3>Customization</h3> + <p> + The widget adapts to the width of its container. For best results: + </p> + <ul> + <li>Use a minimum width of 400px for optimal display</li> + <li>Set a minimum height of 600px to avoid scrolling</li> + <li>The widget has a transparent background that can blend with your site</li> + </ul> + + <h3>Usage Notes</h3> + <ul> + <li>The widget is free to use on any website</li> + <li>Please consider adding attribution with a link back to <a href="https://cidr.xyz" class="text-blue-600 hover:underline">cidr.xyz</a></li> + <li>For any questions or customization needs, visit the <a href="https://github.com/yuvadm/cidr.xyz" class="text-blue-600 hover:underline">GitHub repository</a></li> + </ul> + </div> +</Layout> diff --git a/src/pages/embed.astro b/src/pages/embed.astro new file mode 100644 index 0000000..3496287 --- /dev/null +++ b/src/pages/embed.astro @@ -0,0 +1,72 @@ +--- +import Cidr from "../components/Cidr"; +import { GOOGLE_ANALYTICS_ID } from "../config"; + +const title = "CIDR Calculator Widget"; +const description = "Embeddable CIDR calculator widget for network calculations"; +--- + +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" type="image/x-icon" href="/ico/favicon.ico" /> + <meta name="viewport" content="width=device-width" /> + <title>{title}</title> + <meta name="description" content={description} /> + <meta name="robots" content="noindex, follow" /> + + <!-- Import global styles --> + <style is:global> + @import "../styles/global.css"; + </style> + + <!-- Embed-specific styles --> + <style> + body { + margin: 0; + padding: 0; + background: transparent; + overflow: hidden; + } + .embed-container { + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.9); + border-radius: 8px; + padding: 10px; + box-sizing: border-box; + } + </style> + + <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> + <body> + <div class="embed-container"> + <Cidr client:load /> + </div> + + <script is:inline> + // Handle messages from parent window for potential configuration + window.addEventListener('message', (event) => { + // You can add functionality here to configure the widget based on messages + // from the parent window if needed in the future + }); + + // Notify parent when loaded + window.addEventListener('load', () => { + if (window.parent !== window) { + window.parent.postMessage({ type: 'cidr-widget-loaded' }, '*'); + } + }); + </script> + </body> +</html> diff --git a/src/pages/index.astro b/src/pages/index.astro index 9458dab..23588d9 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -19,18 +19,18 @@ const faqJsonLd = { --- <Layout title={title} description={description}> - <h1 - class="my-3 sm:my-1 text-center sm:text-left text-4xl font-extrabold tracking-tight text-gray-900 sm:text-6xl text-4xl" - > - 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> - <a - href="/cidr-calculator-subnet-guide" - class="text-blue-600 hover:underline">Read the guide</a - > + <header> + <div class="mx-auto max-w-7xl px-4 py-2 sm:py-4 lg:px-6 text-center"> + <h1 + class="text-4xl font-extrabold tracking-tight text-gray-900 sm:text-6xl" + > + CIDR Calculator + </h1> + <p class="mt-4 text-lg sm:text-xl max-w-2xl mx-auto text-gray-700"> + Visualize and Calculate Network Ranges with IPv4 CIDR Blocks + </p> + </div> + </header> <Cidr client:load /> diff --git a/src/pages/cidr-calculator-subnet-guide.astro b/src/pages/subnet-guide.astro index 3f2c4d1..9a0d67f 100644 --- a/src/pages/cidr-calculator-subnet-guide.astro +++ b/src/pages/subnet-guide.astro @@ -27,17 +27,11 @@ import { Content as GuideContent } from "../content/cidr-guide.md"; <Layout title={title} description={description}> <header> - <a href="/" class="group flex items-center text-blue-600 transition-all duration-300 hover:text-blue-800"> - <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1 transform transition-transform duration-300 group-hover:-translate-x-1" fill="none" viewBox="0 0 24 24" stroke="currentColor"> - <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" /> - </svg> - <span class="hover:underline">Back Home</span> - </a> <div class="mx-auto max-w-7xl px-4 py-2 sm:py-4 lg:px-6 text-center"> <h1 class="text-4xl font-extrabold tracking-tight text-gray-900 sm:text-6xl" > - CIDR Calculator & Subnet Guide + CIDR Subnet Guide </h1> <p class="mt-4 text-lg sm:text-xl max-w-2xl mx-auto text-gray-700"> Convert CIDR blocks to IP ranges and master subnetting for IPv4 @@ -46,7 +40,7 @@ import { Content as GuideContent } from "../content/cidr-guide.md"; </div> </header> - <section> + <section class="hidden sm:block"> <Cidr client:load /> </section> |
