Implemented image at header and implemented horizontal scroll
This commit is contained in:
parent
79e3321a85
commit
b801689f32
4 changed files with 67 additions and 43 deletions
BIN
src/frontend/src/assets/profile-circle.png
Normal file
BIN
src/frontend/src/assets/profile-circle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -1,9 +1,12 @@
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
|
import profileCircle from "../../assets/profile-circle.png";
|
||||||
import { FaDiscord, FaGithub } from "react-icons/fa";
|
import { FaDiscord, FaGithub } from "react-icons/fa";
|
||||||
import { RiTwitterXFill } from "react-icons/ri";
|
import { RiTwitterXFill } from "react-icons/ri";
|
||||||
import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
|
import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
|
||||||
import AlertDropdown from "../../alerts/alertDropDown";
|
import AlertDropdown from "../../alerts/alertDropDown";
|
||||||
import {
|
import {
|
||||||
|
BACKEND_URL,
|
||||||
|
BASE_URL_API,
|
||||||
LOCATIONS_TO_RETURN,
|
LOCATIONS_TO_RETURN,
|
||||||
USER_PROJECTS_HEADER,
|
USER_PROJECTS_HEADER,
|
||||||
} from "../../constants/constants";
|
} from "../../constants/constants";
|
||||||
|
|
@ -192,34 +195,35 @@ export default function Header(): JSX.Element {
|
||||||
variant="none"
|
variant="none"
|
||||||
size="none"
|
size="none"
|
||||||
data-testid="user-profile-settings"
|
data-testid="user-profile-settings"
|
||||||
className={
|
>
|
||||||
"h-7 w-7 rounded-full focus-visible:outline-0 " +
|
<img
|
||||||
(userData?.profile_image ??
|
src={
|
||||||
(userData?.id
|
`${BACKEND_URL.slice(
|
||||||
? gradients[
|
0,
|
||||||
parseInt(userData?.id ?? "", 30) % gradients.length
|
BACKEND_URL.length - 1,
|
||||||
]
|
)}${BASE_URL_API}files/profile_pictures/${userData?.profile_image}` ??
|
||||||
: "bg-gray-500"))
|
profileCircle
|
||||||
}
|
}
|
||||||
/>
|
className="h-7 w-7 focus-visible:outline-0 "
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent>
|
<DropdownMenuContent>
|
||||||
{!autoLogin && (
|
{!autoLogin && (
|
||||||
<>
|
<>
|
||||||
<DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div
|
<img
|
||||||
className={
|
src={
|
||||||
"h-5 w-5 rounded-full focus-visible:outline-0 " +
|
`${BACKEND_URL.slice(
|
||||||
(userData?.profile_image ??
|
0,
|
||||||
(userData?.id
|
BACKEND_URL.length - 1,
|
||||||
? gradients[
|
)}${BASE_URL_API}files/profile_pictures/${userData?.profile_image}` ??
|
||||||
parseInt(userData?.id ?? "", 30) %
|
profileCircle
|
||||||
gradients.length
|
|
||||||
]
|
|
||||||
: "bg-gray-500"))
|
|
||||||
}
|
}
|
||||||
|
className="h-5 w-5 focus-visible:outline-0 "
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{userData?.username ?? "User"}
|
{userData?.username ?? "User"}
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import useAlertStore from "../../../../../../../../stores/alertStore";
|
import useAlertStore from "../../../../../../../../stores/alertStore";
|
||||||
import { gradients } from "../../../../../../../../utils/styleUtils";
|
import { gradients } from "../../../../../../../../utils/styleUtils";
|
||||||
import useGetProfilePictures from "./hooks/use-get-profile-pictures";
|
import useGetProfilePictures from "./hooks/use-get-profile-pictures";
|
||||||
|
|
@ -10,6 +10,8 @@ import {
|
||||||
import HorizontalScrollFadeComponent from "../../../../../../../../components/horizontalScrollFadeComponent";
|
import HorizontalScrollFadeComponent from "../../../../../../../../components/horizontalScrollFadeComponent";
|
||||||
import LoadingComponent from "../../../../../../../../components/loadingComponent";
|
import LoadingComponent from "../../../../../../../../components/loadingComponent";
|
||||||
import Loading from "../../../../../../../../components/ui/loading";
|
import Loading from "../../../../../../../../components/ui/loading";
|
||||||
|
import { cn } from "../../../../../../../../utils/utils";
|
||||||
|
import { Button } from "../../../../../../../../components/ui/button";
|
||||||
|
|
||||||
type ProfilePictureChooserComponentProps = {
|
type ProfilePictureChooserComponentProps = {
|
||||||
profilePictures: { [key: string]: string[] };
|
profilePictures: { [key: string]: string[] };
|
||||||
|
|
@ -24,35 +26,53 @@ export default function ProfilePictureChooserComponent({
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
}: ProfilePictureChooserComponentProps) {
|
}: ProfilePictureChooserComponentProps) {
|
||||||
|
const ref = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (value && ref) {
|
||||||
|
ref.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||||
|
}
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-center gap-2">
|
<div className="flex flex-col justify-center gap-2">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Loading />
|
<Loading />
|
||||||
) : (
|
) : (
|
||||||
Object.keys(profilePictures).map((folder, idx) => (
|
Object.keys(profilePictures).map((folder, idx) => (
|
||||||
<Label>
|
<div className="flex flex-col gap-2">
|
||||||
<div className="edit-flow-arrangement">
|
<div className="edit-flow-arrangement">
|
||||||
<span className="font-medium">{folder}</span>
|
<span className="font-normal">{folder}</span>
|
||||||
</div>
|
</div>
|
||||||
<HorizontalScrollFadeComponent>
|
<div className="block overflow-hidden">
|
||||||
{profilePictures[folder].map((path, idx) => (
|
<div className="flex items-center gap-1 overflow-x-auto rounded-lg bg-background px-1">
|
||||||
<img
|
{profilePictures[folder].map((path, idx) => (
|
||||||
key={idx}
|
<Button
|
||||||
src={`${BACKEND_URL.slice(
|
ref={value === folder + "/" + path ? ref : undefined}
|
||||||
0,
|
size="none"
|
||||||
BACKEND_URL.length - 1,
|
variant="none"
|
||||||
)}${BASE_URL_API}files/images/${folder + "/" + path}`}
|
onClick={() => onChange(folder + "/" + path)}
|
||||||
className={
|
className="shrink-0 px-0.5 py-2"
|
||||||
"h-12 w-12 rounded-full" +
|
>
|
||||||
(value === folder + "/" + path
|
<img
|
||||||
? " border-2 border-white"
|
key={idx}
|
||||||
: "")
|
src={`${BACKEND_URL.slice(
|
||||||
}
|
0,
|
||||||
onClick={() => onChange(folder + "/" + path)}
|
BACKEND_URL.length - 1,
|
||||||
/>
|
)}${BASE_URL_API}files/profile_pictures/${folder + "/" + path}`}
|
||||||
))}
|
style={{
|
||||||
</HorizontalScrollFadeComponent>
|
filter:
|
||||||
</Label>
|
value === folder + "/" + path
|
||||||
|
? "drop-shadow(0 0 0.3rem rgb(255, 255, 255))"
|
||||||
|
: "",
|
||||||
|
}}
|
||||||
|
className={cn("h-12 w-12")}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ type ProfilePictureFormComponentProps = {
|
||||||
profilePicture: string;
|
profilePicture: string;
|
||||||
handleInput: (event: any) => void;
|
handleInput: (event: any) => void;
|
||||||
handlePatchProfilePicture: (gradient: string) => void;
|
handlePatchProfilePicture: (gradient: string) => void;
|
||||||
handleGetProfilePictures: () => Promise<string[]>;
|
handleGetProfilePictures: () => Promise<string[] | undefined>;
|
||||||
userData: any;
|
userData: any;
|
||||||
};
|
};
|
||||||
const ProfilePictureFormComponent = ({
|
const ProfilePictureFormComponent = ({
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue