| @@ -2,6 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | import { useEffect, useRef, useState } from "react"; |
| 4 | 4 | import { GroveLogo } from "@/app/components/grove-logo"; |
| 5 | import { useTheme } from "@/lib/theme"; |
| 5 | 6 | |
| 6 | 7 | const TERMINAL_LINES = [ |
| 7 | 8 | { prompt: true, text: "grove init --owner letterpress-labs", delay: 40 }, |
| @@ -114,17 +115,28 @@ |
| 114 | 115 | |
| 115 | 116 | export function LandingPage() { |
| 116 | 117 | const [islDomain, setIslDomain] = useState(""); |
| 118 | const { theme } = useTheme(); |
| 119 | const islRef = useRef<HTMLIFrameElement>(null); |
| 117 | 120 | |
| 118 | 121 | useEffect(() => { |
| 119 | 122 | const host = window.location.hostname; |
| 120 | | // Derive isl subdomain: grove.host → isl.grove.host, localhost → "" |
| 121 | 123 | if (host !== "localhost" && !host.match(/^\d/)) { |
| 122 | 124 | setIslDomain(`https://isl.${host}`); |
| 123 | 125 | } |
| 124 | 126 | }, []); |
| 125 | 127 | |
| 128 | // Send theme changes to ISL iframe via postMessage |
| 129 | useEffect(() => { |
| 130 | if (islRef.current?.contentWindow) { |
| 131 | islRef.current.contentWindow.postMessage({ type: "theme", value: theme }, "*"); |
| 132 | } |
| 133 | }, [theme]); |
| 134 | |
| 126 | 135 | return ( |
| 127 | | <div style={{ maxWidth: "800px", margin: "0 auto", padding: "60px 24px 80px" }}> |
| 136 | <div style={{ display: "flex", flexDirection: "column", minHeight: "calc(100vh - 3.5rem)" }}> |
| 137 | {/* Hero + Terminal + Features */} |
| 138 | <div style={{ maxWidth: "800px", margin: "0 auto", padding: "60px 24px 0", width: "100%" }}> |
| 139 | |
| 128 | 140 | {/* Hero */} |
| 129 | 141 | <div style={{ textAlign: "center", marginBottom: "64px" }}> |
| 130 | 142 | <div style={{ display: "inline-block", marginBottom: "24px" }}> |
| @@ -189,49 +201,8 @@ |
| 189 | 201 | <TerminalDemo /> |
| 190 | 202 | </section> |
| 191 | 203 | |
| 192 | | {/* ISL */} |
| 193 | | {islDomain && ( |
| 194 | | <section style={{ marginBottom: "64px" }}> |
| 195 | | <div style={{ marginBottom: "16px" }}> |
| 196 | | <h2 |
| 197 | | style={{ |
| 198 | | fontSize: "0.75rem", |
| 199 | | fontWeight: 600, |
| 200 | | textTransform: "uppercase", |
| 201 | | letterSpacing: "0.1em", |
| 202 | | color: "var(--text-faint)", |
| 203 | | marginBottom: "4px", |
| 204 | | }} |
| 205 | | > |
| 206 | | Interactive Smartlog |
| 207 | | </h2> |
| 208 | | <p style={{ fontSize: "0.875rem", color: "var(--text-muted)" }}> |
| 209 | | Visualize your commit graph, browse diffs, and manage stacked changes — all in the browser. |
| 210 | | This is a live, read-only view of Grove's own repository. |
| 211 | | </p> |
| 212 | | </div> |
| 213 | | <div |
| 214 | | style={{ |
| 215 | | border: "1px solid var(--border-subtle)", |
| 216 | | overflow: "hidden", |
| 217 | | height: "500px", |
| 218 | | }} |
| 219 | | > |
| 220 | | <iframe |
| 221 | | src={islDomain} |
| 222 | | style={{ |
| 223 | | width: "100%", |
| 224 | | height: "100%", |
| 225 | | border: "none", |
| 226 | | }} |
| 227 | | title="Interactive Smartlog" |
| 228 | | /> |
| 229 | | </div> |
| 230 | | </section> |
| 231 | | )} |
| 232 | | |
| 233 | 204 | {/* Features */} |
| 234 | | <section> |
| 205 | <section style={{ marginBottom: "48px" }}> |
| 235 | 206 | <div |
| 236 | 207 | style={{ |
| 237 | 208 | display: "grid", |
| @@ -282,6 +253,54 @@ |
| 282 | 253 | ))} |
| 283 | 254 | </div> |
| 284 | 255 | </section> |
| 256 | |
| 257 | </div>{/* end centered wrapper */} |
| 258 | |
| 259 | {/* ISL — fills remaining viewport */} |
| 260 | {islDomain && ( |
| 261 | <section style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: "500px" }}> |
| 262 | <div style={{ padding: "0 24px 16px", maxWidth: "800px", margin: "0 auto", width: "100%" }}> |
| 263 | <h2 |
| 264 | style={{ |
| 265 | fontSize: "0.75rem", |
| 266 | fontWeight: 600, |
| 267 | textTransform: "uppercase", |
| 268 | letterSpacing: "0.1em", |
| 269 | color: "var(--text-faint)", |
| 270 | marginBottom: "4px", |
| 271 | }} |
| 272 | > |
| 273 | Interactive Smartlog |
| 274 | </h2> |
| 275 | <p style={{ fontSize: "0.875rem", color: "var(--text-muted)" }}> |
| 276 | Visualize your commit graph, browse diffs, and manage stacked changes — all in the browser. |
| 277 | This is a live, read-only view of Grove's own repository. |
| 278 | </p> |
| 279 | </div> |
| 280 | <div |
| 281 | style={{ |
| 282 | flex: 1, |
| 283 | borderTop: "1px solid var(--border-subtle)", |
| 284 | }} |
| 285 | > |
| 286 | <iframe |
| 287 | ref={islRef} |
| 288 | src={`${islDomain}?theme=${theme}`} |
| 289 | style={{ |
| 290 | width: "100%", |
| 291 | height: "100%", |
| 292 | border: "none", |
| 293 | display: "block", |
| 294 | }} |
| 295 | title="Interactive Smartlog" |
| 296 | onLoad={() => { |
| 297 | // Send theme on initial load |
| 298 | islRef.current?.contentWindow?.postMessage({ type: "theme", value: theme }, "*"); |
| 299 | }} |
| 300 | /> |
| 301 | </div> |
| 302 | </section> |
| 303 | )} |
| 285 | 304 | </div> |
| 286 | 305 | ); |
| 287 | 306 | } |
| 288 | 307 | |