Skip to content
This repository has been archived by the owner on Sep 29, 2024. It is now read-only.

Frontend alert #357

Merged
merged 5 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 155 additions & 19 deletions Frontend/src/pages/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export default function Settings(userProfile: UserDataParams) {
const [newName, setNewName] = React.useState('');
const [changedData, setChangedDataName] = React.useState<UserData | null>(null);
const [open, setOpen] = React.useState(false);
const [openName, setOpenName] = React.useState(false);
const [openFile, setOpenFile] = React.useState(false);
const [openFileSuccess, setOpenFileSuccess] = React.useState(false);
const [openPassDialog, setOpenPassDialog] = React.useState(false);
const [passwordDeleteChange, setPasswordDeleteChange] = React.useState("");


Expand All @@ -43,6 +47,43 @@ export default function Settings(userProfile: UserDataParams) {
setOpen(false);
};


const handleClickOpenName = () => {
setOpenName(true);
};

const handleCloseName = () => {
setOpenName(false);
};


const handleClickOpenFile = () => {
setOpenFile(true);

};

const handleCloseFile = () => {
setOpenFile(false);
};


const handleClickOpenFileSucces = () => {
setOpenFileSuccess(true);
};

const handleCloseFileSuccess = () => {
setOpenFileSuccess(false);
};


const handleClickOpenPassDialog = () => {
setOpenPassDialog(true);
};

const handleClosePassDialog = () => {
setOpenPassDialog(false);
};

async function handleDeleteAccount(password: string) {
console.log(password);
const response = await new UserClient().deleteProfile(password);
Expand All @@ -57,24 +98,24 @@ export default function Settings(userProfile: UserDataParams) {
let imgUrl: string = document.querySelector(".ImageInput")?.firstElementChild?.getAttribute("src") ?? "";

if (imgUrl === "/static/media/photo_placeholder.47177532c4d2205871f4.png") {
alert("Please upload a picture first");
handleClickOpenFile();
return
} else {

document.querySelector(".userPicture")?.firstElementChild?.setAttribute("src", imgUrl);
const response = await new UserClient().changeProfilePicture(imgUrl ?? null);

if (response) {
handleClickOpenFileSucces();


alert("Successfully changed PP");
window.location.reload();

} else {
alert("Something went wrong");

}
}



}

useEffect(() => {
Expand Down Expand Up @@ -162,7 +203,7 @@ export default function Settings(userProfile: UserDataParams) {

<span className={"userPicture"}>
<img id="user-image"
src={changedData?.profilePicture ? `https://localhost:44328/images/profile-pictures/${changedData?.profilePicture}`:Placeholder}
src={changedData?.profilePicture ? `https://localhost:44328/images/profile-pictures/${changedData?.profilePicture}` : Placeholder}
alt="User"/>
</span>

Expand Down Expand Up @@ -197,44 +238,71 @@ export default function Settings(userProfile: UserDataParams) {
value={newName}
onChange={(e) => setNewName(e.target.value)}
/>

<Button
id="changeUsernameButton"
variant="contained"
color="primary"
onClick={async () => {
const result = await new UserClient().changeUsername(newName);

if (result === 200) {
if (changedData) {
setChangedDataName({...changedData, name: newName});
handleClickOpenName();
}
alert("Username changed successfully to " + newName);

} else {
alert("Error. Server responded with status: " + result);
alert("Error. Something went wrong: " + result);
}
}}
>Submit
</Button>
<span id="newNameMessage" style={{color: "red", fontSize: "22px", fontStyle: "bold"}}>{newNameMessage}</span>
<Dialog
open={openName}
onClose={handleCloseName}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
className="dialog-window"
>
<DialogTitle id="alert-dialog-title"
className="delete-dialog-title">{"Information"}</DialogTitle>
<DialogContent>
<p id="alert-dialog-description" className="delete-dialog-description">
Your name was changed to
<strong style={{display: "block", textAlign: "center"}}>{newName}</strong>
</p>
</DialogContent>
<DialogActions className="dialog-actions">
<Button className="dialog-button" onClick={handleCloseName} color="primary" autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>

<span id="newNameMessage"
style={{color: "red", fontSize: "22px", fontStyle: "bold"}}>{newNameMessage}</span>

<br/><br/>

<h2>Change Password</h2>
<TextField id="oldPassword" className="filled-basic" label="Current password" variant="filled" value={oldPassword} type="password" onChange={e => setOldPassword(e.target.value)}/>
<TextField id="newPassword" className="filled-basic" label="Enter new Password" variant="filled" value={newPassword} type="password"
<TextField id="oldPassword" className="filled-basic" label="Current password" variant="filled"
value={oldPassword} type="password" onChange={e => setOldPassword(e.target.value)}/>
<TextField id="newPassword" className="filled-basic" label="Enter new Password" variant="filled"
value={newPassword} type="password"
onChange={(e) => setNewPassword(e.target.value)}/>
<TextField id="repeatNewPassword" className="filled-basic" label="Repeat new password" variant="filled" value={passwordRe} type="password"
<TextField id="repeatNewPassword" className="filled-basic" label="Repeat new password" variant="filled"
value={passwordRe} type="password"
onChange={(e) => setPasswordRe(e.target.value)}/>
<Button id="changePasswordButton" variant="contained" color="primary" onClick={async () => {
if (newPassword !== passwordRe) {
alert("Passwords don't match!");
return
}
const response = await new UserClient().changePassword(oldPassword, newPassword);
if (response === 200) {

handleClickOpenPassDialog();
setPasswordAfterChangeMessage("Password Changed");
}else {

} else {
setPasswordAfterChangeMessage(response?.toString() ?? "Error");
}
setOldPassword("");
Expand All @@ -244,8 +312,32 @@ export default function Settings(userProfile: UserDataParams) {
}}>
Submit
</Button>
<span style={{color: "red", fontSize: "22px", fontStyle: "bold"}} id="passwordValidationMessage">{newPasswordMessage}</span>
<span style={{color: "red", fontSize: "22px", fontStyle: "bold"}} id="passwordAfterChangeMessage">{passwordAfterChangeMessage}</span>
<span style={{color: "red", fontSize: "22px", fontStyle: "bold"}}
id="passwordValidationMessage">{newPasswordMessage}</span>
<span style={{color: "red", fontSize: "22px", fontStyle: "bold"}}
id="passwordAfterChangeMessage">{passwordAfterChangeMessage}</span>

<Dialog
open={openPassDialog}
onClose={handleClosePassDialog}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
className="dialog-window"
>
<DialogTitle id="alert-dialog-title"
className="delete-dialog-title">{"Information"}</DialogTitle>
<DialogContent>
<p id="alert-dialog-description" className="delete-dialog-description">

<strong style={{display: "block", textAlign: "center"}}>Your password was successfully changed </strong>
</p>
</DialogContent>
<DialogActions className="dialog-actions">
<Button className="dialog-button" onClick={handleClosePassDialog} color="primary" autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>
</Box>

<Box className={"body-right"}
Expand All @@ -258,7 +350,51 @@ export default function Settings(userProfile: UserDataParams) {
>
<h2>Change Profile Picture</h2>
<ImageUploader recipe={null} setRecipe={null}/>
<Button id="changeProfilePictureButton" variant="contained" color="secondary" onClick={handlePicChange}>Change</Button>
<Button id="changeProfilePictureButton" variant="contained" color="secondary"
onClick={handlePicChange}>Change</Button>

<Dialog
open={openFile}
onClose={handleCloseFile}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
className="dialog-window"
>
<DialogTitle id="alert-dialog-title"
className="delete-dialog-title">{"Something went wrong!"}</DialogTitle>
<DialogContent>
<p id="alert-dialog-description" className="delete-dialog-description">
Please select a file first!
</p>
</DialogContent>
<DialogActions className="dialog-actions">
<Button className="dialog-button" onClick={handleCloseFile} color="primary" autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>
<Dialog
open={openFileSuccess}
onClose={handleCloseFileSuccess}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
className="dialog-window"
>
<DialogTitle id="alert-dialog-title"
className="delete-dialog-title">{"Information"}</DialogTitle>
<DialogContent>
<p id="alert-dialog-description" className="delete-dialog-description">

<strong style={{display: "block", textAlign: "center"}}>Your profile picture was
successfully changed</strong>
</p>
</DialogContent>
<DialogActions className="dialog-actions">
<Button className="dialog-button" onClick={() => {handleCloseFileSuccess(); window.location.reload();}} color="primary" autoFocus>
Ok
</Button>
</DialogActions>
</Dialog>

<br/>

Expand Down
2 changes: 1 addition & 1 deletion Frontend/src/setupTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jest.setTimeout(20_000);

beforeAll(async () => {
const options = new Chrome.Options();
options.addArguments('headless', 'ignore-certificate-errors', '--disable-single-click-autofill');
options.addArguments( 'headless', 'ignore-certificate-errors', '--disable-single-click-autofill');
options.setUserPreferences({ 'autofill.profile_enabled': false });
driver = await new Builder().forBrowser(Browser.CHROME).setChromeOptions(options).build();
await driver.manage().setTimeouts({ implicit: 2000 });
Expand Down
1 change: 1 addition & 0 deletions Frontend/src/tests/MyRecipes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('test with logged in user', () => {
const ownRecipesHeading = await driver.findElement(By.css('.recipe-column:nth-of-type(2) .heading'));
const likedRecipesCards = await driver.findElements(By.css('.recipe-column:nth-child(1) .recipe-card-container'));
const ownRecipesCards = await driver.findElements(By.css('.recipe-column:nth-child(2) .recipe-card-container'));
await driver.wait(until.elementIsVisible(likedRecipesCards[0]?? likedRecipesHeading));

// ASSERT
expect(await likedRecipesHeading.getText()).toContain("'s Liked Recipes");
Expand Down
2 changes: 2 additions & 0 deletions Frontend/src/tests/Recipe.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe('test with logged in user', () => {
await driver.wait(until.elementIsVisible(likeCount));
expect(await likeCount.getText()).toEqual('Likes: 1');
expect(await likeButton.getAttribute('aria-pressed')).toEqual('true');
await driver.wait(until.elementIsVisible(likeButton));

try {
// ACT
Expand Down Expand Up @@ -75,6 +76,7 @@ describe('test with logged in user', () => {
await driver.wait(until.elementIsVisible(likeButton));
expect(await likeCount.getText()).toEqual('Likes: 0');
expect(await likeButton.getAttribute('aria-pressed')).toEqual('false');
await driver.wait(until.elementIsVisible(likeButton));

try {
// ACT
Expand Down
Loading
Loading