feat: enhance Header and SidebarBetter components with improved image handling and favicon support

This commit is contained in:
faisolavolut 2025-02-18 22:34:31 +07:00
parent 79b6081bb4
commit 4a6e49735a
5 changed files with 65 additions and 11 deletions

View File

@ -1,5 +1,6 @@
"use client";
import { siteurl } from "@/lib/utils/siteurl";
import React from "react";
interface HeaderProps {
@ -23,6 +24,7 @@ const Header: React.FC<HeaderProps> = ({
{author && <meta name="author" content={author} />}
<meta name="generator" content="Next.js" />
<title>{title}</title>
<link rel="icon" href={siteurl("/logo.ico")} type="image/x-icon" />
<link
rel="canonical"
href="https://www.creative-tim.com/product/soft-ui-dashboard-pro-flowbite"

View File

@ -1,6 +1,6 @@
"use client";
import React from "react";
import { Avatar, Sidebar } from "flowbite-react";
import { Sidebar } from "flowbite-react";
import { useEffect, useState } from "react";
import classNames from "classnames";
import { css } from "@emotion/css";
@ -24,6 +24,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "../ui/tooltip";
import ImageBetter from "../ui/Image";
interface TreeMenuItem {
title: string;
@ -683,7 +684,16 @@ const SidebarBetterTree: React.FC<TreeMenuProps> = ({
mini ? "py-4" : "p-4 bg-primary "
)}
>
<Avatar alt="" img={siteurl("/dog.jpg")} rounded size="sm" />
<ImageBetter
src={siteurl(
get_user("profile.avatar")
? get_user("profile.avatar")
: get_user("photo")
)}
alt="Profile"
className="h-8 w-8 rounded-full object-cover"
defaultSrc={siteurl("/404-img.jpg")}
/>
{!mini && (
<div className="flex flex-row items-center flex-grow font-bold text-white">
<div className=" px-2 h-full flex flex-col text-xs flex-grow">

28
components/ui/Image.tsx Normal file
View File

@ -0,0 +1,28 @@
import { useState } from "react";
interface ImageWithFallbackProps {
src: string;
alt?: string;
defaultSrc?: string;
className?: string;
}
const ImageBetter = ({
src,
alt,
defaultSrc = "/default-image.png",
className,
}: ImageWithFallbackProps) => {
const [imageSrc, setImageSrc] = useState(src);
return (
<img
src={imageSrc}
alt={alt}
className={className}
onError={() => setImageSrc(defaultSrc)}
/>
);
};
export default ImageBetter;

View File

@ -165,7 +165,7 @@ const DropdownMenuSeparator = React.forwardRef<
>(({ className, ...props }, ref) => (
<DropdownMenuPrimitive.Separator
ref={ref}
className={cn("-mx-1 my-1 h-px bg-gray-200", className)}
className={cn("-mx-1 h-px bg-gray-200", className)}
{...props}
/>
));

View File

@ -6,7 +6,6 @@ import { userRoleMe } from "../utils/getAccess";
export const userToken = async () => {
if (process.env.NEXT_PUBLIC_MODE === "dev") {
let user = localStorage.getItem("user");
if (user) {
try {
await userRoleMe();
@ -41,14 +40,29 @@ export const userToken = async () => {
await api.post(process.env.NEXT_PUBLIC_BASE_URL + "/api/cookies", {
token: jwt,
});
const user = await api.get(
`${process.env.NEXT_PUBLIC_API_PORTAL}/api/users/me`
);
const us = user.data.data;
if (us) {
localStorage.setItem("user", JSON.stringify(user.data.data));
let user = await apix({
port: "portal",
value: "data.data",
path: "/api/users/me",
});
if (user) {
let profile = null;
try {
const data = await apix({
port: "recruitment",
value: "data.data",
path: "/api/user-profiles/user",
});
profile = data;
delete profile["user"];
user = {
...user,
profile,
};
} catch (ex) {}
localStorage.setItem("user", JSON.stringify(user));
const w = window as any;
w.user = JSON.parse(user.data.data);
w.user = JSON.parse(user);
return true;
}
} catch (ex) {