Skip to content

Commit

Permalink
Frontend things (#150)
Browse files Browse the repository at this point in the history
....
  • Loading branch information
Yousef-Taha1 committed Jul 1, 2024
2 parents 5d7ddc2 + 8ab40a4 commit 4e41ff0
Show file tree
Hide file tree
Showing 22 changed files with 348 additions and 1,383 deletions.
14 changes: 14 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 1 addition & 38 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import React from "react";
import { useAuth } from "react-oidc-context";
import { useState } from "react";
import "./App.css";
import LinkDevice from "./Components/LinkDevice";
import Footer from "./Components/Footer";
import Navbar from "./Components/Navbar/Navbar";
import Settings from "./Components/Settings";
import CreatePetModal from "./Components/CreatePetModal";
import PetPage from "./Components/PetPage";
import type { paths } from "./web-backend-api";
import createClient, { type Middleware } from "openapi-fetch";

function App() {
const auth = useAuth();
const [count, setCount] = useState(0);

switch (auth.activeNavigator) {
case "signinSilent":
Expand All @@ -32,41 +23,13 @@ function App() {
}

if (auth.isAuthenticated) {
// Client initialisation
const authMiddleware: Middleware = {
async onRequest({ request }) {
// add Authorization header to every request
request.headers.set(
"Authorization",
`Bearer ${auth.user?.access_token}`
);
return request;
},
};

const client = createClient<paths>({
baseUrl: "http://localhost:4000/backend",
});
client.use(authMiddleware);

// https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch
(async () => {
// console.log("hi there!");
// const { data, error } = await client.GET("/api/v1/devices/self", {});
// console.log("data", data);
// console.log("error", error);
})();

return (
<div style={{ backgroundColor: "#FFFFFF" }}>
<div>
<div>
<Navbar client={client} />
<Navbar />
</div>
</div>
{/* <div>
Hello USERNAME: {auth.user?.profile?.preferred_username || "User"}
</div> */}
<Footer />
</div>
);
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/Components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from "react";

const Footer = () => (
<div className="footer-content">
<footer className="footer page-footer font-small pt-3 bg-light">
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/Components/Friends.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from 'react';

const Friends = () => (
<div>
<h1>Friends Page</h1>
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/Components/Inventory.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import React from 'react';

const Inventory = () => (
<div>
<h1>Inventory Page</h1>
Expand Down
9 changes: 4 additions & 5 deletions frontend/src/Components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { useState } from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import Inventory from "../Inventory.tsx";
import Settings from "../Settings.tsx";
import Friends from "../Friends.tsx";
import PetPage from "../PetPage.tsx";
import LinkDevice from "../LinkDevice.tsx";
import { useAuth } from "react-oidc-context";
import "./navbar.css";
import { useState } from "react";

const Navbar = (client) => {
const Navbar = () => {
const auth = useAuth();
const [activePage, setActivePage] = useState("Pet Page");

Expand All @@ -22,7 +21,7 @@ const Navbar = (client) => {
marginRight: "20px",
};

const handlePageClick = (page) => {
const handlePageClick = (page: string) => {
setActivePage(page);
};

Expand Down Expand Up @@ -146,7 +145,7 @@ const Navbar = (client) => {
}
/>
<Route path="/Friends" element={<Friends />} />
<Route path="/PetPage" element={<PetPage client={client} />} />
<Route path="/PetPage" element={<PetPage />} />
</Routes>
</Router>
</div>
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/Components/PetDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Pet } from "../lib/api/usePetApi";
import PetDetailsProgressBar from "./PetDetailsProgressBar";

const PetDetails = (props: {pet: Pet, petImageSrc: string}) => {
const {pet, petImageSrc} = props;

if (!pet.state) return;
const petState = pet.state;

return (
<>
<div className="col-6">
<img className="img-fluid" src={petImageSrc} alt="Image showing the pet" />
</div>
<div className="col-6">
<div className="h2 px-3 py-4">{pet.name}</div>
<PetDetailsProgressBar value={petState.xp} color="green" />
<PetDetailsProgressBar value={petState.happiness} color="purple" />
<PetDetailsProgressBar value={petState.health} color="red" />
</div>
</>
);
}

export default PetDetails;
25 changes: 25 additions & 0 deletions frontend/src/Components/PetDetailsProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ProgressBar } from "react-progressbar-fancy";
import { IProgressBarProps } from "react-progressbar-fancy/build/ProgressBar/ProgressBar.types";

/**
* See https://github.com/RavinRau/react-progressbar-fancy
*/
const PetDetailsProgressBar = (props: {value?: number, color: IProgressBarProps["progressColor"]}) => {
return (
<>
{props.value != undefined && (
<div>
<div className="h5 px-3">{props.value}</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={props.color}
score={props.value}
/>
</div>
)}
</>
);
}

export default PetDetailsProgressBar;
146 changes: 28 additions & 118 deletions frontend/src/Components/PetPage.tsx
Original file line number Diff line number Diff line change
@@ -1,135 +1,45 @@
import { useEffect, useState } from "react";
import petImage from "../assets/pet_frog.png";
import { ProgressBar } from "react-progressbar-fancy";
import type { paths, components } from "../../src/web-backend-api";
import { useAuth } from "react-oidc-context";
import CreatePetModal from "./CreatePetModal";
import createClient, { type Middleware } from "openapi-fetch";
// https://github.com/RavinRau/react-progressbar-fancy?tab=readme-ov-file
import { Device, useDeviceApi } from "../lib/api/useDeviceApi";
import { Pet, usePetApi } from "../lib/api/usePetApi";
import PetDetails from "./PetDetails";

type PetDTO = components["schemas"]["PetDTO"];
// https://github.com/RavinRau/react-progressbar-fancy?tab=readme-ov-file

const PetPage = () => {
const auth = useAuth();
const authMiddleware: Middleware = {
async onRequest({ request }) {
// add Authorization header to every request
request.headers.set("Authorization", `Bearer ${auth.user?.access_token}`);
return request;
},
};
const [devices, setDevices] = useState<Device[]>([]);
const [pet, setPet] = useState<Pet | undefined>();
const deviceApi = useDeviceApi();
const petApi = usePetApi();

const client = createClient<paths>({
baseUrl: "http://localhost:4000/backend",
});
client.use(authMiddleware);

const [petData, setPetData] = useState({} as PetDTO);
useEffect(() => {
loadData();
}, []);
if (!deviceApi || !petApi) return;

const fetchData = async () => {
const devices = await deviceApi.getDevices();
const defaultDevice = devices[0];

const loadData = async () => {
const { data, error } = await client.GET("/api/v1/devices/self", {});
if (data && data[0].petId != undefined) {
const { data: data2, error } = await client.GET(
"/api/v1/pets/self/{petId}",
{
params: {
path: { petId: +data[0].petId },
},
}
);
console.log(data2);
if (data2) {
setPetData(data2);
setDevices(devices);

if (defaultDevice && defaultDevice.petId) {
const pet = await petApi.getPetById(defaultDevice.petId);
setPet(pet);
}
}
};

fetchData();
}, [deviceApi, petApi]);

console.log("loaded-devices", devices);

return (
<div className="container-fluid row p-5">
<div className="col-6">
{petData != null ? (
<img className="img-fluid" src={petImage} alt="pet name" />
) : (
<div>
<CreatePetModal />
</div>
)}
</div>
<div className="col-6">
<div className="h2 px-3 py-4">{petData.name}</div>
<div>
<div className="h5 px-3">HP</div>
<ProgressBar
className="px-1 pb-3"
hideText={true}
progressColor={"red"}
score={petData.state?.health == null ? 0 : petData.state.health}
/>
</div>
<div>
<div className="h5 px-3">Well-being</div>
<ProgressBar
className="px-1 pb-3"
hideText={true}
progressColor={"purple"}
score={
petData.state?.wellbeing == null ? 0 : petData.state.wellbeing
}
/>
</div>
<div>
<div className="h5 px-3">XP</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={"green"}
score={petData.state?.xp == null ? 0 : petData.state.xp}
/>
</div>
<div>
<div className="h5 px-3">Cleanliness</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={"green"}
score={
petData.state?.cleanliness == null ? 0 : petData.state.cleanliness
}
/>
</div>
<div>
<div className="h5 px-3">Fun</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={"green"}
score={petData.state?.fun == null ? 0 : petData.state.fun}
/>
</div>
<div>
<div className="h5 px-3">Hunger</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={"green"}
score={petData.state?.hunger == null ? 0 : petData.state.hunger}
/>
</div>
<div>
<div className="h5 px-3">Happiness</div>
<ProgressBar
className="px-1"
hideText={true}
progressColor={"green"}
score={
petData.state?.happiness == null ? 0 : petData.state.happiness
}
/>
</div>
</div>
{pet != undefined ? (
<PetDetails pet={pet} petImageSrc={petImage} />
) : (
<CreatePetModal />
)}
</div>
);
};
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/Components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import { 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";
Expand All @@ -17,9 +17,9 @@ function Settings(
setItems(items.filter((_, i) => i !== index));
};

const resetItem = (index: number) => {
setItems(items.map((item, i) => (i === index ? `Item ${index + 1}` : item)));
};
// 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'>
Expand Down
Loading

0 comments on commit 4e41ff0

Please sign in to comment.