navbar UI improved
This commit is contained in:
parent
35a8d74943
commit
39abb09002
|
@ -1,27 +0,0 @@
|
||||||
import { ReactNode, useState } from "react";
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
src: string;
|
|
||||||
className: string;
|
|
||||||
children: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ImageWithFallback = ({ src, className, children, ...rest }: Props) => {
|
|
||||||
const [error, setError] = useState(false);
|
|
||||||
|
|
||||||
return error ? (
|
|
||||||
<>{children}</>
|
|
||||||
) : (
|
|
||||||
<img
|
|
||||||
alt=""
|
|
||||||
{...rest}
|
|
||||||
src={src}
|
|
||||||
className={className}
|
|
||||||
onError={() => {
|
|
||||||
setError(true);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ImageWithFallback;
|
|
|
@ -3,16 +3,15 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import {
|
import {
|
||||||
faClose,
|
faClose,
|
||||||
faPenToSquare,
|
faPenToSquare,
|
||||||
faUser,
|
|
||||||
faUserPlus,
|
faUserPlus,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import useCollectionStore from "@/store/collections";
|
import useCollectionStore from "@/store/collections";
|
||||||
import { CollectionIncludingMembers, Member } from "@/types/global";
|
import { CollectionIncludingMembers, Member } from "@/types/global";
|
||||||
import { useSession } from "next-auth/react";
|
import { useSession } from "next-auth/react";
|
||||||
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
import addMemberToCollection from "@/lib/client/addMemberToCollection";
|
||||||
import ImageWithFallback from "../../ImageWithFallback";
|
|
||||||
import Checkbox from "../../Checkbox";
|
import Checkbox from "../../Checkbox";
|
||||||
import SubmitButton from "@/components/SubmitButton";
|
import SubmitButton from "@/components/SubmitButton";
|
||||||
|
import ProfilePhoto from "@/components/ProfilePhoto";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
toggleCollectionModal: Function;
|
toggleCollectionModal: Function;
|
||||||
|
@ -186,15 +185,7 @@ export default function TeamManagement({
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<ImageWithFallback
|
<ProfilePhoto src={`/api/avatar/${e.userId}`} />
|
||||||
key={i}
|
|
||||||
src={`/api/avatar/${e.userId}`}
|
|
||||||
className="h-10 w-10 shadow rounded-full border-[3px] border-sky-100"
|
|
||||||
>
|
|
||||||
<div className="text-white bg-sky-500 h-10 w-10 shadow rounded-full border-[3px] border-sky-100 flex items-center justify-center">
|
|
||||||
<FontAwesomeIcon icon={faUser} className="w-5 h-5" />
|
|
||||||
</div>
|
|
||||||
</ImageWithFallback>
|
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-bold text-sky-500">
|
<p className="text-sm font-bold text-sky-500">
|
||||||
{e.user.name}
|
{e.user.name}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { useRouter } from "next/router";
|
||||||
import Search from "@/components/Search";
|
import Search from "@/components/Search";
|
||||||
import UserSettings from "./Modal/UserSettings";
|
import UserSettings from "./Modal/UserSettings";
|
||||||
import useAccountStore from "@/store/account";
|
import useAccountStore from "@/store/account";
|
||||||
|
import ProfilePhoto from "./ProfilePhoto";
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const { account } = useAccountStore();
|
const { account } = useAccountStore();
|
||||||
|
@ -71,27 +72,17 @@ export default function () {
|
||||||
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div
|
<div
|
||||||
className="flex gap-1 group items-center w-fit bg-white cursor-pointer"
|
className="flex gap-1 group sm:hover:bg-slate-200 sm:hover:p-1 duration-100 h-10 rounded-full items-center w-fit bg-white cursor-pointer"
|
||||||
onClick={() => setProfileDropdown(!profileDropdown)}
|
onClick={() => setProfileDropdown(!profileDropdown)}
|
||||||
id="profile-dropdown"
|
id="profile-dropdown"
|
||||||
>
|
>
|
||||||
{account.profilePic ? (
|
<ProfilePhoto
|
||||||
<img
|
|
||||||
src={account.profilePic}
|
src={account.profilePic}
|
||||||
className="h-10 w-10 shadow pointer-events-none rounded-full border-[3px] border-sky-500 group-hover:border-sky-400 duration-100"
|
className="sm:group-hover:h-8 sm:group-hover:w-8 duration-100"
|
||||||
alt=""
|
|
||||||
id="profile-dropdown"
|
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon={faCircleUser}
|
|
||||||
id="profile-dropdown"
|
|
||||||
className="h-10 w-10 pointer-events-none text-sky-500 group-hover:text-sky-400 duration-100"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
id="profile-dropdown"
|
id="profile-dropdown"
|
||||||
className="text-sky-500 group-hover:text-sky-400 duration-100 hidden sm:flex item-center gap-1 max-w-[8rem]"
|
className="text-sky-500 duration-100 hidden sm:flex item-center gap-1 max-w-[8rem]"
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
id="profile-dropdown"
|
id="profile-dropdown"
|
||||||
|
@ -102,7 +93,7 @@ export default function () {
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
id="profile-dropdown"
|
id="profile-dropdown"
|
||||||
icon={faChevronDown}
|
icon={faChevronDown}
|
||||||
className="h-3 w-3"
|
className="h-3 w-3 text-gray-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import ImageWithFallback from "./ImageWithFallback";
|
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faUser } from "@fortawesome/free-solid-svg-icons";
|
import { faUser } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
|
@ -9,16 +8,26 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ProfilePhoto({ src, className }: Props) {
|
export default function ProfilePhoto({ src, className }: Props) {
|
||||||
return (
|
const [error, setError] = useState(false);
|
||||||
<ImageWithFallback
|
|
||||||
src={src}
|
useEffect(() => {
|
||||||
className={`h-10 w-10 shadow rounded-full border-[3px] border-sky-100 ${className}`}
|
console.log(src);
|
||||||
>
|
}, []);
|
||||||
|
|
||||||
|
return error || !src ? (
|
||||||
<div
|
<div
|
||||||
className={`bg-sky-500 text-white h-10 w-10 shadow rounded-full border-[3px] border-sky-100 flex items-center justify-center ${className}`}
|
className={`bg-sky-500 text-white h-10 w-10 shadow rounded-full border-[3px] border-slate-200 flex items-center justify-center ${className}`}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faUser} className="w-5 h-5" />
|
<FontAwesomeIcon icon={faUser} className="w-5 h-5" />
|
||||||
</div>
|
</div>
|
||||||
</ImageWithFallback>
|
) : (
|
||||||
|
<img
|
||||||
|
alt=""
|
||||||
|
src={src}
|
||||||
|
className={`h-10 w-10 shadow rounded-full border-[3px] border-slate-200 ${className}`}
|
||||||
|
onError={() => {
|
||||||
|
setError(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ export default function Search() {
|
||||||
placeholder="Search for Links"
|
placeholder="Search for Links"
|
||||||
value={searchQuery}
|
value={searchQuery}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
e.target.value.includes("%") &&
|
||||||
|
console.log("The search query should not contain '%'.");
|
||||||
setSearchQuery(e.target.value.replace("%", ""));
|
setSearchQuery(e.target.value.replace("%", ""));
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) =>
|
onKeyDown={(e) =>
|
||||||
|
@ -41,7 +43,7 @@ export default function Search() {
|
||||||
router.push("/search/" + encodeURIComponent(searchQuery))
|
router.push("/search/" + encodeURIComponent(searchQuery))
|
||||||
}
|
}
|
||||||
autoFocus={searchBox}
|
autoFocus={searchBox}
|
||||||
className="border border-sky-100 rounded-md pl-10 py-2 pr-2 w-44 sm:w-60 focus:border-sky-500 sm:focus:w-80 hover:border-sky-500 duration-100 outline-none"
|
className="border border-sky-100 rounded-md pl-10 py-2 pr-2 w-44 sm:w-60 focus:border-sky-500 md:focus:w-80 hover:border-sky-500 duration-100 outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,7 +21,6 @@ export default function ({ className }: { className?: string }) {
|
||||||
const [active, setActive] = useState("");
|
const [active, setActive] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(window.location.hash);
|
|
||||||
setActive(router.asPath);
|
setActive(router.asPath);
|
||||||
}, [router, collections]);
|
}, [router, collections]);
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ export interface CollectionIncludingMembers
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccountSettings extends User {
|
export interface AccountSettings extends User {
|
||||||
profilePic: string | null;
|
profilePic: string;
|
||||||
oldPassword?: string;
|
oldPassword?: string;
|
||||||
newPassword?: string;
|
newPassword?: string;
|
||||||
}
|
}
|
||||||
|
|
Ŝarĝante…
Reference in New Issue