init commit

This commit is contained in:
2024-11-11 10:03:20 +07:00
parent d72887445e
commit bd3a3d42ce
53 changed files with 18089 additions and 182 deletions

19
src/components/Footer.jsx Normal file
View File

@@ -0,0 +1,19 @@
import React from 'react';
const Footer = () => {
return (
<footer className="py-4 bg-light mt-auto">
<div className="container-fluid px-4">
<div className="d-flex align-items-center justify-content-between small">
<div className="text-muted">Copyright &copy; Your Website 2023</div>
<div>
<a href="#">Privacy Policy</a> &middot;
<a href="#">Terms & Conditions</a>
</div>
</div>
</div>
</footer>
);
};
export default Footer;

16
src/components/Main.jsx Normal file
View File

@@ -0,0 +1,16 @@
import React from 'react';
const Main = () => {
return (
<main>
<div className="container-fluid px-4">
<h1 className="mt-4">Dashboard</h1>
<ol className="breadcrumb mb-4">
<li className="breadcrumb-item active">Dashboard</li>
</ol>
</div>
</main>
);
};
export default Main;

165
src/components/Navbar.jsx Normal file
View File

@@ -0,0 +1,165 @@
import React, { useState, useEffect } from 'react';
import { Logo } from '../assets/images';
import { Link } from 'react-router-dom';
const Navbar = () => {
const messageCount = 5; // Example count for messages
const notificationCount = 3; // Example count for notifications
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth < 600);
};
// Check the initial screen size
handleResize();
// Add event listener for window resize
window.addEventListener('resize', handleResize);
// Cleanup event listener on component unmount
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<nav className="sb-topnav navbar navbar-expand" style={{ backgroundColor: '#0542cc' }}>
<Link to="/getting-started">
<a className="navbar-brand ps-3 text-white d-flex align-items-center">
{/* Logo Image */}
<img
src={Logo}
alt="Logo"
style={{ width: '30px', height: '30px', marginRight: '10px' }} // Adjust size as needed
/>
Rekan Veri
</a>
</Link>
<button
className={`btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0 text-white ${isMobile ? 'ms-auto' : ''}`}
id="sidebarToggle"
href="#!"
>
<i className="fas fa-bars"></i>
</button>
{/* Show navigation and search only on larger screens */}
{!isMobile && (
<>
<div className="navbar-nav me-auto">
<a className="nav-link text-white" href="/">Home</a>
<a className="nav-link text-white" href="/">Contact</a>
</div>
<form className="d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0">
<div className="input-group">
<input
className="form-control"
type="text"
placeholder="Search for..."
aria-label="Search for..."
aria-describedby="btnNavbarSearch"
/>
<button className="btn btn-primary" id="btnNavbarSearch" type="button">
<i className="fas fa-search"></i>
</button>
</div>
</form>
<ul className="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
{/* Messages Dropdown with Count */}
<li className="nav-item dropdown me-3 position-relative">
<a
className="nav-link dropdown-toggle text-white"
id="messagesDropdown"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i className="fas fa-envelope fa-fw"></i>
{messageCount > 0 && (
<span className="badge bg-danger badge-circle custom-badge">
{messageCount}
</span>
)}
</a>
<ul className="dropdown-menu dropdown-menu-end" aria-labelledby="messagesDropdown">
<li><a className="dropdown-item" href="#!">New Message</a></li>
<li><a className="dropdown-item" href="#!">Inbox</a></li>
<li><a className="dropdown-item" href="#!">Sent Messages</a></li>
</ul>
</li>
{/* Notifications Dropdown with Count */}
<li className="nav-item dropdown me-3 position-relative">
<a
className="nav-link dropdown-toggle text-white"
id="notificationsDropdown"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i className="fas fa-bell fa-fw"></i>
{notificationCount > 0 && (
<span className="badge bg-danger badge-circle custom-badge">
<strong>{notificationCount}</strong>
</span>
)}
</a>
<ul className="dropdown-menu dropdown-menu-end" aria-labelledby="notificationsDropdown">
<li><a className="dropdown-item" href="#!">New Notification</a></li>
<li><a className="dropdown-item" href="#!">Alerts</a></li>
<li><a className="dropdown-item" href="#!">Updates</a></li>
</ul>
</li>
{/* Expand Dropdown */}
<li className="nav-item dropdown me-3">
<a
className="nav-link dropdown-toggle text-white"
id="expandDropdown"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i className="fas fa-expand fa-fw"></i>
</a>
<ul className="dropdown-menu dropdown-menu-end" aria-labelledby="expandDropdown">
<li><a className="dropdown-item" href="#!">Full Screen</a></li>
<li><a className="dropdown-item" href="#!">Windowed Mode</a></li>
</ul>
</li>
{/* Apps Dropdown */}
<li className="nav-item dropdown me-3">
<a
className="nav-link dropdown-toggle text-white"
id="appsDropdown"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i className="fas fa-th fa-fw"></i>
</a>
<ul className="dropdown-menu dropdown-menu-end" aria-labelledby="appsDropdown">
<li><a className="dropdown-item" href="#!">App 1</a></li>
<li><a className="dropdown-item" href="#!">App 2</a></li>
<li><a className="dropdown-item" href="#!">App 3</a></li>
</ul>
</li>
</ul>
</>
)}
</nav>
);
};
export default Navbar;

View File

@@ -0,0 +1,50 @@
import React from 'react';
import DeeperMenu from './DeeperMenu';
const DeepMenu = ({ name, link, target, subMenus, activeMenu, onMenuClick }) => {
return (
<>
{subMenus ? (
<a
className={`nav-link collapsed ${activeMenu === name ? 'active' : ''}`} // Menambahkan kelas 'active' pada DeepMenu
href="#"
data-bs-toggle="collapse"
data-bs-target={`#${target}`} // Menggunakan target untuk menghubungkan dengan collapse
aria-expanded="false"
aria-controls={target} // Memastikan ID yang sesuai digunakan untuk kontrol collapse
onClick={() => onMenuClick(name)} // Menangani klik pada DeepMenu
>
{name}
<div className="sb-sidenav-collapse-arrow">
<i className="fas fa-angle-down"></i>
</div>
</a>
) : (
<a
className={`nav-link ${activeMenu === name ? 'active' : ''}`} // Menambahkan kelas 'active' pada DeepMenu
href={link}
onClick={() => onMenuClick(name)} // Menangani klik pada DeepMenu
>
{name}
</a>
)}
{subMenus && (
<div className="collapse" id={target}>
<nav className="sb-sidenav-menu-nested nav">
{subMenus.map((deepSubMenu, index) => (
<DeeperMenu
key={index}
{...deepSubMenu}
activeMenu={activeMenu} // Menyediakan state activeMenu ke DeeperMenu
onMenuClick={onMenuClick} // Fungsi untuk menangani klik
/>
))}
</nav>
</div>
)}
</>
);
};
export default DeepMenu;

View File

@@ -0,0 +1,15 @@
import { Link } from 'react-router-dom';
const DeeperMenu = ({ name, link, target, activeMenu, onMenuClick }) => {
return (
<Link
className={`nav-link ${activeMenu === name ? 'active' : ''}`} // Menambahkan kelas 'active' pada DeeperMenu
to={link} // Menggunakan `to` dari `Link` untuk navigasi
onClick={() => onMenuClick(name)} // Menangani klik pada DeeperMenu
>
{name}
</Link>
);
};
export default DeeperMenu;

View File

@@ -0,0 +1,70 @@
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import SubMenu from './SubMenu';
import dataMenu from './dataMenu';
const Menu = ({ searchQuery }) => {
const [activeMenu, setActiveMenu] = useState(null);
const handleMenuClick = (name) => {
setActiveMenu(name); // Menyimpan menu yang aktif
};
const filteredMenu = dataMenu.map((menuSection) => {
const filteredItems = menuSection.items.filter((item) => {
const itemName = item.name.toLowerCase();
const matches = itemName.includes(searchQuery);
const subMatches = item.subMenus?.some((subMenu) =>
subMenu.name.toLowerCase().includes(searchQuery)
);
return matches || subMatches;
});
return {
...menuSection,
items: filteredItems,
};
}).filter(section => section.items.length > 0); // Filter out sections without items
return (
<div className="sb-sidenav-menu mb-2">
<div className="nav">
{filteredMenu.map((menuSection, index) => (
<React.Fragment key={index}>
{menuSection.items.map((item, idx) => (
// Jika item memiliki submenu, render SubMenu
item.subMenus ? (
<SubMenu
key={idx}
heading={item.name}
target={item.target}
iconClass={menuSection.iconClass}
subMenus={item.subMenus.filter(subMenu =>
subMenu.name.toLowerCase().includes(searchQuery)
)}
activeMenu={activeMenu}
onMenuClick={handleMenuClick}
/>
) : (
// Jika item tidak memiliki submenu, gunakan <Link> untuk navigasi
<Link
key={idx}
className={`nav-link ${activeMenu === item.name ? 'active' : ''}`} // Menambahkan kelas 'active' pada item yang dipilih
to={item.link}
onClick={() => handleMenuClick(item.name)} // Memperbarui state activeMenu saat item dipilih
>
<div className="sb-nav-link-icon">
{item.iconClass && <i className={item.iconClass}></i>}
</div>
{item.name}
</Link>
)
))}
</React.Fragment>
))}
</div>
</div>
);
};
export default Menu;

View File

@@ -0,0 +1,37 @@
// src/components/Profile.js
import React from 'react';
import { ProfileImage } from '../../assets/images';
const Profile = () => (
<div className="profile-section" style={styles.container}>
<img
src={ProfileImage}
alt="Profile"
className="profile-image"
style={styles.image}
/>
<span className="profile-name" style={styles.name}>Alexander Pierce</span>
</div>
);
export default Profile;
const styles = {
container: {
padding: '10px',
display: 'flex',
alignItems: 'center',
marginTop: '2vh'
},
image: {
width: '40px',
height: '40px',
borderRadius: '50%',
marginRight: '10px',
},
name: {
fontWeight: 'bold',
},
};

View File

@@ -0,0 +1,50 @@
// src/components/SearchBar.js
import React from 'react';
const SearchBar = ({ onSearch }) => (
<div className="search-bar" style={styles.container}>
<input
type="text"
className="search-input"
placeholder="Search"
onChange={(e) => onSearch(e.target.value)}
style={styles.input}
/>
<button className="search-button" style={styles.button}>
<i className="fa fa-search" style={styles.icon}></i>
</button>
</div>
);
export default SearchBar;
const styles = {
container: {
padding: '0.1rem',
display: 'flex',
alignItems: 'center',
margin: '0 0.5rem 0 0.6rem'
},
input: {
width: '100%',
padding: '6px',
borderRadius: '4px 0 0 4px',
border: '1px solid #ddd',
outline: 'none',
fontSize: '0.9em',
},
button: {
padding: '6px',
border: '1px solid #ddd',
borderLeft: 'none',
borderRadius: '0 4px 4px 0',
backgroundColor: '#fff',
cursor: 'pointer',
},
icon: {
color: '#555',
fontSize: '0.9em',
},
};

View File

@@ -0,0 +1,25 @@
import React, { useState } from 'react';
import Menu from './Menu';
import Profile from './Profile';
import SearchBar from './SearchBar';
const Sidebar = () => {
const [searchQuery, setSearchQuery] = useState('');
return (
<div id="layoutSidenav_nav">
<nav className="sb-sidenav accordion sb-sidenav-light" id="sidenavAccordion">
<Profile />
<SearchBar onSearch={(query) => setSearchQuery(query.toLowerCase())} />
<Menu searchQuery={searchQuery} />
<div className="sb-sidenav-footer">
<div className="small">Logged in as:</div>
Start Bootstrap
</div>
</nav>
</div>
);
};
export default Sidebar;

View File

@@ -0,0 +1,41 @@
import React from 'react';
import DeepMenu from './DeepMenu';
const SubMenu = ({ heading, target, iconClass, subMenus, activeMenu, onMenuClick }) => {
return (
<>
<div className="sb-sidenav-menu-heading">{heading}</div>
<a
className={`nav-link collapsed ${activeMenu === heading ? 'active' : ''}`} // Menggunakan kelas active
href="#"
data-bs-toggle="collapse"
data-bs-target={`#${target}`}
aria-expanded="false"
aria-controls={target}
onClick={() => onMenuClick(heading)} // Memperbarui activeMenu
>
<div className="sb-nav-link-icon">
<i className={iconClass}></i>
</div>
{heading}
<div className="sb-sidenav-collapse-arrow">
<i className="fas fa-angle-down"></i>
</div>
</a>
<div className="collapse" id={target} aria-labelledby="headingOne">
<nav className="sb-sidenav-menu-nested nav">
{subMenus.map((subMenu, index) => (
<DeepMenu
key={index}
{...subMenu}
activeMenu={activeMenu}
onMenuClick={onMenuClick}
/>
))}
</nav>
</div>
</>
);
};
export default SubMenu;

View File

@@ -0,0 +1,263 @@
// src/components/dataMenu.js
const dataMenu = [
{
items: [
{
name: 'Main Dashboard', // Changed the name
target: 'collapseHome',
subMenus: [
{
name: 'Getting Started',
link: '/getting-started'
},
{
name: 'Dashboard Overview', // Changed the name
link: '/dashboard'
},
{
name: 'Application Settings', // Changed the name
link: '/application'
},
],
},
],
iconClass: 'fas fa-tachometer-alt',
},
{
items: [
{
name: 'Biometric Systems', // Changed the name
target: 'collapseBiometric',
subMenus: [
{
name: 'Face Recognition System', // Changed the name
target: 'collapseFaceRecog',
subMenus: [
{ name: 'Verify Identity', link: '/face-verify'}, // Changed the name
{ name: 'Summary Report', link: '/face-summary'}, // Changed the name
{ name: 'Transaction Log', link: '/face-transaction'}, // Changed the name
],
},
{
name: 'KTP OCR', // Changed the name
target: 'collapseOcrKtp',
subMenus: [
{ name: 'Verify KTP', link: '/ktp-verify'}, // Changed the name
{ name: 'Manage Basic Auth', link: '/ktp-manage'},
{ name: 'Summary of KTPs', link: '/ktp-summary'}, // Changed the name
{ name: 'KTP Transaction History', link: '/ktp-transaction'}, // Changed the name
],
},
{
name: 'NPWP OCR', // Changed the name
target: 'collapseOcrNpwp',
subMenus: [
{ name: 'Verify NPWP', link: '/npwp-verify'}, // Changed the name
{ name: 'NPWP Summary', link: '/npwp-summary'}, // Changed the name
{ name: 'NPWP Transaction Log', link: '/npwp-transaction'}, // Changed the name
],
},
{
name: 'SIM OCR', // Changed the name
target: 'collapseOcrSim',
subMenus: [
{ name: 'Verify SIM', link: '/sim-verify'}, // Changed the name
{ name: 'SIM Summary', link: '/sim-summary'}, // Changed the name
{ name: 'SIM Transaction Log', link: '/sim-transaction'}, // Changed the name
],
},
{
name: 'Document OCR', // Changed the name
target: 'collapseOcrDocument',
subMenus: [
{ name: 'Verify Document', link: '/document-verify'}, // Changed the name
{ name: 'Document Summary', link: '/document-summary'}, // Changed the name
{ name: 'Document Transaction History', link: '/document-transaction'}, // Changed the name
],
},
],
},
],
iconClass: 'fas fa-user',
},
{
items: [
{
name: 'SMS Services', // Changed the name
target: 'collapseSms',
subMenus: [
{
name: 'SMS Verification', // Changed the name
link: '/sms-verify'
},
{
name: 'SMS OTP Management', // Changed the name
target: 'collapseSmsOtp',
subMenus: [
{ name: 'Settings', link: '/sms-otp-settings'},
{ name: 'Summary Report', link: '/sms-otp-summary'}, // Changed the name
{ name: 'Transaction Log', link: '/sms-otp-transaction'}, // Changed the name
{ name: 'Detail View', link: '/sms-otp-detail'}, // Changed the name
],
},
{
name: 'SMS Announcements', // Changed the name
target: 'collapseAnnouncement',
subMenus: [
{ name: 'Bulk Message', link: '/sms-announcement-bulk'}, // Changed the name
{ name: 'Announcement Summary', link: '/sms-announcement-summary'}, // Changed the name
{ name: 'Transaction Logs', link: '/sms-announcement-transaction'},
],
},
{
name: 'Blocked Numbers', // Changed the name
link: '/sms-block'
},
{
name: 'SMS Anomaly Report', // Changed the name
link: '/sms-anomaly'
},
],
},
],
iconClass: 'fas fa-phone',
},
{
items: [
{
name: 'WhatsApp Communication', // Changed the name
target: 'collapseWa',
subMenus: [
{
name: 'Verify WhatsApp Account', // Changed the name
link: '/wa-verify'
},
{
name: 'WhatsApp Management', // Changed the name
target: 'collapseWaManage',
subMenus: [
{ name: 'Register Business Account', link: '/wa-manage-register'}, // Changed the name
{ name: 'WhatsApp Profile Settings', link: '/wa-manage-profile'}, // Changed the name
{ name: 'Message Templates', link: '/wa-manage-template'}, // Changed the name
{ name: 'Integration Settings', link: '/wa-manage-integration'}, // Changed the name
],
},
{
name: 'WhatsApp Activity', // Changed the name
target: 'collapseActivity',
subMenus: [
{ name: 'Settings', link: '/wa-activity-settings'}, // Changed the name
{ name: 'Activity Summary', link: '/wa-activity-summary'}, // Changed the name
{ name: 'Transaction Logs', link: '/wa-activity-transaction'},
{ name: 'Bulk Sending', link: '/wa-activity-bulk'}, // Changed the name
],
},
{
name: 'WhatsApp Inbox', // Changed the name
link: '/wa-inbox'
},
{
name: 'Blocked WhatsApp Numbers', // Changed the name
link: '/wa-block'
},
],
},
],
iconClass: 'fab fa-whatsapp',
},
{
items: [
{
name: 'Identity Verification', // Changed the name
target: 'collapseIdentify',
subMenus: [
{
name: 'Electronic Certificate Verification', // Changed the name
target: 'collapseElectro',
subMenus: [
{ name: 'Verify Certificate', link: '/identify-electro-verify'}, // Changed the name
{ name: 'Transaction Logs', link: '/identify-electro-transaction'},
],
},
{
name: 'NPWP Verification', // Changed the name
target: 'collapseIdentifyNpwp',
subMenus: [
{ name: 'Transaction Logs', link: '/identify-npwp-transaction'}
],
},
{
name: 'Tax Number Verification', // Changed the name
target: 'collapseTax',
subMenus: [
{ name: 'Verify Tax Number', link: '/identify-tax-verify'}, // Changed the name
{ name: 'Transaction Logs', link: '/identify-tax-transaction'}
],
},
{
name: 'Income Verification', // Changed the name
target: 'collapseIncome',
subMenus: [
{ name: 'Verify Income', link: '/identify-income-verify'}, // Changed the name
{ name: 'Transaction Logs', link: '/identify-income-transaction'}
],
},
{
name: 'ID Verification', // Changed the name
target: 'collapseIdVerification',
subMenus: [
{ name: 'Verify ID', link: '/identify-id-verify'}, // Changed the name
{ name: 'Transaction Logs', link: '/identify-id-transaction'}
],
},
],
},
],
iconClass: 'fas fa-edit',
},
{
items: [
{
name: 'Watchlist Management', // Changed the name
target: 'collapseWatchlist',
subMenus: [
{
name: 'Watchlist Screening', // Changed the name
target: 'collapseScreening',
subMenus: [
{ name: 'Verify Watchlist', link: '/watchlist-screening-verify'}, // Changed the name
{ name: 'Admin Settings', link: '/watchlist-screening-admin'},
{ name: 'Search Watchlist', link: '/watchlist-screening-search'}, // Changed the name
{ name: 'Transaction Logs', link: '/watchlist-screening-transaction'},
{ name: 'Monitor Watchlist', link: '/watchlist-screening-monitor'},
],
},
],
},
],
iconClass: 'fas fa-calendar',
},
{
items: [
{
name: 'File Management', // Changed the name
target: 'collapseFiles',
subMenus: [
{
name: 'File Screening', // Changed the name
target: 'collapseScreening',
subMenus: [
{ name: 'Verify File', link: '/files-screening-verify'}, // Changed the name
{ name: 'Search Files', link: '/files-screening-search'}, // Changed the name
{ name: 'File Management Settings', link: '/files-screening-admin'},
],
},
],
},
],
iconClass: 'fas fa-cogs',
}
];
export default dataMenu;

11
src/components/index.js Normal file
View File

@@ -0,0 +1,11 @@
import Navbar from "./Navbar";
import Sidebar from "./Sidebar/Sidebar";
import Main from "./Main";
import Footer from "./Footer";
export {
Navbar,
Sidebar,
Main,
Footer
}