Upload 26 files
Browse files- .gitattributes +8 -0
- Dockerfile +10 -0
- package-lock.json +0 -0
- package.json +39 -0
- public/Logo.jpg +0 -0
- public/Mockup1.png +3 -0
- public/Mockup2.png +3 -0
- public/Mockup3.png +3 -0
- public/Mockup4.png +3 -0
- public/apple badge.png +0 -0
- public/gp badge.png +0 -0
- public/index.html +43 -0
- public/logo.png +0 -0
- src/App.jsx +7 -0
- src/assets/Logo.jpg +0 -0
- src/assets/Mockup1.png +3 -0
- src/assets/Mockup2.png +3 -0
- src/assets/Mockup3.png +3 -0
- src/assets/Mockup4.png +3 -0
- src/assets/apple badge.png +0 -0
- src/assets/gp badge.png +0 -0
- src/assets/logo.png +0 -0
- src/components/Header.jsx +48 -0
- src/components/HeroDownloadSection.jsx +101 -0
- src/components/ShortCopywriting.jsx +140 -0
- src/index.jsx +10 -0
- src/pages/LandingPage.jsx +14 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,11 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
public/Mockup1.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
public/Mockup2.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
public/Mockup3.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
public/Mockup4.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
src/assets/Mockup1.png filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
src/assets/Mockup2.png filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
src/assets/Mockup3.png filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
src/assets/Mockup4.png filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM node:18
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
COPY package*.json ./
|
| 5 |
+
RUN npm install
|
| 6 |
+
COPY . .
|
| 7 |
+
RUN npm run build
|
| 8 |
+
|
| 9 |
+
RUN npm install -g serve
|
| 10 |
+
CMD ["serve", "-s", "build", "-l", "7860"]
|
package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "fitsion-landing",
|
| 3 |
+
"version": "0.1.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"dependencies": {
|
| 6 |
+
"@testing-library/dom": "^10.4.1",
|
| 7 |
+
"@testing-library/jest-dom": "^6.9.1",
|
| 8 |
+
"@testing-library/react": "^16.3.0",
|
| 9 |
+
"@testing-library/user-event": "^13.5.0",
|
| 10 |
+
"react": "^19.2.0",
|
| 11 |
+
"react-dom": "^19.2.0",
|
| 12 |
+
"react-scripts": "5.0.1",
|
| 13 |
+
"web-vitals": "^2.1.4"
|
| 14 |
+
},
|
| 15 |
+
"scripts": {
|
| 16 |
+
"start": "react-scripts start",
|
| 17 |
+
"build": "react-scripts build",
|
| 18 |
+
"test": "react-scripts test",
|
| 19 |
+
"eject": "react-scripts eject"
|
| 20 |
+
},
|
| 21 |
+
"eslintConfig": {
|
| 22 |
+
"extends": [
|
| 23 |
+
"react-app",
|
| 24 |
+
"react-app/jest"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
"browserslist": {
|
| 28 |
+
"production": [
|
| 29 |
+
">0.2%",
|
| 30 |
+
"not dead",
|
| 31 |
+
"not op_mini all"
|
| 32 |
+
],
|
| 33 |
+
"development": [
|
| 34 |
+
"last 1 chrome version",
|
| 35 |
+
"last 1 firefox version",
|
| 36 |
+
"last 1 safari version"
|
| 37 |
+
]
|
| 38 |
+
}
|
| 39 |
+
}
|
public/Logo.jpg
ADDED
|
public/Mockup1.png
ADDED
|
Git LFS Details
|
public/Mockup2.png
ADDED
|
Git LFS Details
|
public/Mockup3.png
ADDED
|
Git LFS Details
|
public/Mockup4.png
ADDED
|
Git LFS Details
|
public/apple badge.png
ADDED
|
public/gp badge.png
ADDED
|
public/index.html
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8" />
|
| 5 |
+
<link rel="icon" href="%PUBLIC_URL%/logo.png" />
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
<meta name="theme-color" content="#000000" />
|
| 8 |
+
<meta
|
| 9 |
+
name="description"
|
| 10 |
+
content="Web site created using create-react-app"
|
| 11 |
+
/>
|
| 12 |
+
<link rel="logo" href="%PUBLIC_URL%/logo.jpg" />
|
| 13 |
+
<!--
|
| 14 |
+
manifest.json provides metadata used when your web app is installed on a
|
| 15 |
+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
| 16 |
+
-->
|
| 17 |
+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
| 18 |
+
<!--
|
| 19 |
+
Notice the use of %PUBLIC_URL% in the tags above.
|
| 20 |
+
It will be replaced with the URL of the `public` folder during the build.
|
| 21 |
+
Only files inside the `public` folder can be referenced from the HTML.
|
| 22 |
+
|
| 23 |
+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
| 24 |
+
work correctly both with client-side routing and a non-root public URL.
|
| 25 |
+
Learn how to configure a non-root public URL by running `npm run build`.
|
| 26 |
+
-->
|
| 27 |
+
<title>Fitsion</title>
|
| 28 |
+
</head>
|
| 29 |
+
<body>
|
| 30 |
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
| 31 |
+
<div id="root"></div>
|
| 32 |
+
<!--
|
| 33 |
+
This HTML file is a template.
|
| 34 |
+
If you open it directly in the browser, you will see an empty page.
|
| 35 |
+
|
| 36 |
+
You can add webfonts, meta tags, or analytics to this file.
|
| 37 |
+
The build step will place the bundled scripts into the <body> tag.
|
| 38 |
+
|
| 39 |
+
To begin the development, run `npm start` or `yarn start`.
|
| 40 |
+
To create a production bundle, use `npm run build` or `yarn build`.
|
| 41 |
+
-->
|
| 42 |
+
</body>
|
| 43 |
+
</html>
|
public/logo.png
ADDED
|
src/App.jsx
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import LandingPage from "./pages/LandingPage";
|
| 2 |
+
|
| 3 |
+
function App() {
|
| 4 |
+
return <LandingPage />;
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
export default App;
|
src/assets/Logo.jpg
ADDED
|
src/assets/Mockup1.png
ADDED
|
Git LFS Details
|
src/assets/Mockup2.png
ADDED
|
Git LFS Details
|
src/assets/Mockup3.png
ADDED
|
Git LFS Details
|
src/assets/Mockup4.png
ADDED
|
Git LFS Details
|
src/assets/apple badge.png
ADDED
|
src/assets/gp badge.png
ADDED
|
src/assets/logo.png
ADDED
|
src/components/Header.jsx
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
import { motion } from "framer-motion";
|
| 3 |
+
import logo from "../assets/logo.png"; // ganti dengan logo kamu
|
| 4 |
+
|
| 5 |
+
export default function Header() {
|
| 6 |
+
// Fungsi untuk menggulir halaman ke bagian paling atas (koordinat y=0)
|
| 7 |
+
const scrollToTop = () => {
|
| 8 |
+
window.scrollTo({
|
| 9 |
+
top: 0,
|
| 10 |
+
behavior: "smooth", // Memberikan animasi gulir yang mulus
|
| 11 |
+
});
|
| 12 |
+
};
|
| 13 |
+
|
| 14 |
+
return (
|
| 15 |
+
<header
|
| 16 |
+
style={{
|
| 17 |
+
position: "sticky",
|
| 18 |
+
top: 0,
|
| 19 |
+
width: "100%",
|
| 20 |
+
background: "linear-gradient(135deg, #FFFFFF 0%, #FBE9D8 25%, #FB8A8A 50%, #8A3B6F 75%, #83B9FF 100%)",
|
| 21 |
+
padding: "10px 0",
|
| 22 |
+
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
|
| 23 |
+
zIndex: 1000,
|
| 24 |
+
display: "flex",
|
| 25 |
+
justifyContent: "center",
|
| 26 |
+
alignItems: "center",
|
| 27 |
+
height: 80, // tetap tinggi header
|
| 28 |
+
userSelect: "none"
|
| 29 |
+
}}
|
| 30 |
+
>
|
| 31 |
+
<motion.img
|
| 32 |
+
src={logo}
|
| 33 |
+
alt="Fitsion Logo"
|
| 34 |
+
style={{
|
| 35 |
+
maxHeight: "150px",
|
| 36 |
+
// Menambahkan gaya kursor dan userSelect pada logo
|
| 37 |
+
cursor: "pointer",
|
| 38 |
+
userSelect: "none"
|
| 39 |
+
}}
|
| 40 |
+
// PENTING: Menambahkan onClick HANYA pada logo
|
| 41 |
+
onClick={scrollToTop}
|
| 42 |
+
initial={{ opacity: 0, y: -20 }}
|
| 43 |
+
animate={{ opacity: 1, y: 0 }}
|
| 44 |
+
transition={{ duration: 0.8 }}
|
| 45 |
+
/>
|
| 46 |
+
</header>
|
| 47 |
+
);
|
| 48 |
+
}
|
src/components/HeroDownloadSection.jsx
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
import { motion } from "framer-motion";
|
| 3 |
+
|
| 4 |
+
import googlePlay from "../assets/gp badge.png";
|
| 5 |
+
import appStore from "../assets/apple badge.png";
|
| 6 |
+
|
| 7 |
+
export default function HeroDownloadSection() {
|
| 8 |
+
return (
|
| 9 |
+
<section
|
| 10 |
+
style={{
|
| 11 |
+
marginTop: 20,
|
| 12 |
+
background: "linear-gradient(135deg, #FFFFFF 0%, #FBE9D8 25%, #FB8A8A 50%, #8A3B6F 75%, #83B9FF 100%)",
|
| 13 |
+
color: "white",
|
| 14 |
+
textAlign: "center",
|
| 15 |
+
padding: "130px 20px",
|
| 16 |
+
borderRadius: "20px",
|
| 17 |
+
boxShadow: "0 10px 30px rgba(0,0,0,0.1)",
|
| 18 |
+
fontFamily: "'Poppins', sans-serif",
|
| 19 |
+
}}
|
| 20 |
+
>
|
| 21 |
+
{/* Hero Title */}
|
| 22 |
+
<motion.h1
|
| 23 |
+
initial={{ opacity: 0, y: -50 }}
|
| 24 |
+
animate={{ opacity: 1, y: 0 }}
|
| 25 |
+
transition={{ duration: 0.8 }}
|
| 26 |
+
style={{
|
| 27 |
+
fontSize: "64px",
|
| 28 |
+
fontWeight: "900",
|
| 29 |
+
marginBottom: "15px",
|
| 30 |
+
lineHeight: 1.1,
|
| 31 |
+
textTransform: "uppercase",
|
| 32 |
+
letterSpacing: "2px",
|
| 33 |
+
userSelect: "none"
|
| 34 |
+
}}
|
| 35 |
+
>
|
| 36 |
+
YOUR STYLE, <br />
|
| 37 |
+
VISUALIZED
|
| 38 |
+
</motion.h1>
|
| 39 |
+
|
| 40 |
+
{/* Sub-Headline */}
|
| 41 |
+
<motion.p
|
| 42 |
+
initial={{ opacity: 0 }}
|
| 43 |
+
animate={{ opacity: 1 }}
|
| 44 |
+
transition={{ delay: 0.4, duration: 0.8 }}
|
| 45 |
+
style={{
|
| 46 |
+
fontSize: "20px",
|
| 47 |
+
fontWeight: "400",
|
| 48 |
+
marginBottom: "40px",
|
| 49 |
+
maxWidth: "600px",
|
| 50 |
+
marginLeft: "auto",
|
| 51 |
+
marginRight: "auto",
|
| 52 |
+
userSelect: "none"
|
| 53 |
+
}}
|
| 54 |
+
>
|
| 55 |
+
Download sekarang dan wujudkan penampilan impianmu!
|
| 56 |
+
</motion.p>
|
| 57 |
+
|
| 58 |
+
{/* Download Badges */}
|
| 59 |
+
<motion.div
|
| 60 |
+
initial={{ opacity: 0, y: 20 }}
|
| 61 |
+
animate={{ opacity: 1, y: 0 }}
|
| 62 |
+
transition={{ delay: 0.8, duration: 0.6 }}
|
| 63 |
+
style={{
|
| 64 |
+
display: "flex",
|
| 65 |
+
justifyContent: "center",
|
| 66 |
+
gap: "20px",
|
| 67 |
+
flexWrap: "wrap",
|
| 68 |
+
userSelect: "none"
|
| 69 |
+
}}
|
| 70 |
+
>
|
| 71 |
+
<a
|
| 72 |
+
href="https://play.google.com/store/apps/details?id=YOUR_APP_ID"
|
| 73 |
+
target="_blank"
|
| 74 |
+
rel="noreferrer"
|
| 75 |
+
>
|
| 76 |
+
<motion.img
|
| 77 |
+
src={googlePlay}
|
| 78 |
+
alt="Google Play"
|
| 79 |
+
style={{ height: 60 }}
|
| 80 |
+
whileHover={{ scale: 1.05 }}
|
| 81 |
+
transition={{ duration: 0.3 }}
|
| 82 |
+
/>
|
| 83 |
+
</a>
|
| 84 |
+
|
| 85 |
+
<a
|
| 86 |
+
href="https://apps.apple.com/app/idYOUR_APP_ID"
|
| 87 |
+
target="_blank"
|
| 88 |
+
rel="noreferrer"
|
| 89 |
+
>
|
| 90 |
+
<motion.img
|
| 91 |
+
src={appStore}
|
| 92 |
+
alt="App Store"
|
| 93 |
+
style={{ height: 60 }}
|
| 94 |
+
whileHover={{ scale: 1.05 }}
|
| 95 |
+
transition={{ duration: 0.3 }}
|
| 96 |
+
/>
|
| 97 |
+
</a>
|
| 98 |
+
</motion.div>
|
| 99 |
+
</section>
|
| 100 |
+
);
|
| 101 |
+
}
|
src/components/ShortCopywriting.jsx
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
import { motion } from "framer-motion";
|
| 3 |
+
|
| 4 |
+
import mock1 from "../assets/Mockup1.png";
|
| 5 |
+
import mock2 from "../assets/Mockup2.png";
|
| 6 |
+
import mock3 from "../assets/Mockup3.png";
|
| 7 |
+
import mock4 from "../assets/Mockup4.png";
|
| 8 |
+
|
| 9 |
+
export default function ShortCopywriting() {
|
| 10 |
+
const sections = [
|
| 11 |
+
{
|
| 12 |
+
title: "Explore your style effortlessly",
|
| 13 |
+
text: "Try every outfit with real-time AR without visiting stores.",
|
| 14 |
+
img: mock1,
|
| 15 |
+
bg: "#FB4868",
|
| 16 |
+
textColor: "#FFF",
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
title: "Discover the best fashion from top marketplaces",
|
| 20 |
+
text: "Browse top marketplace products quickly and easily.",
|
| 21 |
+
img: mock2,
|
| 22 |
+
bg: "#46072C",
|
| 23 |
+
textColor: "#FFF",
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
title: "Adjust your measurements for accurate visualization",
|
| 27 |
+
text: "Get accurate AR visualization with personalized sizes.",
|
| 28 |
+
img: mock3,
|
| 29 |
+
bg: "#FBE9D8",
|
| 30 |
+
textColor: "#FFF",
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
title: "Revisit your favorite tried outfits",
|
| 34 |
+
text: "Easily access your previously tried clothing anytime.",
|
| 35 |
+
img: mock4,
|
| 36 |
+
bg: "#83B9FF",
|
| 37 |
+
textColor: "#FFF",
|
| 38 |
+
},
|
| 39 |
+
];
|
| 40 |
+
|
| 41 |
+
return (
|
| 42 |
+
<section style={{ padding: "50px 20px", fontFamily: "'Poppins', sans-serif" }}>
|
| 43 |
+
{sections.map((sec, index) => {
|
| 44 |
+
const isLeft = index % 2 === 0;
|
| 45 |
+
|
| 46 |
+
return (
|
| 47 |
+
<motion.div
|
| 48 |
+
key={index}
|
| 49 |
+
style={{
|
| 50 |
+
display: "flex",
|
| 51 |
+
flexDirection: isLeft ? "row" : "row-reverse",
|
| 52 |
+
alignItems: "center",
|
| 53 |
+
justifyContent: "center",
|
| 54 |
+
padding: "40px 20px",
|
| 55 |
+
backgroundColor: sec.bg,
|
| 56 |
+
borderRadius: 15,
|
| 57 |
+
marginBottom: 30,
|
| 58 |
+
boxShadow: "0 8px 20px rgba(0,0,0,0.06)",
|
| 59 |
+
gap: 30,
|
| 60 |
+
userSelect: "none"
|
| 61 |
+
}}
|
| 62 |
+
// Animasi Fade In/Out saat scroll
|
| 63 |
+
initial={{ opacity: 0, y: 50 }}
|
| 64 |
+
whileInView={{ opacity: 1, y: 0 }}
|
| 65 |
+
viewport={{ once: false, amount: 0.3 }}
|
| 66 |
+
transition={{ duration: 0.7, ease: "easeOut" }}
|
| 67 |
+
>
|
| 68 |
+
{/* Konten (Gambar dan Teks) */}
|
| 69 |
+
<div
|
| 70 |
+
style={{
|
| 71 |
+
display: "flex",
|
| 72 |
+
flexDirection: isLeft ? "row" : "row-reverse",
|
| 73 |
+
alignItems: "center",
|
| 74 |
+
gap: 30,
|
| 75 |
+
maxWidth: 900,
|
| 76 |
+
width: "100%",
|
| 77 |
+
// Responsiveness sederhana
|
| 78 |
+
"@media (max-width: 768px)": {
|
| 79 |
+
flexDirection: "column",
|
| 80 |
+
textAlign: "center",
|
| 81 |
+
},
|
| 82 |
+
}}
|
| 83 |
+
>
|
| 84 |
+
{/* Gambar (Ukuran tetap 280px) */}
|
| 85 |
+
<motion.div
|
| 86 |
+
style={{ flex: "0 0 auto", maxWidth: 280, width: "100%", textAlign: "center" }}
|
| 87 |
+
initial={{ scale: 0.9, opacity: 0 }}
|
| 88 |
+
whileInView={{ scale: 1, opacity: 1 }}
|
| 89 |
+
viewport={{ once: false, amount: 0.5 }}
|
| 90 |
+
transition={{ delay: 0.2, duration: 0.6, ease: "easeOut" }}
|
| 91 |
+
>
|
| 92 |
+
<img
|
| 93 |
+
src={sec.img}
|
| 94 |
+
alt={sec.title}
|
| 95 |
+
style={{
|
| 96 |
+
width: "100%",
|
| 97 |
+
height: "auto",
|
| 98 |
+
|
| 99 |
+
}}
|
| 100 |
+
/>
|
| 101 |
+
</motion.div>
|
| 102 |
+
|
| 103 |
+
{/* Teks */}
|
| 104 |
+
<motion.div
|
| 105 |
+
style={{
|
| 106 |
+
flex: 1,
|
| 107 |
+
minWidth: 200,
|
| 108 |
+
textAlign: isLeft ? "left" : "right",
|
| 109 |
+
color: sec.textColor,
|
| 110 |
+
"@media (max-width: 768px)": {
|
| 111 |
+
textAlign: "center",
|
| 112 |
+
},
|
| 113 |
+
}}
|
| 114 |
+
initial={{ x: isLeft ? 30 : -30, opacity: 0 }}
|
| 115 |
+
whileInView={{ x: 0, opacity: 1 }}
|
| 116 |
+
viewport={{ once: false, amount: 0.5 }}
|
| 117 |
+
transition={{ delay: 0.3, duration: 0.6, ease: "easeOut" }}
|
| 118 |
+
>
|
| 119 |
+
<h2
|
| 120 |
+
style={{
|
| 121 |
+
fontSize: 70, // Diperbesar dari 32px
|
| 122 |
+
fontWeight: "700",
|
| 123 |
+
marginBottom: 10,
|
| 124 |
+
lineHeight: 1.2,
|
| 125 |
+
textTransform: "capitalize",
|
| 126 |
+
letterSpacing: "0.2px",
|
| 127 |
+
}}
|
| 128 |
+
>
|
| 129 |
+
{sec.title}
|
| 130 |
+
</h2>
|
| 131 |
+
<p style={{ opacity: 0.9, fontSize: 24, lineHeight: 1.5 }}>{sec.text}</p>
|
| 132 |
+
{/* Diperbesar dari 16px */}
|
| 133 |
+
</motion.div>
|
| 134 |
+
</div>
|
| 135 |
+
</motion.div>
|
| 136 |
+
);
|
| 137 |
+
})}
|
| 138 |
+
</section>
|
| 139 |
+
);
|
| 140 |
+
}
|
src/index.jsx
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
import ReactDOM from "react-dom/client";
|
| 3 |
+
import App from "./App";
|
| 4 |
+
|
| 5 |
+
const root = ReactDOM.createRoot(document.getElementById("root"));
|
| 6 |
+
root.render(
|
| 7 |
+
<React.StrictMode>
|
| 8 |
+
<App />
|
| 9 |
+
</React.StrictMode>
|
| 10 |
+
);
|
src/pages/LandingPage.jsx
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from "react";
|
| 2 |
+
import HeroDownloadSection from "../components/HeroDownloadSection";
|
| 3 |
+
import ShortCopywriting from "../components/ShortCopywriting";
|
| 4 |
+
import Header from "../components/Header";
|
| 5 |
+
|
| 6 |
+
export default function LandingPage() {
|
| 7 |
+
return (
|
| 8 |
+
<div>
|
| 9 |
+
<Header />
|
| 10 |
+
<HeroDownloadSection />
|
| 11 |
+
<ShortCopywriting />
|
| 12 |
+
</div>
|
| 13 |
+
);
|
| 14 |
+
}
|