mirror of
https://github.com/bubblecup-12/VogelSocialMedia.git
synced 2025-07-06 15:18:48 +00:00
install file picker and fix UI bugs
This commit is contained in:
parent
df9b44d061
commit
3a0a3e4331
6 changed files with 121 additions and 64 deletions
|
@ -21,6 +21,7 @@
|
||||||
"react-router-dom": "^7.6.2",
|
"react-router-dom": "^7.6.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"typescript": "^4.4.2",
|
"typescript": "^4.4.2",
|
||||||
|
"use-file-picker": "^2.1.4",
|
||||||
"web-vitals": "^2.1.0"
|
"web-vitals": "^2.1.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useRef, useState } from "react";
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
styled,
|
styled,
|
||||||
|
@ -10,12 +9,15 @@ import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
|
Divider,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import EditSquareIcon from "@mui/icons-material/EditSquare";
|
import EditSquareIcon from "@mui/icons-material/EditSquare";
|
||||||
import "../styles/colors.css";
|
import "../styles/colors.css";
|
||||||
import "../styles/fonts.css";
|
import "../styles/fonts.css";
|
||||||
import "./changeAvatarDialog.css";
|
import "./changeAvatarDialog.css";
|
||||||
|
import ButtonPrimary from "./ButtonPrimary";
|
||||||
|
import { useFilePicker } from "use-file-picker";
|
||||||
|
|
||||||
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
|
const BootstrapDialog = styled(Dialog)(({ theme }) => ({
|
||||||
"& .MuiDialogContent-root": {
|
"& .MuiDialogContent-root": {
|
||||||
|
@ -27,25 +29,20 @@ const BootstrapDialog = styled(Dialog)(({ theme }) => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
export default function CustomizedDialogs() {
|
export default function CustomizedDialogs() {
|
||||||
|
const { openFilePicker, filesContent, loading } = useFilePicker({
|
||||||
|
accept: ".png, .jpg, .jpeg",
|
||||||
|
multiple: false,
|
||||||
|
readAs: "DataURL",
|
||||||
|
limitFilesConfig: { max: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
const inputFile = useRef<HTMLInputElement | null>(null);
|
const setImageURL = ({ newImage = false }: { newImage: boolean }) => {
|
||||||
|
if (newImage) {
|
||||||
const openFileExplorer = () => {
|
return filesContent[0].content;
|
||||||
// `current` points to the mounted file input element
|
|
||||||
if (inputFile.current) {
|
|
||||||
inputFile.current.click();
|
|
||||||
}
|
}
|
||||||
};
|
// TODO: If no image is selected, return the image already in the database or undefined
|
||||||
|
|
||||||
const [selectedImage, setSelectedImage] = useState<File | null>(null);
|
|
||||||
|
|
||||||
const setImageURL = (selectedImage: File | null) => {
|
|
||||||
if (selectedImage !== null) {
|
|
||||||
return URL.createObjectURL(selectedImage);
|
|
||||||
}
|
|
||||||
//TODO: If no image is selected, return the image already in the database or undefined
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
@ -53,19 +50,25 @@ export default function CustomizedDialogs() {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setSelectedImage(null); // Reset the selected image when closing
|
setImageURL({ newImage: false }); // Reset the selected image when closing
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
};
|
};
|
||||||
const handleSaveChanges = () => {
|
const handleSaveChanges = () => {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Button onClick={handleClickOpen}>
|
<Button onClick={handleClickOpen}>
|
||||||
<Avatar
|
<Avatar
|
||||||
alt="Username"
|
alt="Username"
|
||||||
src={setImageURL(selectedImage)}
|
// current code does not work yet
|
||||||
|
// TODO: If no image is selected, return the image already in the database or undefined
|
||||||
|
src={
|
||||||
|
filesContent.length > 0
|
||||||
|
? setImageURL({ newImage: true })
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
className="profile-avatar"
|
className="profile-avatar"
|
||||||
>
|
>
|
||||||
U
|
U
|
||||||
|
@ -76,7 +79,11 @@ export default function CustomizedDialogs() {
|
||||||
aria-labelledby="change-profile-picture-dialog"
|
aria-labelledby="change-profile-picture-dialog"
|
||||||
open={open}
|
open={open}
|
||||||
>
|
>
|
||||||
<DialogTitle sx={{ m: 0, p: 2 }} id="change-profile-picture-dialog">
|
<DialogTitle
|
||||||
|
className="small-title orange-text"
|
||||||
|
sx={{ m: 1.5, p: 2 }}
|
||||||
|
id="change-profile-picture-dialog"
|
||||||
|
>
|
||||||
Change Profile Picture
|
Change Profile Picture
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -91,7 +98,8 @@ export default function CustomizedDialogs() {
|
||||||
>
|
>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<DialogContent dividers>
|
<Divider variant="middle" className="divider" />
|
||||||
|
<DialogContent>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
@ -103,32 +111,32 @@ export default function CustomizedDialogs() {
|
||||||
maxHeight: "30rem",
|
maxHeight: "30rem",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{selectedImage && (
|
{filesContent.map((file) => (
|
||||||
<img
|
<img
|
||||||
src={URL.createObjectURL(selectedImage)}
|
alt={file.name}
|
||||||
alt="Profile Picture"
|
src={file.content}
|
||||||
style={{maxWidth: "30rem", maxHeight: "30rem" , width: "100%", height: "100%", objectFit: "cover"}}
|
style={{
|
||||||
/>
|
maxWidth: "30rem",
|
||||||
)}
|
maxHeight: "30rem",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
objectFit: "cover",
|
||||||
|
}}
|
||||||
|
></img>
|
||||||
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
<IconButton aria-label="upload picture" onClick={openFileExplorer}>
|
<div className="change-avatar-button">
|
||||||
<EditSquareIcon />
|
<IconButton
|
||||||
<input
|
aria-label="upload picture"
|
||||||
type="file"
|
onClick={() => openFilePicker()}
|
||||||
id="file"
|
>
|
||||||
onChange={(event) => {
|
<EditSquareIcon className="edit-icon" />
|
||||||
console.log(event.target.files ? [0] : undefined); // Log the selected file
|
</IconButton>
|
||||||
if (event.target.files && event.target.files[0]) {
|
</div>
|
||||||
setSelectedImage(event.target.files[0]); // Update the state with the selected file
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
<Divider variant="middle" className="divider" />
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button autoFocus onClick={handleSaveChanges}>
|
<ButtonPrimary value="Save Changes" onClick={handleSaveChanges} />
|
||||||
Save changes
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</BootstrapDialog>
|
</BootstrapDialog>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|
|
@ -4,9 +4,43 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-image-large {
|
.profile-image-large {
|
||||||
width: 20rem;
|
max-width: 30rem;
|
||||||
height: 20rem;
|
max-height: 30rem;
|
||||||
object-fit: cover;
|
width: 100%;
|
||||||
border-radius: 8px;
|
height: 100%;
|
||||||
|
object-fit: "cover";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.css-10d30g3-MuiPaper-root-MuiDialog-paper {
|
||||||
|
background-color: var(--transparent-dark-blue);
|
||||||
|
backdrop-filter: blur(15px);
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-10d30g3-MuiPaper-root-MuiDialog-paper {
|
||||||
|
color: var(--Rotkehlchen-orange-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-avatar {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background-color: aqua;
|
||||||
|
}
|
||||||
|
|
||||||
|
.css-53g0n7-MuiButtonBase-root-MuiIconButton-root {
|
||||||
|
color: var(--Rotkehlchen-orange-default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.change-avatar-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.profile-avatar {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
background-color: var(--Rotkehlchen-yellow-default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
.numeral-data {
|
.numeral-data {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--Rotkehlchen-gray);
|
color: var(--Rotkehlchen-gray);
|
||||||
|
@ -49,12 +50,6 @@
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-avatar {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
background-color: aqua;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-username {
|
.profile-username {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
|
@ -99,7 +94,7 @@
|
||||||
.numeral-data {
|
.numeral-data {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 2rem;
|
margin-top: 1rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
@ -115,10 +110,4 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-avatar {
|
|
||||||
width: 5rem;
|
|
||||||
height: 5rem;
|
|
||||||
background-color: aqua;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,3 +26,14 @@ body{
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.blue-background {
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: var(--transparent-dark-blue);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-icon {
|
||||||
|
color: var(--Rotkehlchen-brown-light)
|
||||||
|
}
|
|
@ -4830,6 +4830,13 @@ file-loader@^6.2.0:
|
||||||
loader-utils "^2.0.0"
|
loader-utils "^2.0.0"
|
||||||
schema-utils "^3.0.0"
|
schema-utils "^3.0.0"
|
||||||
|
|
||||||
|
file-selector@^2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-2.1.2.tgz#fe7c7ee9e550952dfbc863d73b14dc740d7de8b4"
|
||||||
|
integrity sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.7.0"
|
||||||
|
|
||||||
filelist@^1.0.4:
|
filelist@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz"
|
resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz"
|
||||||
|
@ -9385,7 +9392,7 @@ tslib@^1.8.1:
|
||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
tslib@^2.0.3:
|
tslib@^2.0.3, tslib@^2.7.0:
|
||||||
version "2.8.1"
|
version "2.8.1"
|
||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz"
|
||||||
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
|
||||||
|
@ -9601,6 +9608,13 @@ url-parse@^1.5.3:
|
||||||
querystringify "^2.1.1"
|
querystringify "^2.1.1"
|
||||||
requires-port "^1.0.0"
|
requires-port "^1.0.0"
|
||||||
|
|
||||||
|
use-file-picker@^2.1.4:
|
||||||
|
version "2.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/use-file-picker/-/use-file-picker-2.1.4.tgz#2c005b005b627af30d2cfd1aeb3c01e952d390d1"
|
||||||
|
integrity sha512-b4lZiAWrXi/QNUjTv0Q+S0hVcSFXIC9c4EUcrnYtdPtgK3T6xfi01YLVamhoY0k9WM9Cg4KyxD1TtM1e8dzQAQ==
|
||||||
|
dependencies:
|
||||||
|
file-selector "^2.1.2"
|
||||||
|
|
||||||
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue