responsive mobile

main
tuanpep 2 years ago
parent e577a90e65
commit 421e53fd20
  1. 102
      src/pages/Animated.tsx
  2. 2
      src/pages/Home.tsx
  3. 10
      src/shared/components/Footer.tsx
  4. 15
      src/shared/components/Header.tsx
  5. 40
      src/shared/components/animated/Introduction.tsx
  6. 22
      src/shared/components/animated/MysteriousText.tsx
  7. 30
      src/shared/components/animated/Trail.tsx
  8. 21
      src/shared/components/home/AboutSection.tsx
  9. 50
      src/shared/components/home/RoadMap.tsx
  10. 59
      src/shared/components/home/TokenomicsSection.tsx
  11. 1
      src/shared/components/layouts/HomeLayout.tsx
  12. 7
      src/shared/providers/RouterProviderComponent.tsx

@ -1,6 +1,18 @@
import React, { useRef } from "react"; import {
import { Parallax, ParallaxLayer, IParallax } from "@react-spring/parallax"; IParallax,
IParallaxLayer,
Parallax,
ParallaxLayer,
} from "@react-spring/parallax";
import { useScroll } from "@react-spring/web";
import React, { useEffect } from "react";
import { useRef } from "react";
import Introduction from "../shared/components/animated/Introduction"; import Introduction from "../shared/components/animated/Introduction";
import Footer from "../shared/components/Footer";
import Header from "../shared/components/Header";
import AboutSection from "../shared/components/home/AboutSection";
import RoadMap from "../shared/components/home/RoadMap";
import TokenomicsSection from "../shared/components/home/TokenomicsSection";
// Little helpers ... // Little helpers ...
const url = (name: string, wrap = false) => const url = (name: string, wrap = false) =>
@ -12,41 +24,52 @@ const url = (name: string, wrap = false) =>
function Animated() { function Animated() {
const parallax = useRef<IParallax>(null!); const parallax = useRef<IParallax>(null!);
const [isScrolled, setIsScrolled] = React.useState(false);
const onScroll = () => {
if (parallax.current.container.current.scrollTop > 0) {
setIsScrolled(true);
} else {
setIsScrolled(false);
}
};
useEffect(() => {
if (!parallax.current || !parallax.current.container) return;
parallax.current.container.current.onscroll = onScroll;
});
return ( return (
<div className="w-full min-h-screen bg-[#253237]"> <div className="w-full min-h-screen bg-[#253237]">
<Parallax ref={parallax} pages={3}> <Parallax ref={parallax} pages={4.2}>
<ParallaxLayer
sticky={{ start: 0, end: 4 }}
style={{ height: "fit-content" }}
>
<Header />
</ParallaxLayer>
<ParallaxLayer <ParallaxLayer
offset={1} offset={1}
speed={1} speed={1}
style={{ backgroundColor: "#805E73" }} style={{ backgroundColor: "#133955" }}
/> />
<ParallaxLayer <ParallaxLayer
offset={2} offset={2}
speed={1} speed={1}
style={{ backgroundColor: "#87BCDE" }} style={{ backgroundColor: "#3A7575" }}
/> />
<ParallaxLayer <ParallaxLayer
offset={0} offset={0}
speed={0} speed={0}
factor={3} factor={4}
style={{ style={{
backgroundImage: url("stars", true), backgroundImage: url("stars", true),
backgroundSize: "cover", backgroundSize: "cover",
}} }}
/> />
<ParallaxLayer
offset={1.3}
speed={-0.3}
style={{ pointerEvents: "none" }}
>
<img
src={url("satellite4")}
style={{ width: "15%", marginLeft: "70%" }}
/>
</ParallaxLayer>
<ParallaxLayer offset={1} speed={0.8} style={{ opacity: 0.1 }}> <ParallaxLayer offset={1} speed={0.8} style={{ opacity: 0.1 }}>
<img <img
src={url("cloud")} src={url("cloud")}
@ -115,11 +138,9 @@ function Animated() {
justifyContent: "center", justifyContent: "center",
pointerEvents: "none", pointerEvents: "none",
}} }}
> ></ParallaxLayer>
<img src={url("earth")} style={{ width: "60%" }} />
</ParallaxLayer>
<ParallaxLayer {/* <ParallaxLayer
offset={2} offset={2}
speed={-0.3} speed={-0.3}
style={{ style={{
@ -127,18 +148,22 @@ function Animated() {
backgroundPosition: "center", backgroundPosition: "center",
backgroundImage: url("clients", true), backgroundImage: url("clients", true),
}} }}
/> /> */}
{/* section 1 */} {/* section 1 */}
<ParallaxLayer <ParallaxLayer
offset={0} offset={0}
speed={0.1} speed={0.1}
onScroll={() => parallax.current.scrollTo(1)}
style={{ style={{
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}} }}
id="section1"
onClick={() => parallax.current.scrollTo(1)}
onScroll={(e) => {
console.log("e", e);
}}
> >
<Introduction /> <Introduction />
</ParallaxLayer> </ParallaxLayer>
@ -153,7 +178,7 @@ function Animated() {
justifyContent: "center", justifyContent: "center",
}} }}
> >
<img src={url("bash")} style={{ width: "40%" }} /> <AboutSection />
</ParallaxLayer> </ParallaxLayer>
<ParallaxLayer <ParallaxLayer
@ -164,9 +189,36 @@ function Animated() {
alignItems: "center", alignItems: "center",
justifyContent: "center", justifyContent: "center",
}} }}
onClick={() => parallax.current.scrollTo(3)}
>
<RoadMap />
</ParallaxLayer>
<ParallaxLayer
offset={3}
speed={-0}
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
onClick={() => parallax.current.scrollTo(0)}
>
<TokenomicsSection />
</ParallaxLayer>
<ParallaxLayer
offset={4}
speed={-0}
style={{
display: "flex",
alignItems: "start",
justifyContent: "center",
backgroundColor: "#000000",
}}
onClick={() => parallax.current.scrollTo(0)} onClick={() => parallax.current.scrollTo(0)}
> >
<img src={url("clients-main")} style={{ width: "40%" }} /> <Footer />
</ParallaxLayer> </ParallaxLayer>
</Parallax> </Parallax>
</div> </div>

@ -7,7 +7,7 @@ type Props = {};
const Home = (props: Props) => { const Home = (props: Props) => {
return ( return (
<div className="flex flex-col gap-20"> <div className="flex flex-col gap-20 bg-[#253237]">
<FirstSection /> <FirstSection />
<AboutSection /> <AboutSection />
<RoadMap /> <RoadMap />

@ -4,7 +4,7 @@ type Props = {};
const Footer = (props: Props) => { const Footer = (props: Props) => {
return ( return (
<div className="container mx-auto flex justify-between text-white py-12"> <div className="container mx-auto md: px-4 flex flex-col gap-4 items-center md:flex-row justify-between text-white py-12">
<div className="md:w-1/4 flex gap-2 items-center"> <div className="md:w-1/4 flex gap-2 items-center">
<div className="bg-white rounded-full overflow-hidden p-1"> <div className="bg-white rounded-full overflow-hidden p-1">
<img <img
@ -22,10 +22,10 @@ const Footer = (props: Props) => {
</div> </div>
<div className="md:w-2/5 flex justify-between items-center"> <div className="md:w-2/5 flex justify-between items-center">
<p>NFT Systems</p> <p className="text-center">NFT Systems</p>
<p>Team</p> <p className="text-center">Team</p>
<p>Privacy Policy</p> <p className="text-center">Privacy Policy</p>
<p>Terms & Conditions</p> <p className="text-center">Terms & Conditions</p>
</div> </div>
</div> </div>
); );

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect } from "react";
import Button from "./Button"; import Button from "./Button";
import robotLogo from "../../assets/images/robot-logo.png"; import robotLogo from "../../assets/images/robot-logo.png";
import { BsNewspaper, BsGithub } from "react-icons/bs"; import { BsNewspaper, BsGithub } from "react-icons/bs";
@ -17,14 +17,14 @@ const menuItems = [
id: "about", id: "about",
}, },
{ {
name: "Tokenomics", name: "Roadmap",
path: "", path: "",
id: "tokenomics", id: "roadmap",
}, },
{ {
name: "Roadmap", name: "Tokenomics",
path: "", path: "",
id: "roadmap", id: "tokenomics",
}, },
]; ];
@ -32,6 +32,10 @@ const Header = (props: Props) => {
const [isScrolled, setIsScrolled] = React.useState(false); const [isScrolled, setIsScrolled] = React.useState(false);
React.useEffect(() => { React.useEffect(() => {
// check is mobile or tablet
if (window.innerWidth <= 1024) {
setIsScrolled(true);
} else {
window.addEventListener("scroll", () => { window.addEventListener("scroll", () => {
if (window.scrollY > 0) { if (window.scrollY > 0) {
setIsScrolled(true); setIsScrolled(true);
@ -39,6 +43,7 @@ const Header = (props: Props) => {
setIsScrolled(false); setIsScrolled(false);
} }
}); });
}
}, []); }, []);
const jumpToSection = (section: string) => { const jumpToSection = (section: string) => {

@ -1,5 +1,4 @@
import { useTrail } from "@react-spring/web"; import { useEffect } from "react";
import React from "react";
import { import {
BsDiscord, BsDiscord,
BsFacebook, BsFacebook,
@ -8,28 +7,41 @@ import {
BsTwitter, BsTwitter,
} from "react-icons/bs"; } from "react-icons/bs";
import Button from "../Button"; import Button from "../Button";
import Trail from "./Trail"; import MysteriousText from "./MysteriousText";
type Props = {}; type Props = {};
const Introduction = (props: Props) => { const Introduction = (props: Props) => {
// create animate when user scroll to this section
useEffect(() => {
const section = document.getElementById("section1");
if (section) {
section.addEventListener("scroll", () => {
console.log("scroll");
});
}
}, []);
return ( return (
<div className="flex flex-col gap-10 items-center text-white lg:w-3/4 max-w-4xl"> <div
className="flex flex-col gap-10 items-center text-white p-10 lg:p-0 lg:w-3/4 max-w-4xl"
id="section1"
>
<h4 className="lg:text-8xl md:text-7xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-pink-600"> <h4 className="lg:text-8xl md:text-7xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-purple-400 to-pink-600">
<Trail open={true}> <MysteriousText>
<span>A digital currency</span> A digital currency payment for SGPT chat bot services
<span>payment for SGPT</span> </MysteriousText>
<span>chat bot services</span>
</Trail>
</h4> </h4>
<p className="w-full font-body text-transparent bg-clip-text bg-gradient-to-r from-sky-400 to-purple-300"> <p className="w-full font-body text-transparent bg-clip-text bg-gradient-to-r from-sky-400 to-purple-300">
The SGPT Token is a digital currency designed to facilitate payments for <MysteriousText>
services provided by the SGPT chat bot. The chat bot is a powerful tool The SGPT Token is a digital currency designed to facilitate payments
that utilizes artificial intelligence to communicate with users and for services provided by the SGPT chat bot. The chat bot is a powerful
provide valuable information and services. tool that utilizes artificial intelligence to communicate with users
and provide valuable information and services.
</MysteriousText>
</p> </p>
<div className="flex flex-col justify-center mt-[15vh]"> <div className="flex flex-col justify-center mt-[15vh] z-50">
<h2 className="text-3xl mb-4 font-bold text-center"> <h2 className="text-3xl mb-4 font-bold text-center">
Join Our Community Join Our Community
</h2> </h2>

@ -0,0 +1,22 @@
import { useSpring, animated } from "@react-spring/web";
import React from "react";
type Props = {
children: string;
};
const MysteriousText = ({ children, ...props }: Props) => {
const animation = (i: any) =>
useSpring({ opacity: 1, from: { opacity: 0 }, delay: Math.random() * 500 });
return (
<>
{children.split("").map((item, index) => (
<animated.span key={index} style={animation(index)} {...props}>
{item}
</animated.span>
))}
</>
);
};
export default MysteriousText;

@ -1,30 +0,0 @@
import { a, useTrail } from "@react-spring/web";
import React from "react";
import styles from "./styles.module.css";
type Props = {
open: boolean;
children: React.ReactNode;
};
const Trail: React.FC<Props> = ({ open, children }) => {
const items = React.Children.toArray(children);
const trail = useTrail(items.length, {
config: { mass: 5, tension: 2000, friction: 200 },
opacity: open ? 1 : 0,
x: open ? 0 : 20,
height: open ? 110 : 0,
from: { opacity: 0, x: 20, height: 0 },
});
return (
<div>
{trail.map(({ height, ...style }, index) => (
<a.div key={index} className="will-change-auto" style={style}>
<a.div style={{ height }}>{items[index]}</a.div>
</a.div>
))}
</div>
);
};
export default Trail;

@ -1,5 +1,6 @@
import React from "react"; import React from "react";
import aboutImage from "../../../assets/images/robot32.png"; import aboutImage from "../../../assets/images/robot32.png";
import MysteriousText from "../animated/MysteriousText";
type Props = {}; type Props = {};
const AboutSection = (props: Props) => { const AboutSection = (props: Props) => {
@ -11,23 +12,29 @@ const AboutSection = (props: Props) => {
<div <div
className="container mx-auto text-white py-20 flex relative" className="container mx-auto text-white py-20 flex relative"
id="about" id="about"
style={{
backgroundImage: `url(https://awv3node-homepage.surge.sh/build/assets/stars.svg)}`,
}}
> >
<div className="flex flex-col justify-center gap-10 lg:w-1/2 w-full px-8"> <div className="flex flex-col justify-center gap-10 lg:w-1/2 w-full px-8">
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<h4 className="text-5xl uppercase font-bold">What is SGPT?</h4> <h4 className="text-5xl uppercase font-bold">What is SGPT?</h4>
<p className="text-gray-300 md:w-4/5 text-lg"> <p className="text-gray-100 md:w-4/5 text-lg">
<MysteriousText>
SGPT Token is a complementary token created on the blockchain SGPT Token is a complementary token created on the blockchain
platform to provide a platform for small and medium-sized businesses platform to provide a platform for small and medium-sized
(SMBs) to create and manage an internal Q&A system. SGPT Token will businesses (SMBs) to create and manage an internal Q&A system.
be used to conduct transactions on the platform and provide benefits SGPT Token will be used to conduct transactions on the platform
to members of the internal Q&A system. SGPT Token will also be used and provide benefits to members of the internal Q&A system. SGPT
to reward members who make positive contributions to the system. Token will also be used to reward members who make positive
contributions to the system.
</MysteriousText>
</p> </p>
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<h4 className="text-5xl uppercase font-bold">SGPT Solution</h4> <h4 className="text-5xl uppercase font-bold">SGPT Solution</h4>
<p className="text-gray-300 md:w-4/5 text-lg"> <p className="text-gray-100 md:w-4/5 text-lg">
The SGPT Token is a solution to the problems associated with The SGPT Token is a solution to the problems associated with
traditional payment methods for chat bot services. The token is traditional payment methods for chat bot services. The token is
built on blockchain technology, which ensures that transactions are built on blockchain technology, which ensures that transactions are

@ -1,4 +1,5 @@
import React from "react"; import { useSpring, animated } from "@react-spring/web";
import React, { useEffect, useRef, useState } from "react";
import { VscDebugBreakpointLog } from "react-icons/vsc"; import { VscDebugBreakpointLog } from "react-icons/vsc";
type Props = {}; type Props = {};
@ -40,16 +41,53 @@ const roadMapData = [
]; ];
const RoadMap = (props: Props) => { const RoadMap = (props: Props) => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const section = document.querySelector(".animate-on-scroll");
const observer = new IntersectionObserver(
([entry]) => {
setIsVisible(entry.isIntersecting);
},
{ threshold: 0.5 }
);
if (!section) {
return;
}
observer.observe(section);
return () => {
observer.unobserve(section);
};
}, []);
useEffect(() => {
console.log("isVisible", isVisible);
}, [isVisible]);
const styles = useSpring({
opacity: isVisible ? 1 : 0,
transform: isVisible ? "translateY(0)" : "translateY(100px)",
config: {
duration: 500,
},
});
return ( return (
<div className="container mx-auto text-white md:min-h-[60vh]" id="roadmap"> <div
className="container mx-auto text-white md:min-h-[60vh] animate-on-scroll py-20"
id="roadmap"
>
<h1 className="text-5xl font-bold text-center">RoadMap</h1> <h1 className="text-5xl font-bold text-center">RoadMap</h1>
<div className="flex flex-col gap-10 mt-20 justify-center px-10 lg:px-0"> <div className="flex flex-col lg:flex-row gap-10 mt-20 justify-center px-10 lg:px-0">
{roadMapData.map((item, index) => { {roadMapData.map((item, index) => {
return ( return (
<div <animated.div
key={index} key={index}
className="lg:w-1/4 bg-[conic-gradient(at_left,_var(--tw-gradient-stops))] from-orange-400 to-rose-400 rounded-lg min-h-[250px] p-5" className="lg:w-1/4 bg-[#E24666] rounded-lg min-h-[250px] p-5"
style={styles}
> >
<h4 className="text-center text-3xl text-gray-100 font-semibold mb-6"> <h4 className="text-center text-3xl text-gray-100 font-semibold mb-6">
{item.phase} {item.phase}
@ -64,7 +102,7 @@ const RoadMap = (props: Props) => {
); );
})} })}
</ol> </ol>
</div> </animated.div>
); );
})} })}
</div> </div>

@ -1,3 +1,5 @@
import { useSpring, animated } from "@react-spring/web";
import { useEffect, useState } from "react";
import tokenomicChart from "../../../assets/images/tokenomic-chart.png"; import tokenomicChart from "../../../assets/images/tokenomic-chart.png";
type Props = {}; type Props = {};
@ -46,25 +48,68 @@ const tokenomics = [
]; ];
const TokenomicsSection = (props: Props) => { const TokenomicsSection = (props: Props) => {
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
const section = document.querySelector("#tokenomics");
const observer = new IntersectionObserver(
([entry]) => {
setIsVisible(entry.isIntersecting);
},
{ threshold: 0.5 }
);
if (!section) {
return;
}
observer.observe(section);
return () => {
observer.unobserve(section);
};
}, []);
useEffect(() => {
console.log("isVisible", isVisible);
}, [isVisible]);
const styles = useSpring({
opacity: isVisible ? 1 : 0,
from: {
opacity: 0,
transform: "translateY(100px)",
},
to: {
opacity: isVisible ? 1 : 0,
transform: "translateY(0px)",
},
config: {
duration: 500,
},
});
return ( return (
<div className="w-full bg-white py-24" id="tokenomics"> <div className="w-full py-24" id="tokenomics">
<div className="container mx-auto"> <div className="container mx-auto">
<h1 className="text-5xl font-bold text-center text-black mb-20"> <h1 className="text-5xl text-white font-bold text-center mb-20">
Tokenomics Tokenomics
</h1> </h1>
<div className="w-full flex flex-col lg:flex-row"> <div className="w-full flex flex-col gap-4 lg:flex-row">
<div className="lg:w-1/2"> <div className="lg:w-1/2 flex justify-center">
<img src={tokenomicChart} alt="" /> <img src={tokenomicChart} alt="" className="rounded-3xl w-[80%]" />
</div> </div>
<div className="lg:w-1/2"> <div className="lg:w-1/2">
<ul className="flex flex-col items-end justify-center h-full gap-3 px-3"> <ul className="flex flex-col items-end justify-center h-full gap-3 px-3">
{tokenomics.map((item, index) => { {tokenomics.map((item, index) => {
return ( return (
<li <animated.li
key={index} key={index}
className={`text-center w-full lg:w-2/3 bg-slate-200 py-3 relative`} className={`text-center w-full lg:w-2/3 bg-slate-200 py-3 relative`}
style={{
...styles,
}}
> >
<div <div
className={`absolute h-full top-0 w-2 ${item.color}`} className={`absolute h-full top-0 w-2 ${item.color}`}
@ -73,7 +118,7 @@ const TokenomicsSection = (props: Props) => {
{item.title} {item.title}
</h4> </h4>
<p className="text-gray-500">{item.description}</p> <p className="text-gray-500">{item.description}</p>
</li> </animated.li>
); );
})} })}
</ul> </ul>

@ -11,6 +11,7 @@ const HomeLayout = (props: Props) => {
<div className="w-full"> <div className="w-full">
<Outlet /> <Outlet />
</div> </div>
<Footer />
</div> </div>
); );
}; };

@ -8,11 +8,14 @@ const router = createBrowserRouter([
path: "/", path: "/",
element: <HomeLayout />, element: <HomeLayout />,
children: [ children: [
{ path: "", element: <Home /> },
{ {
path: "fuck", path: "animated",
element: <Animated />, element: <Animated />,
}, },
{
path: "",
element: <Home />,
},
], ],
}, },
]); ]);

Loading…
Cancel
Save