diff --git a/landing/app/globals.css b/landing/app/globals.css index 8c2c043..482cfc8 100644 --- a/landing/app/globals.css +++ b/landing/app/globals.css @@ -188,6 +188,84 @@ footer, transform: translateY(0); } +@keyframes screenshotFadeIn { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +@keyframes modalPanelIn { + from { + opacity: 0; + transform: translateY(14px) scale(0.96); + } + + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +@keyframes screenshotSlideNext { + from { + opacity: 0; + transform: translateX(22px) scale(0.985); + } + + to { + opacity: 1; + transform: translateX(0) scale(1); + } +} + +@keyframes screenshotSlidePrevious { + from { + opacity: 0; + transform: translateX(-22px) scale(0.985); + } + + to { + opacity: 1; + transform: translateX(0) scale(1); + } +} + +@keyframes screenshotSlideDirect { + from { + opacity: 0; + transform: scale(0.985); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +.screenshot-image-fade { + animation: screenshotFadeIn 260ms ease both; +} + +.modal-panel-in { + animation: modalPanelIn 220ms ease both; +} + +.screenshot-slide-next { + animation: screenshotSlideNext 240ms ease both; +} + +.screenshot-slide-previous { + animation: screenshotSlidePrevious 240ms ease both; +} + +.screenshot-slide-direct { + animation: screenshotSlideDirect 200ms ease both; +} + .faq-item:hover { background: rgba(var(--theme-primary-rgb), 0.04); } diff --git a/landing/components/download-cta.tsx b/landing/components/download-cta.tsx index 2473a34..189fbfc 100644 --- a/landing/components/download-cta.tsx +++ b/landing/components/download-cta.tsx @@ -4,7 +4,14 @@ import { TiltLink } from "@/components/tilt-link"; function GithubIcon({ className }: { className?: string }) { return ( -
Logo de FreeTPV("latte"); + const [activeIndex, setActiveIndex] = useState(null); + const [slideDirection, setSlideDirection] = useState("direct"); + const activeScreenshot = activeIndex === null ? null : screenshots[activeIndex]; + const activeNumber = activeIndex === null ? 0 : activeIndex + 1; + const isDark = theme === "mocha"; + const themeLabel = isDark ? "Modo oscuro" : "Modo claro"; + + function getScreenshotSrc(screenshot: (typeof screenshots)[number]) { + return isDark ? screenshot.srcDark : screenshot.src; + } + + function handleScreenshotError( + event: React.SyntheticEvent, + fallbackSrc: string, + ) { + if (event.currentTarget.src.endsWith(fallbackSrc)) { + return; + } + + event.currentTarget.src = fallbackSrc; + } + + function closeCarousel() { + setActiveIndex(null); + } + + function openCarousel(index: number) { + setSlideDirection("direct"); + setActiveIndex(index); + } + + function showPrevious() { + setSlideDirection("previous"); + setActiveIndex((current) => { + if (current === null) return current; + return current === 0 ? screenshots.length - 1 : current - 1; + }); + } + + function showNext() { + setSlideDirection("next"); + setActiveIndex((current) => { + if (current === null) return current; + return current === screenshots.length - 1 ? 0 : current + 1; + }); + } + + function showDirect(index: number) { + setSlideDirection("direct"); + setActiveIndex(index); + } + + useEffect(() => { + setTheme(getInitialTheme()); + + const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + const root = document.documentElement; + + function updateThemeFromDocument() { + setTheme(getInitialTheme()); + } + + const observer = new MutationObserver(updateThemeFromDocument); + observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] }); + mediaQuery.addEventListener("change", updateThemeFromDocument); + + return () => { + observer.disconnect(); + mediaQuery.removeEventListener("change", updateThemeFromDocument); + }; + }, []); + + useEffect(() => { + if (activeIndex === null) return; + + const previousOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + + function handleKeyDown(event: KeyboardEvent) { + if (event.key === "Escape") closeCarousel(); + if (event.key === "ArrowLeft") showPrevious(); + if (event.key === "ArrowRight") showNext(); + } + + document.addEventListener("keydown", handleKeyDown); + + return () => { + document.body.style.overflow = previousOverflow; + document.removeEventListener("keydown", handleKeyDown); + }; + }, [activeIndex]); + return (
@@ -40,33 +170,129 @@ export function Screenshots() { Un vistazo a FreeTPV

- Las capturas mostrarán las partes principales de la aplicación, + Capturas reales de las partes principales de la aplicación, desde la venta diaria hasta la configuración del negocio.

- {screenshots.map((screenshot) => ( -
-
-
-
- -
-

- Captura pendiente -

-

- {screenshot.filename} -

+ {screenshots.map((screenshot, index) => ( +
+ ))}
+ + {activeScreenshot && ( +
+
event.stopPropagation()}> +
+
+
+

+ {activeNumber} / {screenshots.length} +

+ + {themeLabel} + +
+

{activeScreenshot.title}

+
+ +
+ +
+ {activeScreenshot.alt} handleScreenshotError(event, activeScreenshot.src)} + /> + + + + +
+ +
+ {screenshots.map((screenshot, index) => ( + + ))} +
+
+
+ )}
); } diff --git a/landing/package-lock.json b/landing/package-lock.json index 5ddf890..12fbe1f 100644 --- a/landing/package-lock.json +++ b/landing/package-lock.json @@ -1,11 +1,11 @@ { - "name": "landing", + "name": "freetpv-landing", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "landing", + "name": "freetpv-landing", "version": "0.1.0", "dependencies": { "lucide-react": "^1.16.0", @@ -1606,6 +1606,35 @@ "tailwindcss": "4.3.0" } }, + "node_modules/@tailwindcss/postcss/node_modules/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", @@ -5201,9 +5230,9 @@ } }, "node_modules/next/node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", "funding": [ { "type": "opencollective", @@ -5220,9 +5249,9 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -5517,35 +5546,6 @@ "node": ">= 0.4" } }, - "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.12", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", diff --git a/landing/package.json b/landing/package.json index 7b425db..c4d57a5 100644 --- a/landing/package.json +++ b/landing/package.json @@ -23,5 +23,8 @@ "eslint-config-next": "16.2.6", "tailwindcss": "^4", "typescript": "^5" + }, + "overrides": { + "postcss": "8.5.10" } } diff --git a/landing/public/images/logo.webp b/landing/public/images/logo.webp new file mode 100644 index 0000000..caa9beb Binary files /dev/null and b/landing/public/images/logo.webp differ diff --git a/landing/public/images/screenshots/screenshot-ajustes-d.webp b/landing/public/images/screenshots/screenshot-ajustes-d.webp new file mode 100644 index 0000000..a63a1ea Binary files /dev/null and b/landing/public/images/screenshots/screenshot-ajustes-d.webp differ diff --git a/landing/public/images/screenshots/screenshot-ajustes.webp b/landing/public/images/screenshots/screenshot-ajustes.webp new file mode 100644 index 0000000..25c7bab Binary files /dev/null and b/landing/public/images/screenshots/screenshot-ajustes.webp differ diff --git a/landing/public/images/screenshots/screenshot-cobro-d.webp b/landing/public/images/screenshots/screenshot-cobro-d.webp new file mode 100644 index 0000000..47a6d30 Binary files /dev/null and b/landing/public/images/screenshots/screenshot-cobro-d.webp differ diff --git a/landing/public/images/screenshots/screenshot-cobro.webp b/landing/public/images/screenshots/screenshot-cobro.webp new file mode 100644 index 0000000..026c6d3 Binary files /dev/null and b/landing/public/images/screenshots/screenshot-cobro.webp differ diff --git a/landing/public/images/screenshots/screenshot-productos-d.webp b/landing/public/images/screenshots/screenshot-productos-d.webp new file mode 100644 index 0000000..095d9ac Binary files /dev/null and b/landing/public/images/screenshots/screenshot-productos-d.webp differ diff --git a/landing/public/images/screenshots/screenshot-productos.webp b/landing/public/images/screenshots/screenshot-productos.webp new file mode 100644 index 0000000..ec68600 Binary files /dev/null and b/landing/public/images/screenshots/screenshot-productos.webp differ diff --git a/landing/public/images/screenshots/screenshot-ventas-d.webp b/landing/public/images/screenshots/screenshot-ventas-d.webp new file mode 100644 index 0000000..6cf48c3 Binary files /dev/null and b/landing/public/images/screenshots/screenshot-ventas-d.webp differ diff --git a/landing/public/images/screenshots/screenshot-ventas.webp b/landing/public/images/screenshots/screenshot-ventas.webp new file mode 100644 index 0000000..fdaf657 Binary files /dev/null and b/landing/public/images/screenshots/screenshot-ventas.webp differ diff --git a/landing/public/logo.png b/landing/public/logo.png deleted file mode 100644 index 636530c..0000000 Binary files a/landing/public/logo.png and /dev/null differ diff --git a/src/main/resources/com/mateo/freetpv/view/main-view.fxml b/src/main/resources/com/mateo/freetpv/view/main-view.fxml index c00726a..0f037d2 100644 --- a/src/main/resources/com/mateo/freetpv/view/main-view.fxml +++ b/src/main/resources/com/mateo/freetpv/view/main-view.fxml @@ -13,7 +13,7 @@ - + @@ -72,7 +72,10 @@ - - - +