diff --git a/package-lock.json b/package-lock.json index 7fb5bb3..f95dfbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "axios": "^1.9.0", "bootstrap": "^5.3.6", "bootstrap-icons": "^1.13.1", + "framer-motion": "^12.18.1", "next": "15.3.3", "react": "^19.0.0", "react-dom": "^19.0.0" @@ -987,6 +988,33 @@ "node": ">= 6" } }, + "node_modules/framer-motion": { + "version": "12.18.1", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.18.1.tgz", + "integrity": "sha512-6o4EDuRPLk4LSZ1kRnnEOurbQ86MklVk+Y1rFBUKiF+d2pCdvMjWVu0ZkyMVCTwl5UyTH2n/zJEJx+jvTYuxow==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.18.1", + "motion-utils": "^12.18.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1195,6 +1223,21 @@ "node": ">= 0.6" } }, + "node_modules/motion-dom": { + "version": "12.18.1", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.18.1.tgz", + "integrity": "sha512-dR/4EYT23Snd+eUSLrde63Ws3oXQtJNw/krgautvTfwrN/2cHfCZMdu6CeTxVfRRWREW3Fy1f5vobRDiBb/q+w==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.18.1" + } + }, + "node_modules/motion-utils": { + "version": "12.18.1", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.18.1.tgz", + "integrity": "sha512-az26YDU4WoDP0ueAkUtABLk2BIxe28d8NH1qWT8jPGhPyf44XTdDUh8pDk9OPphaSrR9McgpcJlgwSOIw/sfkA==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", diff --git a/package.json b/package.json index 56f7819..1ca78ab 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "axios": "^1.9.0", "bootstrap": "^5.3.6", "bootstrap-icons": "^1.13.1", + "framer-motion": "^12.18.1", "next": "15.3.3", "react": "^19.0.0", "react-dom": "^19.0.0" diff --git a/src/app/(auth)/page.tsx b/src/app/(auth)/page.tsx index fb926eb..1d31a6b 100644 --- a/src/app/(auth)/page.tsx +++ b/src/app/(auth)/page.tsx @@ -3,9 +3,22 @@ import SimpleInput from "@/components/input"; import PasswordInput from "@/components/password"; import React from "react"; + +import { motion } from "framer-motion"; + + export default function Page() { return ( -
+ + + + +

Bienvenido al sistema de

Carga Masiva

-
+ + ); } diff --git a/src/app/landing/IconCircle.css b/src/app/landing/IconCircle.css new file mode 100644 index 0000000..7f6f6e5 --- /dev/null +++ b/src/app/landing/IconCircle.css @@ -0,0 +1,45 @@ +* { + padding: none; + margin: none; +} + +.icon-circle { + position: relative; + width: 300px; + height: 300px; + margin: 2rem auto; + border-radius: 50%; +} + +.central-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 2rem; + background: white; + padding: 1rem; + border-radius: 50%; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + z-index: 1; +} + +.floating-icon { + position: absolute; + width: 40px; + height: 40px; + background: white; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + top: 50%; + left: 50%; + transform: rotate(calc(45deg * var(--i))) translate(130px) rotate(calc(-45deg * var(--i))); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); +} + +.floating-icon i { + font-size: 1.25rem; + color: #7c3aed; /* Morado como el diseño */ +} diff --git a/src/app/landing/IconCircle.tsx b/src/app/landing/IconCircle.tsx new file mode 100644 index 0000000..6fd4acb --- /dev/null +++ b/src/app/landing/IconCircle.tsx @@ -0,0 +1,60 @@ +// IconCircle.tsx +'use client'; +import React from 'react'; +import { motion } from 'framer-motion'; +import './IconCircle.css'; + +const iconClasses = [ + 'bi bi-graph-up', + 'bi bi-lightning-fill', + 'bi bi-currency-exchange', + 'bi bi-globe2', + 'bi bi-bar-chart-line-fill', + 'bi bi-arrow-left-right', + 'bi bi-bank', + 'bi bi-boxes', +]; + +interface IconCircleProps { + delay?: number; +} + +const IconCircle: React.FC = ({ delay = 0 }) => { + return ( +
+ + + + + {iconClasses.map((iconClass, i) => ( + + + + ))} +
+ ); +}; + +export default IconCircle; diff --git a/src/app/landing/globals.css b/src/app/landing/globals.css new file mode 100644 index 0000000..4ed1e28 --- /dev/null +++ b/src/app/landing/globals.css @@ -0,0 +1,152 @@ +* { + padding: none; + margin: none; +} + + /* Fondo general y tipografía */ + body { + margin: 0; + font-family: 'Segoe UI', sans-serif; + background: radial-gradient(circle at center, #f8f4ff, hsl(218, 45%, 37%)); + + /* background: radial-gradient(circle at center, #f8f4ff, hsl(217, 100%, 89%)); */ + + color: #1a1a1a; + text-align: center; + + } + + /* Header */ + header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1.5rem 2rem; + background: transparent; + font-weight: bold; + } + + header div:first-child { + font-size: 1.5rem; + color: #5b2edd; + } + + .nav-links { + background-color: white; + padding: 10px; + border-radius: 50px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); /* sombra suave */ + display: flex; + gap: 1rem; /* espacio entre los */ + } + + header a { + margin: 0 0.75rem; + text-decoration: none; + color: #333; + font-weight: 500; + } + + header button { + margin-left: 0.5rem; + padding: 0.4rem 1rem; + border-radius: 20px; + border: none; + font-weight: 600; + cursor: pointer; + } + + header button:first-of-type { + background-color: white; + border: 1px solid #ccc; + color: #555; + } + + header button:last-of-type { + background-color: #0033ff; + color: white; + } + + /* Texto principal */ + strong { + display: block; + font-size: 2.5rem; + margin: 2rem 0 1rem; + } + + p { + font-size: 1rem; + color: #555; + /* max-width: 600px; */ + margin: 0 auto 1rem; + } + + /* Botón principal */ + div > button { + margin-top: 1rem; + background-color: #5b2edd; + color: white; + padding: 0.7rem 2rem; + border: none; + border-radius: 25px; + font-size: 1rem; + cursor: pointer; + } + + /* Texto de "years of reliability" */ + div > div { + /* display: flex; */ + justify-content: center; + align-items: center; + gap: 0.5rem; + margin-top: 0.5rem; + } + + div > div p { + margin: 0; + font-size: 0.9rem; + color: #888; + } + + + + /* Scroll hint */ + body > p:last-of-type { + margin-top: 2rem; + font-size: 0.85rem; + color: #aaa; + letter-spacing: 1px; + } + +.circle-background { + margin-top: 0; + padding-top: 0; + position: fixed; + top: none; + left: none; + width: 100vw; + height: 100vh; + z-index: -1; /* para que esté detrás de todo */ + pointer-events: none; /* no interfiere con el contenido */ + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; +} + +.circle { + position: absolute; + background: radial-gradient(circle, rgb(255, 255, 255), transparent); + border-radius: 50%; + pointer-events: none; + backdrop-filter: blur(2px); +} + + + + + + +.invert { + filter: invert(1); +} \ No newline at end of file diff --git a/src/app/landing/landing_body.tsx b/src/app/landing/landing_body.tsx new file mode 100644 index 0000000..d7664aa --- /dev/null +++ b/src/app/landing/landing_body.tsx @@ -0,0 +1,31 @@ +// components/LandingBody.tsx +"use client"; + +import { motion } from "framer-motion"; +import IconCircle from "./IconCircle"; + +export default function LandingBody() { + return ( + + + + Explore markets ready for trading +

+ Explore 300+ trading instruments across 10+ asset classes with Alchemy + Markets. Trade Forex, Stocks, Indices, and more! +

+ +
+ +
+ +
+
+
+ ); +} diff --git a/src/app/landing/new_header.tsx b/src/app/landing/new_header.tsx new file mode 100644 index 0000000..72d53a2 --- /dev/null +++ b/src/app/landing/new_header.tsx @@ -0,0 +1,80 @@ +"use client"; + +import { motion } from "framer-motion"; +import Image from "next/image"; +import Link from "next/link"; + + + +interface HeaderProps { + onNavClick: (page: string) => void; +} + + + +export default function Header({ onNavClick }: HeaderProps) { + return ( + +
+ + Logo de la UNAM + +
+ + {/*
+ Trading + Platforms + Tools & Education + About Us + Partners + Login +
*/} + + + + + +
+ + Logo de la FES Acatlán + +
+ + ); +} diff --git a/src/app/landing/page.tsx b/src/app/landing/page.tsx new file mode 100644 index 0000000..cad61cf --- /dev/null +++ b/src/app/landing/page.tsx @@ -0,0 +1,91 @@ +"use client"; + +import "./globals.css"; +import "bootstrap-icons/font/bootstrap-icons.css"; +import IconCircle from "./IconCircle"; +import { motion } from "framer-motion"; +import Image from "next/image"; +import Link from "next/link"; + + +import Header from "./new_header"; // ajusta la ruta si estás en otra carpeta +import Footer from "@/components/layout/footer"; +import LandingBody from "./landing_body"; +import { useState } from "react"; +import Page from "../(auth)/page"; + + +type PageKey = "landing" | "login" | "admin" | "worker" | "publico"; + + +const Home = () => { + + + const [page, setPage] = useState("landing"); + + + + + + return ( + +
+ {[150, 300, 450, 600, 900].map((size, i) => ( + + ))} +
+ + {/* ⬇️ Tu contenido principal */} +
+ + {/* */} + {/* renderiza el body según el estado `page` */} + {page === "landing" && } + {page === "login" && } + {/* {page === "admin" && } + {page === "worker" && } + {page === "publico" && } + */} + + + {/* + + + + + + */} + + + + + + + + +
+ + + ); +}; + +export default Home; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 93a221f..9b5317a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,8 +4,7 @@ import { Roboto } from "next/font/google"; import 'bootstrap-icons/font/bootstrap-icons.css'; import '@/styles/sass/bootstrap.scss'; import BootstrapClient from "@/components/bootstrap-client"; -import Footer from "@/components/layout/footer"; -import Header from "@/components/layout/header"; + const roboto = Roboto({ weight: ["100", "300", "400", "500", "700", "900"], @@ -20,11 +19,8 @@ export default function RootLayout({ return ( -
-
- {children} -
-
+ + {children} ); diff --git a/src/components/layout/footer.tsx b/src/components/layout/footer.tsx index 3c44d77..fc4eb8b 100644 --- a/src/components/layout/footer.tsx +++ b/src/components/layout/footer.tsx @@ -1,20 +1,33 @@ import React from "react"; + + +import { motion } from "framer-motion"; + + export default function Footer() { const date = new Date(); const year = date.getFullYear(); - return ( - - ); -} + + ) +} \ No newline at end of file