initiate template layout
This commit is contained in:
parent
7f367fa670
commit
2f2e4b2925
|
@ -2,9 +2,9 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" type="image/svg+xml+png" href="/assets/images/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
<title>Kedai Susu Tuli - SIBI</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
@ -8,11 +8,16 @@
|
|||
"name": "ksuli-sibi",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"zustand": "^4.5.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/node": "^22.4.2",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
|
@ -1234,17 +1239,26 @@
|
|||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.2.tgz",
|
||||
"integrity": "sha512-nAvM3Ey230/XzxtyDcJ+VjvlzpzoHwLsF7JaDRfoI0ytO0mVheerNmM45CtA0yOILXwXXxOrcUWH3wltX+7PSw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
|
||||
"integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz",
|
||||
"integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^3.0.2"
|
||||
|
@ -1803,6 +1817,14 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
|
@ -1879,7 +1901,7 @@
|
|||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"dev": true
|
||||
"devOptional": true
|
||||
},
|
||||
"node_modules/culori": {
|
||||
"version": "3.3.0",
|
||||
|
@ -3349,6 +3371,14 @@
|
|||
"react": "^18.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz",
|
||||
"integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||
|
@ -3689,6 +3719,15 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz",
|
||||
"integrity": "sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.10",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.10.tgz",
|
||||
|
@ -3840,6 +3879,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
|
||||
|
@ -3879,6 +3924,14 @@
|
|||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
|
||||
"integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
@ -4124,6 +4177,33 @@
|
|||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.5.tgz",
|
||||
"integrity": "sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==",
|
||||
"dependencies": {
|
||||
"use-sync-external-store": "1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": ">=16.8",
|
||||
"immer": ">=9.0.6",
|
||||
"react": ">=16.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"immer": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,16 @@
|
|||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1"
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.3.0",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"zustand": "^4.5.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.9.0",
|
||||
"@types/node": "^22.4.2",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
|
@ -1,6 +1,11 @@
|
|||
import LayoutPage from "./components/templates/LayoutPage";
|
||||
|
||||
const App = () => {
|
||||
return <div>Hello World</div>;
|
||||
return (
|
||||
<LayoutPage>
|
||||
<p>Hello World</p>
|
||||
</LayoutPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { cn } from "@/lib/utils";
|
||||
|
||||
type NavLinkProps = {
|
||||
href: string;
|
||||
name: string;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
const NavLink = ({ href, name, isActive }: NavLinkProps) => {
|
||||
return (
|
||||
<a href={href}>
|
||||
<li
|
||||
className={cn(
|
||||
"btn bg-transparent border-none",
|
||||
isActive ? "text-primary" : ""
|
||||
)}
|
||||
>
|
||||
{name}
|
||||
</li>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavLink;
|
|
@ -0,0 +1,14 @@
|
|||
const FooterPage = () => {
|
||||
return (
|
||||
<footer>
|
||||
<div className="flex flex-row justify-center py-2 bg-white">
|
||||
<p className="text-xs text-center">
|
||||
© 2024 <span className="font-medium">Kedai Susu Tuli</span> &
|
||||
Developed by <span className="font-medium">Mphstar</span> ❤️
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default FooterPage;
|
|
@ -0,0 +1,51 @@
|
|||
import useNavbarStore from "@/stores/NavbarStore";
|
||||
import { cn } from "@lib/utils";
|
||||
import { IoClose } from "react-icons/io5";
|
||||
import { RxHamburgerMenu } from "react-icons/rx";
|
||||
import NavLink from "../molecules/NavLink";
|
||||
|
||||
const HeaderPage = () => {
|
||||
const navStore = useNavbarStore();
|
||||
return (
|
||||
<div className="bg-white drop-shadow w-full h-fit sticky top-0">
|
||||
<header className="flex flex-row items-center gap-2 justify-between px-4 py-3 container max-w-[1200px]">
|
||||
<div className="flex gap-1 items-center">
|
||||
<img
|
||||
className="w-10"
|
||||
src="/assets/images/logo.png"
|
||||
alt="Logo Kedai Susu Tuli"
|
||||
/>
|
||||
<div className="form-control">
|
||||
<h1 className="font-semibold">K-SULI</h1>
|
||||
<p className="text-gray-600">Kedai Susu Tuli</p>
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
className={cn(
|
||||
"flex md:flex-row flex-col items-center justify-center fixed md:static min-h-svh md:min-h-0 w-full md:w-fit bg-white/50 md:bg-transparent md:backdrop-blur-none backdrop-blur-md z-[200] top-0 left-0",
|
||||
navStore.isOpen ? "translate-y-0" : "-translate-y-full",
|
||||
"duration-300 ease-in-out md:translate-y-0"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
onClick={() => navStore.toggle()}
|
||||
className="btn absolute top-4 right-4 md:hidden bg-transparent border-none"
|
||||
>
|
||||
<IoClose />
|
||||
</div>
|
||||
<NavLink href="/" name="Home" isActive={true} />
|
||||
<NavLink href="/" name="Kamus" isActive={false} />
|
||||
<NavLink href="/" name="Kuis" isActive={false} />
|
||||
</ul>
|
||||
<button
|
||||
onClick={() => navStore.toggle()}
|
||||
className="btn bg-transparent border-none md:hidden"
|
||||
>
|
||||
<RxHamburgerMenu />
|
||||
</button>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderPage;
|
|
@ -0,0 +1,17 @@
|
|||
import React from "react";
|
||||
import HeaderPage from "../organisms/HeaderPage";
|
||||
import FooterPage from "../organisms/FooterPage";
|
||||
|
||||
const LayoutPage = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<div className="flex flex-col min-h-svh bg-ground">
|
||||
<HeaderPage />
|
||||
<main className="flex flex-col flex-1 container max-w-[1200px]">
|
||||
{children}
|
||||
</main>
|
||||
<FooterPage />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LayoutPage;
|
|
@ -0,0 +1,6 @@
|
|||
import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { create } from "zustand";
|
||||
|
||||
type NavbarType = {
|
||||
isOpen: boolean;
|
||||
toggle: () => void;
|
||||
};
|
||||
|
||||
const useNavbarStore = create<NavbarType>((set) => ({
|
||||
isOpen: false,
|
||||
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
|
||||
}));
|
||||
|
||||
export default useNavbarStore;
|
|
@ -2,7 +2,32 @@
|
|||
export default {
|
||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
container: {
|
||||
center: true,
|
||||
padding: "1rem",
|
||||
},
|
||||
colors: {
|
||||
ground: "#FAF7EE",
|
||||
},
|
||||
},
|
||||
},
|
||||
daisyui: {
|
||||
themes: [
|
||||
{
|
||||
mytheme: {
|
||||
primary: "#fbbf24",
|
||||
secondary: "#00b44a",
|
||||
accent: "#0099db",
|
||||
neutral: "#080f0e",
|
||||
"base-100": "#f3f4f6",
|
||||
info: "#00abf0",
|
||||
success: "#00e5ab",
|
||||
warning: "#fb923c",
|
||||
error: "#e11d48",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [require("daisyui")],
|
||||
};
|
||||
|
|
|
@ -18,7 +18,15 @@
|
|||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
/* Aliases */
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@components/*": ["src/components/*"],
|
||||
"@lib/*": ["src/lib/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import path from "path";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
"@components": path.resolve(__dirname, "./src/components"),
|
||||
"@lib": path.resolve(__dirname, "./src/lib"),
|
||||
},
|
||||
},
|
||||
plugins: [react()],
|
||||
})
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue