feat: tab navigation

This commit is contained in:
2025-05-27 21:26:29 +02:00
parent c5c55f72b1
commit e983719601
6 changed files with 186 additions and 99 deletions

View File

@ -0,0 +1,27 @@
import type { FC } from "react";
import { barItems } from "../tabs";
export interface ISidebarProps {
activeTab: string;
onChangeTab: (tab: string) => void;
}
const Sidebar: FC<ISidebarProps> = ({ activeTab, onChangeTab }) => {
return (
<div className="hidden sm:flex flex-col gap-2 items-stretch min-w-80 w-80 p-5 pt-18 min-h-screen select-none bg-white/65 dark:bg-black/65 shadow-lg shadow-gray-300 dark:shadow-gray-700">
{barItems.map((item) => (
<div
key={item.tab}
onClick={() => onChangeTab(item.tab)}
className={`dark:text-gray-200 transition-colors text-md cursor-pointer p-4 rounded-lg flex flex-row items-center gap-3${
item.tab === activeTab ? " bg-gray-200 dark:bg-gray-900" : ""
}`}
>
{item.icon} {item.title}
</div>
))}
</div>
);
};
export default Sidebar;

View File

@ -0,0 +1,25 @@
import { type FC } from "react";
const Home: FC = () => {
return (
<div className="flex flex-col items-center gap-2 p-7">
<div className="w-24 h-24 sm:w-36 sm:h-36 overflow-hidden rounded-full flex items-center justify-center bg-gray-300">
{/* <User size={64} /> */}
<img
className="w-full h-full"
src="http://192.168.178.69:9000/guard-storage/profile_eff00028-2d9e-458d-8944-677855edc147_1748099702417601900.jpg"
alt="profile pic"
/>
</div>
<h1 className="dark:text-gray-200 text-gray-800 text-2xl select-none">
Welcome, Amir Adal
</h1>
<p className="text-gray-600 dark:text-gray-500 select-none text-center text-sm/normal sm:text-lg">
Manage your info, private and security to make Home Guard work better
for you.
</p>
</div>
);
};
export default Home;

View File

@ -0,0 +1,66 @@
import { ChevronRight } from "lucide-react";
import { type FC } from "react";
const PersonalInfo: FC = () => {
return (
<>
<h1 className="dark:text-gray-200 text-gray-800 text-2xl">
Your profile info in Home services
</h1>
<p className="text-gray-500 text-sm mt-2 sm:text-lg">
Personal info and options to manage it. You can make some of this info,
like your contact details, visible to others so they can reach you
easily. You can also see a summary of your profiles.
</p>
<div className="border dark:border-gray-800 border-gray-300 p-4 rounded mt-4">
<h3 className="dark:text-gray-300 text-gray-800">Basic info</h3>
<p className="text-gray-500 text-sm mt-2 mb-4">
Some info may be visible to other services and tools using Home Guard.{" "}
<a href="#" className="text-blue-500">
Learn more
</a>
</p>
{/* Profile Picture */}
<div className="flex flex-row items-center justify-between px-2 p-4 border-b gap-2 dark:border-b-gray-800 border-b-gray-100">
<div className="flex flex-col items-start gap-2">
<p className="text-sm dark:text-gray-400 font-medium text-gray-600">
Profile picture
</p>
<p className="text-sm dark:text-gray-500 text-gray-600">
Add a profile picture to personalize your account
</p>
</div>
<div>
<div className="w-16 h-16 overflow-hidden rounded-full dark:bg-gray-400 bg-gray-700">
<img
className="w-full h-full"
src="http://192.168.178.69:9000/guard-storage/profile_eff00028-2d9e-458d-8944-677855edc147_1748099702417601900.jpg"
alt="profile pic"
/>
</div>
</div>
</div>
{/* Name */}
<div className="flex flex-row items-center justify-between px-2 p-4 border-b dark:border-b-gray-800 border-b-gray-100">
<div className="flex flex-col items-start gap-2">
<p className="text-sm dark:text-gray-400 font-medium text-gray-600">
Name
</p>
<p className="text dark:text-gray-200 text-gray-800">Amir Adal</p>
</div>
<div>
<div className="text-gray-500">
<ChevronRight size={26} />
</div>
</div>
</div>
</div>
</>
);
};
export default PersonalInfo;

View File

@ -0,0 +1,29 @@
import { type FC } from "react";
import { barItems } from "../tabs";
export interface ITopBarProps {
activeTab: string;
onChangeTab: (tab: string) => void;
}
const TopBar: FC<ITopBarProps> = ({ activeTab, onChangeTab }) => {
return (
<div className="sm:hidden flex w-full overflow-x-auto sm:overflow-x-visible max-w-full min-w-full sm:justify-center sm:space-x-4 no-scrollbar shadow-md shadow-gray-300 dark:shadow-gray-700 dark:bg-black/70 bg-white/70 pt-14">
{barItems.map((item) => (
<div
key={item.tab}
onClick={() => onChangeTab(item.tab)}
className={`flex-shrink-0 transition-all border-b-4 px-4 py-2 min-w-[120px] sm:min-w-0 sm:flex-1 flex items-center justify-center cursor-pointer select-none whitespace-nowrap text-sm font-medium ${
item.tab === activeTab
? " border-b-4 border-b-blue-500 text-blue-500"
: " border-b-transparent text-gray-500"
}`}
>
{item.title}
</div>
))}
</div>
);
};
export default TopBar;

View File

@ -0,0 +1,19 @@
import { Home, Settings2, User } from "lucide-react";
export const barItems = [
{
icon: <Home />,
title: "Home",
tab: "home",
},
{
icon: <User />,
title: "Personal Info",
tab: "personal-info",
},
{
icon: <Settings2 />,
title: "Data & Personalization",
tab: "data-personalization",
},
];