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

Commit

Permalink
Merge branch 'main' into frog_image
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuaki-kumazaki authored Jul 1, 2024
2 parents c429fa3 + 33bc48c commit 2bb2fba
Show file tree
Hide file tree
Showing 13 changed files with 603 additions and 46 deletions.
106 changes: 106 additions & 0 deletions frontend/src/Components/CreatePetModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,112 @@ const CreatePetModal = () => {
</Popup>
</>
);
const [open, setOpen] = useState(false);
const [petName, setPetName] = useState("");
const [petType, setPetType] = useState("Land");

const handleClose = () => {
setPetName("");
setPetType("Land");
setOpen(false);
};

const handleInputPetName = (e: { target: { value: SetStateAction<string>; }; }) => {
setPetName(e.target.value);
};

const handleInputPetType = (e: { target: { value: SetStateAction<string>; }; }) => {
setPetType(e.target.value);
};

const handleSubmit = (e: { preventDefault: () => void; }) => {
e.preventDefault(); // Prevent form from reloading the page
if (petName.trim() === "" || petName.trim() === "DEAD" || petType === "") {
return;
}
// TODO: Save the device ID or perform any action with the input value
console.log("Pet Name:", petName, " Pet Type:", petType);
setOpen(false); // Close the popup after submission
};

return (
<>
<div className='container-fluid d-flex justify-content-center align-items-center' style={{ height: '100vh' }}>
<button className="btn btn-success" onClick={() => setOpen(true)}>Create Teamagochi</button>
</div>
<Popup
open={open}
onClose={handleClose}
overlayStyle={{ background: 'rgba(0, 0, 0, 0.5)' }}
contentStyle={{ borderRadius: '10px', border: '2px solid grey', width: '50%' }}
>
<div style={{ padding: '20px', position: 'relative' }}>
<button
type="button"
className="btn-close"
aria-label="Close"
style={{ position: 'absolute', top: '10px', right: '10px' }}
onClick={handleClose}
></button>

<form className="row g-0 needs-validation justify-content-center" onSubmit={handleSubmit}>
<figure className='text-center'>
<p className='lead'>
<strong>Enter your Pet Name below and choose it's Type:
<p>Pet name cannot be "DEAD"</p>
</strong>
</p>
</figure>

{petType === "Land" &&
<div className="card align-items-center m-3" style={{ width: "40%" }}>
<img src={profile_land} className="card-img-top py-3" style={{ width: "80%", height: "auto" }} />
</div>
}

{petType == "Air" &&
<div className="card align-items-center m-3" style={{ width: "40%" }}>
<img src={profile_air} className="card-img-top py-3" alt="profile picture" style={{ width: "80%", height: "auto" }} />
</div>
}

{petType == "Water" &&
<div className="card align-items-center m-3" style={{ width: "40%" }}>
<img src={profile_water} className="card-img-top py-3" alt="profile picture" style={{ width: "80%", height: "auto" }} />
</div>
}

<div className="input-group mb-1">
<span className="input-group-text">@</span>
<label htmlFor="inputLink" className="visually-hidden">Pet Name</label>
<input type="text" className="form-control" id="inputPetName"
placeholder="Pet Name" required value={petName} onChange={handleInputPetName} />
<div className='invalid-feedback'>ok</div>
</div>

<div className="btn-group btn-group-toggle pt-2" data-toggle="buttons">
<input type="radio" className="btn-check" name="options" id="option1" value="Land" autoComplete="off"
checked={petType === "Land"} onChange={handleInputPetType}></input>
<label className="btn btn-secondary" htmlFor="option1">Land</label>

<input type="radio" className="btn-check" name="options" id="option2" value="Air" autoComplete="off"
checked={petType === "Air"} onChange={handleInputPetType}></input>
<label className="btn btn-secondary" htmlFor="option2">Air</label>

<input type="radio" className="btn-check" name="options" id="option3" value="Water" autoComplete="off"
checked={petType === "Water"} onChange={handleInputPetType}></input>
<label className="btn btn-secondary" htmlFor='option3'>Water</label>
</div>

<button type='submit' className='btn btn-success mt-2 mb-2'>
Create
</button>
</form>
</div>
</Popup>
</>
);

};

export default CreatePetModal;
142 changes: 96 additions & 46 deletions frontend/src/Components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,110 @@
import { useState } from 'react';
import React, { useState } from 'react';
import profile_pic1 from '../Misc/8-bit-dog-nobg.png';
import 'bootstrap/dist/css/bootstrap.min.css';
import LinkDevice from "../Components/LinkDevice";

interface SettingsProps {
username: string;
username: string;
}

function Settings(
{ username }: SettingsProps
{ username }: SettingsProps
) {
const [items, setItems] = useState(['Device 1', 'Device 2', 'Device 3']);
const [showLinkDevice, setShowLinkDevice] = useState<boolean>(true);

const removeItem = (index: number) => {
setItems(items.filter((_, i) => i !== index));
};

// const resetItem = (index: number) => {
// setItems(items.map((item, i) => (i === index ? `Item ${index + 1}` : item)));
// };

return (
<div className='d-flex justify-content-center pt-4 pb-2'>
<div className="card align-items-center text-bg-light" style={{ width: "500px" }}>
<img src={profile_pic1} className="card-img-top py-3" alt="profile picture" style={{ width: "100%", height: "auto" }} />
<h2 className="card-title text-center"><kbd className='bg-success text-white'>PROFILE</kbd></h2>
<div className="card-body" style={{ width: "100%" }}>
<div className="input-group mb-4" style={{ height: "60px" }}>
<div className="input-group-prepend">
<div className="input-group-text" style={{ fontSize: "1.5rem", height: "60px", display: 'flex', alignItems: 'center' }}>@</div>
const [items, setItems] = useState(['Device 1', 'Device 2', 'Device 3']);
const [showLinkDevice, setShowLinkDevice] = useState<boolean>(true);
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
const [showModal, setShowModal] = useState<boolean>(false);
const [itemToRemove, setItemToRemove] = useState<number | null>(null);

const handleRemoveItem = (index: number) => {
setShowModal(true);
setItemToRemove(index);
};

const confirmRemoveItem = () => {
if (itemToRemove !== null) {
setItems(items.filter((_, i) => i !== itemToRemove));
if (selectedIndex === itemToRemove) {
setSelectedIndex(null);
}
setItemToRemove(null);
}
setShowModal(false);
};

const cancelRemoveItem = () => {
setShowModal(false);
setItemToRemove(null);
};

const resetItem = (index: number) => {
setItems(items.map((item, i) => (i === index ? `Item ${index + 1}` : item)));
};

const selectItem = (index: number) => {
setSelectedIndex(index);
};

return (
<div className='d-flex justify-content-center pt-4 pb-2'>
<div className="card align-items-center text-bg-light" style={{ width: "500px" }}>
<img src={profile_pic1} className="card-img-top py-3" alt="profile picture" style={{ width: "100%", height: "auto" }} />
<h2 className="card-title text-center"><kbd className='bg-success text-white'>PROFILE</kbd></h2>
<div className="card-body" style={{ width: "100%" }}>
<div className="input-group mb-4" style={{ height: "60px" }}>
<div className="input-group-prepend">
<div className="input-group-text" style={{ fontSize: "1.5rem", height: "60px", display: 'flex', alignItems: 'center' }}>@</div>
</div>
<input type="text" className="form-control text-black" placeholder={username} disabled style={{ fontSize: "1.5rem", height: "60px" }}></input>
</div>
<div className='d-flex justify-content-center pt-2'>
<button type="button" className="btn btn-success btn-block w-100" style={{ fontSize: "1.5rem", height: "60px" }} onClick={() => setShowLinkDevice(false)} >Link Device</button>
</div>
<div className='pt-4' style={{ width: "100%" }}>
<ul className="list-group" style={{ fontSize: "1.2rem" }}>
{items.map((item, index) => (
<li key={index} className="list-group-item d-flex justify-content-between align-items-center py-3">
{item}
<div>
<button
className="btn btn-primary btn-lg mx-1"
onClick={() => selectItem(index)}
disabled={selectedIndex === index}
>
{selectedIndex === index ? 'Selected' : 'Select'}
</button>
<button className="btn btn-danger btn-lg mx-1" onClick={() => handleRemoveItem(index)}>Remove</button>
</div>
</li>
))}
</ul>
</div>
</div>
</div>
<input type="text" className="form-control text-black" placeholder={username} disabled style={{ fontSize: "1.5rem", height: "60px" }}></input>
</div>
<div className='d-flex justify-content-center pt-2'>
<button type="button" className="btn btn-success btn-block w-100" style={{ fontSize: "1.5rem", height: "60px" }} onClick={() => setShowLinkDevice(false)} >Link Device</button>
</div>
<div className='pt-4' style={{ width: "100%" }}>
<ul className="list-group" style={{ fontSize: "1.2rem" }}>
{items.map((item, index) => (
<li key={index} className="list-group-item d-flex justify-content-between align-items-center py-3">
{item}
<div>
<button className="btn btn-danger btn-lg mx-1" onClick={() => removeItem(index)}>Remove</button>
</div>
</li>
))}
</ul>
</div>
{showLinkDevice === false && (
<LinkDevice onClose={() => setShowLinkDevice(true)} />
)}

{showModal && (
<div className="modal show d-block" tabIndex={-1} role="dialog">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Confirm Removal</h5>
</div>
<div className="modal-body">
<p>Are you sure you want to remove this pet?</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" onClick={cancelRemoveItem}>No</button>
<button type="button" className="btn btn-danger" onClick={confirmRemoveItem}>Yes</button>
</div>
</div>
</div>
</div>
)}
</div>
</div>
{showLinkDevice==false && (
<LinkDevice onClose={() => setShowLinkDevice(true)} />
)}
</div>
);
);
}

export default Settings;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import haw.teamagochi.backend.device.logic.UcManageDevice;
import haw.teamagochi.backend.device.service.rest.v1.mapper.DeviceMapper;
import haw.teamagochi.backend.device.service.rest.v1.model.DeviceDTO;
import haw.teamagochi.backend.pet.logic.UcManagePet;
import haw.teamagochi.backend.pet.logic.gameCycle.GameCycleImpl;
import jakarta.inject.Inject;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
Expand Down Expand Up @@ -34,6 +36,13 @@ public class DeviceRestService {
@Inject
protected UcManageDevice ucManageDevice;

@Inject
protected UcManagePet ucManagePet;

@Inject
protected GameCycleImpl gameCycle;


/**
* Get all devices.
*
Expand Down Expand Up @@ -84,4 +93,20 @@ public DeviceDTO deleteDeviceById(@PathParam("deviceId") long deviceId) {
}
throw new NotFoundException();
}
@DELETE
@Path("/reset")
@Operation(summary = "delete all Devices and Pets")
@APIResponse(responseCode = "200")
@APIResponse(responseCode = "404", description = "Not Found")
public List<DeviceDTO> deleteAllPet() {
List<DeviceEntity> entities = ucFindDevice.findAll();
gameCycle.setStopRequested(true);
while (!gameCycle.isStopped()){
//waiting for stopped
}
ucManageDevice.deleteAll();
ucManagePet.deleteAll();
gameCycle.setStopRequested(false);
return deviceMapper.mapEntityToTransferObject(entities);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package haw.teamagochi.backend.pet.logic;

import haw.teamagochi.backend.pet.dataaccess.model.PetEntity;
import java.util.List;

public interface UcLeaderboard {

/**
* Ranked on Happiness and Wellbeing, two are equally ranked the name decides
* @return the top 10 Pets
*/
List<PetEntity> getTop10();

/**
* Ranked on Happiness and Wellbeing, two are equally ranked the name decides
* @return the leaderboard consisting of all pets
*/
List<PetEntity> getCompleteLeaderBoard();

/**
* Ranked purely on Happiness, when two are equally ranked the name decides
* @return the top 10 pets according to their Happiness
*/
List<PetEntity> getHappinessTop10();

/**
* Ranked purely on Happiness, when two are equally ranked the name decides
* @return the leaderboard consisting of all pets
*/
List<PetEntity> getCompleteHappinessLeaderBoard();

/**
* Ranked purely on Wellbeing, when two are equally ranked the name decides
* @return the top 10 pets according to their Wellbeing
*/
List<PetEntity> getWellbeingTop10();

/**
* Ranked purely on Wellbeing, when two are equally ranked the name decides
* @return the leaderboard consisting of all pets
*/
List<PetEntity> getCompleteWellbeingLeaderboard();



}
Loading

0 comments on commit 2bb2fba

Please sign in to comment.