ok
This commit is contained in:
54
package-lock.json
generated
54
package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
|
"react-router-dom": "^7.6.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
@@ -12866,6 +12867,53 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-router": {
|
||||||
|
"version": "7.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.1.tgz",
|
||||||
|
"integrity": "sha512-5cy/M8DHcG51/KUIka1nfZ2QeylS4PJRs6TT8I4PF5axVsI5JUxp0hC0NZ/AEEj8Vw7xsEoD7L/6FY+zoYaOGA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": "^1.0.1",
|
||||||
|
"set-cookie-parser": "^2.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router-dom": {
|
||||||
|
"version": "7.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.1.tgz",
|
||||||
|
"integrity": "sha512-NkgBCF3sVgCiAWIlSt89GR2PLaksMpoo3HDCorpRfnCEfdtRPLiuTf+CNXvqZMI5SJLZCLpVCvcZrTdtGW64xQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"react-router": "7.8.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=18",
|
||||||
|
"react-dom": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-router/node_modules/cookie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-scripts": {
|
"node_modules/react-scripts": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz",
|
||||||
@@ -13703,6 +13751,12 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/set-cookie-parser": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/set-function-length": {
|
"node_modules/set-function-length": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
|
"react-router-dom": "^7.6.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
|
|||||||
976
src/App.js
976
src/App.js
File diff suppressed because it is too large
Load Diff
409
src/LandingPage.js
Normal file
409
src/LandingPage.js
Normal file
@@ -0,0 +1,409 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import formatRupiah from './helpers/formatRupiah';
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
const { organizationId } = useParams();
|
||||||
|
const [organization, setOrganization] = useState([]);
|
||||||
|
const [tickets, setTickets] = useState([]);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
|
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||||
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const [modalTab, setModalTab] = useState("login"); // "login" or "register"
|
||||||
|
const [selectedTicket, setSelectedTicket] = useState(null);
|
||||||
|
const [formData, setFormData] = useState({});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!organizationId) {
|
||||||
|
setError("Parameter organization tidak ditemukan di URL.");
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
`https://auto.apps.kediritechnopark.com/webhook/mayagen/organization?organization=${organizationId}`
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) throw new Error("Gagal mengambil data tiket");
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setTickets(data[0].tickets);
|
||||||
|
setOrganization(data[0]);
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setError(err.message);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, [organizationId]);
|
||||||
|
|
||||||
|
// Dummy login handler
|
||||||
|
function handleLogin(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Kamu bisa validasi di sini
|
||||||
|
setIsLoggedIn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy register handler
|
||||||
|
function handleRegister(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Kamu bisa validasi dan buat user di sini
|
||||||
|
setIsLoggedIn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Form tiket submit
|
||||||
|
function handleSubmitTicket(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
alert(`Form tiket untuk ${selectedTicket.nama_tiket} submitted:\n` + JSON.stringify(formData, null, 2));
|
||||||
|
setShowModal(false);
|
||||||
|
setSelectedTicket(null);
|
||||||
|
setFormData({});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle klik beli tiket
|
||||||
|
function handleBuyClick(ticket) {
|
||||||
|
if (!isLoggedIn) {
|
||||||
|
setModalTab("login");
|
||||||
|
setShowModal(true);
|
||||||
|
setSelectedTicket(ticket);
|
||||||
|
} else {
|
||||||
|
setSelectedTicket(ticket);
|
||||||
|
setShowModal(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle form input change untuk tiket form
|
||||||
|
function handleFormChange(e) {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setFormData((prev) => ({ ...prev, [name]: value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) return <div>Loading...</div>;
|
||||||
|
if (error) return <div>Error: {error}</div>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-brand-dark text-gray-300 font-sans antialiased min-h-screen relative">
|
||||||
|
<main>
|
||||||
|
{/* Hero Section */}
|
||||||
|
<section className="relative h-[70vh] flex items-center justify-center text-center text-white overflow-hidden">
|
||||||
|
<div
|
||||||
|
className="absolute inset-0 bg-cover bg-center z-0"
|
||||||
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
"url('https://images.unsplash.com/photo-1524368535928-5b5e00ddc76b?q=80&w=2070&auto=format&fit=crop')",
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div className="absolute inset-0 bg-black/70 z-10"></div>
|
||||||
|
<div className="relative z-20 container mx-auto px-6">
|
||||||
|
<h1 className="text-4xl md:text-6xl font-extrabold leading-tight">
|
||||||
|
{organization.nama_organization}
|
||||||
|
</h1>
|
||||||
|
<p className="mt-4 max-w-2xl mx-auto text-lg text-gray-200">
|
||||||
|
{organization.deskripsi}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Acara Section */}
|
||||||
|
<section id="acara" className="py-20">
|
||||||
|
<div className="container mx-auto px-6">
|
||||||
|
<div className="text-center mb-12">
|
||||||
|
<h2 className="text-3xl md:text-4xl font-bold text-white">
|
||||||
|
Acara Mendatang
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
|
{tickets.map((ticket, i) => {
|
||||||
|
const isSoldOut = ticket.sold_out || false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={ticket.tiket_id || i}
|
||||||
|
className={`bg-brand-card rounded-lg overflow-hidden border border-brand-subtle flex flex-col ${isSoldOut ? "relative" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{isSoldOut && (
|
||||||
|
<div className="absolute inset-0 bg-black/60 flex items-center justify-center z-10">
|
||||||
|
<span className="text-white text-2xl font-bold border-2 border-white px-6 py-2 rotate-[-15deg]">
|
||||||
|
TIKET HABIS
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
ticket.poster ||
|
||||||
|
`https://placehold.co/600x400/161B22/FFFFFF?text=${encodeURIComponent(
|
||||||
|
ticket.nama_tiket.replace(/\s/g, "+")
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
alt="Poster Acara"
|
||||||
|
className={`w-full h-48 object-cover ${isSoldOut ? "filter grayscale" : ""
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
<div className="p-6 flex flex-col flex-grow">
|
||||||
|
<h3 className="text-xl font-bold text-white">
|
||||||
|
{ticket.nama_tiket}
|
||||||
|
</h3>
|
||||||
|
<div className="flex items-center text-sm text-gray-400 mt-2 space-x-4">
|
||||||
|
<span>📅 {ticket.tanggal || "Tanggal belum tersedia"}</span>
|
||||||
|
<span>📍 {ticket.lokasi || "Lokasi belum tersedia"}</span>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
className={`mt-4 text-lg font-semibold ${isSoldOut ? "text-gray-500" : "text-white"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{ticket.price === "0.00" ? "Gratis" : formatRupiah(ticket.price)}
|
||||||
|
</p>
|
||||||
|
<div className="mt-auto pt-4">
|
||||||
|
{isSoldOut ? (
|
||||||
|
<button
|
||||||
|
disabled
|
||||||
|
className="block w-full text-center bg-brand-subtle text-gray-500 font-semibold py-2.5 px-5 rounded-lg cursor-not-allowed"
|
||||||
|
>
|
||||||
|
Tiket Habis
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className="block w-full text-center bg-brand-accent hover:bg-brand-accent-hover text-white font-semibold py-2.5 px-5 rounded-lg transition-colors"
|
||||||
|
onClick={() => handleBuyClick(ticket)}
|
||||||
|
>
|
||||||
|
{ticket.price == 0 ? "Ambil Tiket" : `Beli Tiket`}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{organization.about &&
|
||||||
|
<section id="tentang" className="py-20 bg-brand-card">
|
||||||
|
<div className="container mx-auto px-6 grid lg:grid-cols-2 gap-12 items-center">
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
src="https://images.unsplash.com/photo-1523580494863-6f3031224c94?q=80&w=2070&auto=format&fit=crop"
|
||||||
|
className="rounded-lg"
|
||||||
|
alt="Tim SoundVibes Production"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2 className="text-3xl font-bold text-white">
|
||||||
|
Tentang {organization.nama_organization}
|
||||||
|
</h2>
|
||||||
|
<p className="mt-4 text-gray-400">
|
||||||
|
Didirikan pada tahun 2020, SoundVibes Production adalah promotor musik
|
||||||
|
yang berdedikasi untuk menciptakan acara live yang tak terlupakan.
|
||||||
|
Misi kami adalah menghubungkan penggemar dengan artis favorit mereka
|
||||||
|
melalui produksi acara yang berkualitas tinggi, aman, dan nyaman.
|
||||||
|
</p>
|
||||||
|
<p className="mt-4 text-gray-400">
|
||||||
|
Kami percaya bahwa musik memiliki kekuatan untuk menyatukan, dan
|
||||||
|
kami bangga menjadi jembatan antara panggung dan penonton.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
{/* Footer */}
|
||||||
|
<footer
|
||||||
|
id="kontak"
|
||||||
|
className="bg-brand-dark border-t border-brand-subtle"
|
||||||
|
>
|
||||||
|
<div className="container mx-auto px-6 py-8 text-center text-gray-400">
|
||||||
|
<h3 className="text-2xl font-bold text-white">
|
||||||
|
{organization.nama_organization}
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2">Ikuti kami untuk update acara terbaru!</p>
|
||||||
|
<div className="flex justify-center space-x-6 mt-4">
|
||||||
|
<a href="#" className="hover:text-white">
|
||||||
|
Instagram
|
||||||
|
</a>
|
||||||
|
<a href="#" className="hover:text-white">
|
||||||
|
Twitter
|
||||||
|
</a>
|
||||||
|
<a href="#" className="hover:text-white">
|
||||||
|
Facebook
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p className="mt-8 text-sm text-gray-500">
|
||||||
|
Data dalam situs ini mungkin dilindungi hak cipta oleh {organization.nama_organization}.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
{/* Modal */}
|
||||||
|
{showModal && (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-70 flex justify-center items-center z-50">
|
||||||
|
<div className="bg-brand-card rounded-lg max-w-md w-full p-6 relative">
|
||||||
|
<button
|
||||||
|
className="absolute top-3 right-3 text-gray-400 hover:text-white"
|
||||||
|
onClick={() => {
|
||||||
|
setShowModal(false);
|
||||||
|
setSelectedTicket(null);
|
||||||
|
setFormData({});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
✕
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{!isLoggedIn && (
|
||||||
|
<>
|
||||||
|
{/* Tabs */}
|
||||||
|
<div className="flex mb-4 border-b border-gray-600">
|
||||||
|
<button
|
||||||
|
className={`flex-1 py-2 ${modalTab === "login"
|
||||||
|
? "border-b-2 border-brand-accent font-bold"
|
||||||
|
: "text-gray-400"
|
||||||
|
}`}
|
||||||
|
onClick={() => setModalTab("login")}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`flex-1 py-2 ${modalTab === "register"
|
||||||
|
? "border-b-2 border-brand-accent font-bold"
|
||||||
|
: "text-gray-400"
|
||||||
|
}`}
|
||||||
|
onClick={() => setModalTab("register")}
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Login Form */}
|
||||||
|
{modalTab === "login" && (
|
||||||
|
<form onSubmit={handleLogin} className="space-y-4">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Email"
|
||||||
|
required
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
placeholder="Password"
|
||||||
|
required
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full bg-brand-accent py-2 rounded hover:bg-brand-accent-hover transition-colors"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Register Form */}
|
||||||
|
{modalTab === "register" && (
|
||||||
|
<form onSubmit={handleRegister} className="space-y-4">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="Nama Lengkap"
|
||||||
|
required
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Email"
|
||||||
|
required
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
placeholder="Password"
|
||||||
|
required
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full bg-brand-accent py-2 rounded hover:bg-brand-accent-hover transition-colors"
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Jika sudah login, tampilkan form tiket */}
|
||||||
|
{isLoggedIn && selectedTicket && (
|
||||||
|
<form onSubmit={handleSubmitTicket} className="space-y-4">
|
||||||
|
<h2 className="text-xl font-bold mb-4 text-white">
|
||||||
|
Formulir {selectedTicket.nama_tiket}
|
||||||
|
</h2>
|
||||||
|
{Object.entries(selectedTicket.form).map(([key, type]) => {
|
||||||
|
if (type === "text") {
|
||||||
|
return (
|
||||||
|
<div key={key}>
|
||||||
|
<label className="block mb-1 text-gray-300 capitalize" htmlFor={key}>
|
||||||
|
{key.replace(/_/g, " ")}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id={key}
|
||||||
|
name={key}
|
||||||
|
required
|
||||||
|
value={formData[key] || ""}
|
||||||
|
onChange={handleFormChange}
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (type === "selection") {
|
||||||
|
// Contoh opsi metode pembayaran (bisa disesuaikan)
|
||||||
|
const options = [
|
||||||
|
"Transfer Bank",
|
||||||
|
"Kartu Kredit",
|
||||||
|
"Cash",
|
||||||
|
"E-Wallet",
|
||||||
|
];
|
||||||
|
return (
|
||||||
|
<div key={key}>
|
||||||
|
<label className="block mb-1 text-gray-300 capitalize" htmlFor={key}>
|
||||||
|
{key.replace(/_/g, " ")}
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id={key}
|
||||||
|
name={key}
|
||||||
|
required
|
||||||
|
value={formData[key] || ""}
|
||||||
|
onChange={handleFormChange}
|
||||||
|
className="w-full p-2 rounded bg-gray-800 text-white"
|
||||||
|
>
|
||||||
|
<option value="">Pilih {key.replace(/_/g, " ")}</option>
|
||||||
|
{options.map((opt) => (
|
||||||
|
<option key={opt} value={opt}>
|
||||||
|
{opt}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})}
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full bg-brand-accent py-2 rounded hover:bg-brand-accent-hover transition-colors"
|
||||||
|
>
|
||||||
|
{selectedTicket.price == 0 ? "Dapatkan Tiket" : `Bayar Rp ${selectedTicket.price}`}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
8
src/helpers/formatRupiah.js
Normal file
8
src/helpers/formatRupiah.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export default function formatRupiah(number) {
|
||||||
|
return new Intl.NumberFormat('id-ID', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'IDR',
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0
|
||||||
|
}).format(number);
|
||||||
|
}
|
||||||
623
src/index.css
623
src/index.css
@@ -1,614 +1,37 @@
|
|||||||
/* Direktif Tailwind */
|
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
/* Tambahan untuk font */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
|
||||||
|
|
||||||
|
/* Custom Theme Overrides */
|
||||||
|
:root {
|
||||||
|
--color-brand-dark: #0D1117;
|
||||||
|
--color-brand-card: #161B22;
|
||||||
|
--color-brand-accent: #10B981;
|
||||||
|
--color-brand-accent-hover: #059669;
|
||||||
|
--color-brand-subtle: #30363D;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: 'Manrope', sans-serif;
|
@apply bg-[var(--color-brand-dark)] text-gray-300 font-sans antialiased;
|
||||||
background-color: #f8fafc; /* Background utama, mirip dengan brand guide */
|
|
||||||
color: #282930; /* Teks gelap utama */
|
|
||||||
margin: 0;
|
|
||||||
overflow-x: hidden; /* Mencegah scroll horizontal */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom styles for sections and elements */
|
/* Font override for Inter */
|
||||||
.header-bg {
|
* {
|
||||||
background-color: #ffffff;
|
font-family: 'Inter', sans-serif;
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-section {
|
@keyframes marquee {
|
||||||
background-color: #ffffff;
|
0% {
|
||||||
/* padding: 4rem 2rem; */
|
transform: translateX(0%);
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
.stats-grid {
|
transform: translateX(-50%);
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, minmax(0, 1fr)); /* 1 kolom di layar kecil */
|
|
||||||
gap: 1.5rem;
|
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 640px) { /* sm breakpoint */
|
|
||||||
.stats-grid {
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr)); /* 2 kolom di layar sedang */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) { /* lg breakpoint */
|
|
||||||
.stats-grid {
|
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr)); /* 4 kolom di layar besar */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 1rem;
|
|
||||||
text-align: left;
|
|
||||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
||||||
transition: transform 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.dark-bg {
|
|
||||||
background-color: #282930; /* Menggunakan warna gelap dari brand guide */
|
|
||||||
color: #e2e8f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.light-green-bg {
|
|
||||||
background-color: #E5FFCC; /* Menggunakan warna hijau terang dari brand guide */
|
|
||||||
color: #142F32; /* Teks gelap di atas hijau terang */
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-section {
|
|
||||||
background-color: #282930; /* Menggunakan warna gelap dari brand guide */
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
color: #e2e8f0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, minmax(0, 1fr)); /* 1 kolom di layar kecil */
|
|
||||||
gap: 1.5rem;
|
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) { /* md breakpoint */
|
|
||||||
.bottom-grid {
|
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr)); /* 3 kolom di layar sedang */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-card {
|
|
||||||
background-color: #142F32; /* Menggunakan warna hijau gelap dari brand guide */
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 2rem;
|
|
||||||
text-align: left;
|
|
||||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2), 0 4px 6px -2px rgba(0, 0, 0, 0.1);
|
|
||||||
transition: transform 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-primary {
|
|
||||||
background-color: #142F32; /* Menggunakan warna hijau gelap dari brand guide */
|
|
||||||
color: white;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-primary:hover {
|
|
||||||
background-color: #0d1e20; /* Hijau gelap lebih gelap */
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-secondary {
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid #9ca3af; /* Gray border */
|
|
||||||
color: #4b5563; /* Dark gray text */
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-secondary:hover {
|
|
||||||
background-color: #f3f4f6; /* Light gray background */
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-sign-up {
|
|
||||||
background-color: #142F32; /* Menggunakan warna hijau gelap dari brand guide */
|
|
||||||
color: white;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-sign-up:hover {
|
|
||||||
background-color: #0d1e20; /* Hijau gelap lebih gelap */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive image for the first card */
|
|
||||||
.card-image {
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
border-radius: 0.75rem; /* Sudut membulat untuk gambar */
|
|
||||||
object-fit: cover; /* Memastikan gambar menutupi area */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles for Key Benefits Section */
|
|
||||||
.key-benefits-section {
|
|
||||||
background-color: #f8fafc;
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.key-benefits-section {
|
|
||||||
flex-direction: row;
|
|
||||||
text-align: left;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefits-content {
|
|
||||||
flex: 1;
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefits-image-card {
|
|
||||||
flex: 1;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 1.5rem;
|
|
||||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
||||||
margin-top: 2rem;
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.benefits-image-card {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefit-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.benefit-item i {
|
|
||||||
color: #22c55e; /* Hijau centang */
|
|
||||||
margin-right: 0.75rem;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles for Tailored Plans Section */
|
|
||||||
.tailored-plans-section {
|
|
||||||
background-color: #282930; /* Menggunakan warna gelap dari brand guide */
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
color: #e2e8f0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
margin-top: 3rem;
|
|
||||||
max-width: 900px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.pricing-grid {
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card {
|
|
||||||
background-color: #142F32; /* Menggunakan warna hijau gelap dari brand guide */
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 2.5rem;
|
|
||||||
text-align: left;
|
|
||||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2), 0 4px 6px -2px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card .price {
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 800;
|
|
||||||
color: #ffffff;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card .price-per-month {
|
|
||||||
color: #9ca3af;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card .feature-list {
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card .feature-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
color: #cbd5e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pricing-card .feature-item i {
|
|
||||||
color: #22c55e; /* Hijau centang */
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* New styles for Seamless Integrations Section */
|
|
||||||
.integrations-section {
|
|
||||||
background-color: #f8fafc;
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.integrations-section {
|
|
||||||
flex-direction: row;
|
|
||||||
text-align: left;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.integrations-content {
|
|
||||||
flex: 1;
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.integrations-visual {
|
|
||||||
flex: 1;
|
|
||||||
background-color: #E5FFCC; /* Menggunakan warna hijau terang dari brand guide */
|
|
||||||
border-radius: 1rem;
|
|
||||||
padding: 2rem;
|
|
||||||
margin-top: 2rem;
|
|
||||||
max-width: 500px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
.integrations-visual {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.integration-icon-grid {
|
.animate-marquee {
|
||||||
display: grid;
|
animation: marquee 40s linear infinite;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
gap: 1.5rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
justify-items: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.integration-icon {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
font-size: 1.5rem;
|
|
||||||
color: #4a5568;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* From Idea to Production Section */
|
|
||||||
.idea-to-production-section {
|
|
||||||
background-color: #282930; /* Menggunakan warna gelap dari brand guide */
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
color: #e2e8f0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer Section */
|
|
||||||
.footer-section {
|
|
||||||
background-color: #282930; /* Menggunakan warna gelap dari brand guide */
|
|
||||||
padding: 4rem 2rem;
|
|
||||||
color: #a0aec0; /* Teks abu-abu lebih terang */
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
||||||
gap: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
.footer-grid {
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
.footer-grid {
|
|
||||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-col h3 {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #ffffff;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-col ul li {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-col ul li a {
|
|
||||||
color: #a0aec0;
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-col ul li a:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-icons a {
|
|
||||||
color: #a0aec0;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
margin-right: 1rem;
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-icons a:hover {
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Modal Styles */
|
|
||||||
.modal {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 1000;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
transition: opacity 0.3s ease, visibility 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal.show {
|
|
||||||
opacity: 1;
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
background-color: #ffffff;
|
|
||||||
padding: 2.5rem;
|
|
||||||
border-radius: 1rem;
|
|
||||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
|
|
||||||
max-width: 450px;
|
|
||||||
width: 90%;
|
|
||||||
text-align: center;
|
|
||||||
position: relative;
|
|
||||||
transform: translateY(-20px);
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal.show .modal-content {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-button {
|
|
||||||
position: absolute;
|
|
||||||
top: 1rem;
|
|
||||||
right: 1rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #4b5563;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dashboard Styles */
|
|
||||||
.dashboard-container {
|
|
||||||
display: none; /* Hidden by default */
|
|
||||||
grid-template-columns: 250px 1fr; /* Sidebar fixed width, content fills */
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f8fafc;
|
|
||||||
color: #282930;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.dashboard-container {
|
|
||||||
grid-template-columns: 1fr; /* Stack on small screens */
|
|
||||||
}
|
|
||||||
.dashboard-sidebar {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-sidebar {
|
|
||||||
background-color: #142F32; /* Hijau gelap */
|
|
||||||
color: #E5FFCC;
|
|
||||||
padding: 2rem 1rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-sidebar-item {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.2s ease, color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-sidebar-item:hover {
|
|
||||||
background-color: rgba(229, 255, 204, 0.1); /* Hijau terang transparan */
|
|
||||||
color: #E5FFCC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-sidebar-item.active {
|
|
||||||
background-color: #E5FFCC;
|
|
||||||
color: #142F32;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-main-content {
|
|
||||||
padding: 2rem;
|
|
||||||
background-color: #f8fafc;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: calc(100vh - 4rem); /* Adjust for padding */
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 1rem;
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-messages {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: 1.5rem;
|
|
||||||
overflow-y: auto;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-message {
|
|
||||||
max-width: 80%;
|
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-message.user {
|
|
||||||
background-color: #E5FFCC;
|
|
||||||
align-self: flex-end;
|
|
||||||
color: #142F32;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-message.bot {
|
|
||||||
background-color: #f1f5f9;
|
|
||||||
align-self: flex-start;
|
|
||||||
color: #282930;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input-area {
|
|
||||||
display: flex;
|
|
||||||
padding: 1rem;
|
|
||||||
border-top: 1px solid #e2e8f0;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input-area input {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
border: 1px solid #cbd5e0;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
margin-right: 0.75rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input-area button {
|
|
||||||
background-color: #142F32;
|
|
||||||
color: white;
|
|
||||||
padding: 0.75rem 1.25rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
transition: background-color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-input-area button:hover {
|
|
||||||
background-color: #0d1e20;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-indicator {
|
|
||||||
display: none;
|
|
||||||
text-align: center;
|
|
||||||
padding: 1rem;
|
|
||||||
color: #777C90;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading-indicator.show {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.image-gen-preview {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
margin-top: 1.5rem;
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-section-content {
|
|
||||||
background-color: #ffffff;
|
|
||||||
padding: 2rem;
|
|
||||||
border-radius: 1rem;
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
|
|
||||||
min-height: calc(100vh - 8rem); /* Adjust for header/footer/padding */
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-section-content h2 {
|
|
||||||
font-size: 2.25rem;
|
|
||||||
font-weight: 800;
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
color: #282930;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-section-content p {
|
|
||||||
color: #4b5563;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-section-content ul {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-section-content ul li {
|
|
||||||
background-color: #f1f5f9;
|
|
||||||
padding: 1rem;
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
margin-bottom: 0.75rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,21 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
// tailwind.config.js
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
"./src/**/*.{js,jsx,ts,tsx}",
|
"./src/**/*.{js,jsx,ts,tsx}", // pastikan path sesuai struktur project kamu
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['Inter', 'sans-serif'],
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
'brand-dark': '#0D1117',
|
||||||
|
'brand-card': '#161B22',
|
||||||
|
'brand-accent': '#10B981',
|
||||||
|
'brand-accent-hover': '#059669',
|
||||||
|
'brand-subtle': '#30363D',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user