1 Commits
Author SHA1 Message Date
JMR-dev e791becc52 added prettier and formatted code 2024-10-23 18:25:45 -06:00
24 changed files with 8678 additions and 4386 deletions
+3
View File
@@ -0,0 +1,3 @@
# Ignore artifacts:
build
coverage
+1
View File
@@ -0,0 +1 @@
{}
+8035 -3813
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -35,5 +35,8 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"prettier": "3.3.3"
} }
} }
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
+14 -19
View File
@@ -6,31 +6,26 @@ import { PhotosByTag } from "./tags/PhotosByTag";
import { MyImages } from "./images/MyImages"; import { MyImages } from "./images/MyImages";
import { Profile } from "./profile/Profile"; import { Profile } from "./profile/Profile";
export const ApplicationViews = () => { export const ApplicationViews = () => {
return (
return (
<> <>
<main>
<main>
<Route exact path="/"> <Route exact path="/">
<Home /> <Home />
</Route >
<Route path = "/SelectTags/:id">
<SelectTags />
</Route> </Route>
<Route exact path = "/PhotosByTag"> <Route path="/SelectTags/:id">
<PhotosByTag /> <SelectTags />
</Route>
<Route exact path="/PhotosByTag">
<PhotosByTag />
</Route> </Route>
<Route exact path="/Profile"> <Route exact path="/Profile">
<Profile /> <Profile />
</Route> </Route>
<Route exact path ="/MyImages" > <Route exact path="/MyImages">
<MyImages /> <MyImages />
</Route> </Route>
</main> </main>
</> </>
) );
} };
+28 -28
View File
@@ -1,30 +1,30 @@
import { Route, Redirect } from "react-router-dom" import { Route, Redirect } from "react-router-dom";
import { ApplicationViews } from "./ApplicationViews" import { ApplicationViews } from "./ApplicationViews";
import { NavBar } from "./nav/NavBar" import { NavBar } from "./nav/NavBar";
import { Login } from "./auth/Login" import { Login } from "./auth/Login";
import { Register } from "./auth/Register" import { Register } from "./auth/Register";
export const SmugFolio = () => { export const SmugFolio = () => {
if (localStorage.getItem("sf_token")) {
return (
<>
<Route>
<NavBar />
<ApplicationViews />
</Route>
</>
);
} else {
return (
<>
<Redirect to="/login" />
<Route path="/login">
<Login />
</Route>
if (localStorage.getItem("sf_token")) { <Route path="/register">
return( <Register />
<> </Route>
<Route> </>
<NavBar /> );
<ApplicationViews /> }
</Route> };
</>
)
} else {
return <>
<Redirect to="/login" />
<Route path="/login">
<Login />
</Route>
<Route path="/register">
<Register />
</Route>
</>
}
}
+85 -63
View File
@@ -1,68 +1,90 @@
import React, { useRef } from "react" import React, { useRef } from "react";
import { Link, useHistory } from "react-router-dom" import { Link, useHistory } from "react-router-dom";
export const Login = () => { export const Login = () => {
const username = useRef() const username = useRef();
const password = useRef() const password = useRef();
const invalidDialog = useRef() const invalidDialog = useRef();
const history = useHistory() const history = useHistory();
const handleLogin = (e) => { const handleLogin = (e) => {
e.preventDefault() e.preventDefault();
return fetch("http://127.0.0.1:8000/login", { return fetch("http://127.0.0.1:8000/login", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json" Accept: "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
username: username.current.value, username: username.current.value,
password: password.current.value password: password.current.value,
}) }),
}) })
.then(res => res.json()) .then((res) => res.json())
.then(res => { .then((res) => {
if ("valid" in res && res.valid && "token" in res) { if ("valid" in res && res.valid && "token" in res) {
localStorage.setItem("sf_token", res.token) localStorage.setItem("sf_token", res.token);
localStorage.setItem("smug_user_id",res.smug_user_id) localStorage.setItem("smug_user_id", res.smug_user_id);
history.push("/") history.push("/");
} } else {
else { invalidDialog.current.showModal();
invalidDialog.current.showModal() }
} });
}) };
}
return ( return (
<main className="container--login"> <main className="container--login">
<dialog className="dialog dialog--auth" ref={invalidDialog}> <dialog className="dialog dialog--auth" ref={invalidDialog}>
<div>Username or password was not valid.</div> <div>Username or password was not valid.</div>
<button className="button--close" onClick={e => invalidDialog.current.close()}>Close</button> <button
</dialog> className="button--close"
<section> onClick={(e) => invalidDialog.current.close()}
<form className="form--login" onSubmit={handleLogin}> >
<h1>SmugFolio</h1> Close
<h2>Please sign in</h2> </button>
<fieldset> </dialog>
<label htmlFor="inputUsername"> Username</label> <section>
<input ref={username} type="username" id="username" className="form-control" placeholder="Username" required autoFocus /> <form className="form--login" onSubmit={handleLogin}>
</fieldset> <h1>SmugFolio</h1>
<fieldset> <h2>Please sign in</h2>
<label htmlFor="inputPassword"> Password </label> <fieldset>
<input ref={password} type="password" id="password" className="form-control" placeholder="Password" required /> <label htmlFor="inputUsername"> Username</label>
</fieldset> <input
<fieldset style={{ ref={username}
textAlign: "center" type="username"
}}> id="username"
<button className="btn btn-1 btn-sep icon-send" type="submit">Sign In</button> className="form-control"
</fieldset> placeholder="Username"
</form> required
</section> autoFocus
<section className="link--register"> />
<Link to="/register">Register</Link> </fieldset>
</section> <fieldset>
</main> <label htmlFor="inputPassword"> Password </label>
) <input
} ref={password}
type="password"
id="password"
className="form-control"
placeholder="Password"
required
/>
</fieldset>
<fieldset
style={{
textAlign: "center",
}}
>
<button className="btn btn-1 btn-sep icon-send" type="submit">
Sign In
</button>
</fieldset>
</form>
</section>
<section className="link--register">
<Link to="/register">Register</Link>
</section>
</main>
);
};
+135 -85
View File
@@ -1,93 +1,143 @@
import React, { useRef } from "react" import React, { useRef } from "react";
import { Link, useHistory } from "react-router-dom" import { Link, useHistory } from "react-router-dom";
export const Register = () => { export const Register = () => {
const firstName = useRef() const firstName = useRef();
const lastName = useRef() const lastName = useRef();
const username = useRef() const username = useRef();
const email = useRef() const email = useRef();
const password = useRef() const password = useRef();
const verifyPassword = useRef() const verifyPassword = useRef();
const passwordDialog = useRef() const passwordDialog = useRef();
const history = useHistory() const history = useHistory();
const handleRegister = (e) => { const handleRegister = (e) => {
e.preventDefault() e.preventDefault();
if (password.current.value === verifyPassword.current.value) { if (password.current.value === verifyPassword.current.value) {
const newUser = { const newUser = {
"username": username.current.value, username: username.current.value,
"email": email.current.value, email: email.current.value,
"first_name": firstName.current.value, first_name: firstName.current.value,
"last_name": lastName.current.value, last_name: lastName.current.value,
"password": password.current.value password: password.current.value,
} };
return fetch("http://127.0.0.1:8000/register", { return fetch("http://127.0.0.1:8000/register", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json" Accept: "application/json",
}, },
body: JSON.stringify(newUser) body: JSON.stringify(newUser),
}) })
.then(res => res.json()) .then((res) => res.json())
.then(res => { .then((res) => {
if ("token" in res) { if ("token" in res) {
localStorage.setItem("sf_token", res.token) localStorage.setItem("sf_token", res.token);
localStorage.setItem("smug_user_id",res.smug_user) localStorage.setItem("smug_user_id", res.smug_user);
history.push("/") history.push("/");
} }
}) });
} else { } else {
passwordDialog.current.showModal() passwordDialog.current.showModal();
}
} }
};
return ( return (
<main style={{ textAlign: "center" }}> <main style={{ textAlign: "center" }}>
<dialog className="dialog dialog--password" ref={passwordDialog}>
<div>Passwords do not match</div>
<button
className="button--close"
onClick={(e) => passwordDialog.current.close()}
>
Close
</button>
</dialog>
<dialog className="dialog dialog--password" ref={passwordDialog}> <form className="form--login" onSubmit={handleRegister}>
<div>Passwords do not match</div> <h1 className="h3 mb-3 font-weight-normal">Register an account</h1>
<button className="button--close" onClick={e => passwordDialog.current.close()}>Close</button> <fieldset>
</dialog> <label htmlFor="firstName"> First Name </label>
<input
<form className="form--login" onSubmit={handleRegister}> ref={firstName}
<h1 className="h3 mb-3 font-weight-normal">Register an account</h1> type="text"
<fieldset> name="firstName"
<label htmlFor="firstName"> First Name </label> className="form-control"
<input ref={firstName} type="text" name="firstName" className="form-control" placeholder="First name" required autoFocus /> placeholder="First name"
</fieldset> required
<fieldset> autoFocus
<label htmlFor="lastName"> Last Name </label> />
<input ref={lastName} type="text" name="lastName" className="form-control" placeholder="Last name" required /> </fieldset>
</fieldset> <fieldset>
<fieldset> <label htmlFor="lastName"> Last Name </label>
<label htmlFor="inputUsername">Username</label> <input
<input ref={username} type="text" name="username" className="form-control" placeholder="Username" required /> ref={lastName}
</fieldset> type="text"
<fieldset> name="lastName"
<label htmlFor="inputEmail">Email</label> className="form-control"
<input ref={email} type="text" name="email" className="form-control" placeholder="Email" required /> placeholder="Last name"
</fieldset> required
<fieldset> />
<label htmlFor="inputPassword"> Password </label> </fieldset>
<input ref={password} type="password" name="password" className="form-control" placeholder="Password" required /> <fieldset>
</fieldset> <label htmlFor="inputUsername">Username</label>
<fieldset> <input
<label htmlFor="verifyPassword"> Verify Password </label> ref={username}
<input ref={verifyPassword} type="password" name="verifyPassword" className="form-control" placeholder="Verify password" required /> type="text"
</fieldset> name="username"
<fieldset style={{ className="form-control"
textAlign: "center" placeholder="Username"
}}> required
<button className="btn btn-1 btn-sep icon-send" type="submit">Register</button> />
</fieldset> </fieldset>
</form> <fieldset>
<section className="link--register"> <label htmlFor="inputEmail">Email</label>
Already registered? <Link to="/login">Login</Link> <input
</section> ref={email}
</main> type="text"
) name="email"
} className="form-control"
placeholder="Email"
required
/>
</fieldset>
<fieldset>
<label htmlFor="inputPassword"> Password </label>
<input
ref={password}
type="password"
name="password"
className="form-control"
placeholder="Password"
required
/>
</fieldset>
<fieldset>
<label htmlFor="verifyPassword"> Verify Password </label>
<input
ref={verifyPassword}
type="password"
name="verifyPassword"
className="form-control"
placeholder="Verify password"
required
/>
</fieldset>
<fieldset
style={{
textAlign: "center",
}}
>
<button className="btn btn-1 btn-sep icon-send" type="submit">
Register
</button>
</fieldset>
</form>
<section className="link--register">
Already registered? <Link to="/login">Login</Link>
</section>
</main>
);
};
+80 -75
View File
@@ -1,86 +1,91 @@
import React, {useState, useEffect} from "react"; import React, { useState, useEffect } from "react";
import { useHistory,useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { postImages, getImages } from "./HomeManager"; import { postImages, getImages } from "./HomeManager";
export const Home = () => { export const Home = () => {
const homeImages = useState([]) const homeImages = useState([]);
const { id } = useParams() const { id } = useParams();
const history = useHistory() const history = useHistory();
const[ businessImages, setbusinessImages] = useState([]) const [businessImages, setbusinessImages] = useState([]);
const [image, setImage] = useState({ const [image, setImage] = useState({
album_id: 0, album_id: 0,
picture:"" picture: "",
}) });
const [file_name, setfile_Name] = useState("") const [file_name, setfile_Name] = useState("");
const image1URL = "http://localhost:8000/media/smugimages/20140612-_JMR1361.jpg-5bbe21e5-19b0-4aae-b238-5c8791bc0b96.jpeg" const image1URL =
const image2URL = "http://localhost:8000/media/smugimages/20141224-_JMR5400.jpg-b7c8b0a6-33dc-4cd3-902b-a18538eb2283.jpeg" "http://localhost:8000/media/smugimages/20140612-_JMR1361.jpg-5bbe21e5-19b0-4aae-b238-5c8791bc0b96.jpeg";
const image3URL = "http://localhost:8000/media/smugimages/20140609-_JMR1159.jpg-fbcfa699-9136-4cb0-8e0a-a36694554af7.jpeg" const image2URL =
"http://localhost:8000/media/smugimages/20141224-_JMR5400.jpg-b7c8b0a6-33dc-4cd3-902b-a18538eb2283.jpeg";
const image3URL =
"http://localhost:8000/media/smugimages/20140609-_JMR1159.jpg-fbcfa699-9136-4cb0-8e0a-a36694554af7.jpeg";
useEffect( useEffect(() => {
() => { getImages().then((data) => setbusinessImages(data));
getImages().then(data => setbusinessImages(data)) }, []);
},[]
)
const getBase64 = (file, callback) => {
const reader = new FileReader();
reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(file);
};
const getBase64 = (file, callback) => { const createImageString = (event) => {
const reader = new FileReader(); let imageCopy = { ...image };
reader.addEventListener('load', () => callback(reader.result)); getBase64(event.target.files[0], (base64ImageString) => {
reader.readAsDataURL(file); imageCopy.picture = base64ImageString;
} setfile_Name(event.target.files[0].name);
setImage(imageCopy);
const createImageString = (event) => { console.log("Base64 of file is", base64ImageString);
let imageCopy = {...image}
getBase64(event.target.files[0], (base64ImageString) =>
{imageCopy.picture = base64ImageString
setfile_Name(event.target.files[0].name)
setImage(imageCopy)
console.log("Base64 of file is", base64ImageString);
// Update a component state variable to the value of base64ImageString
});
}
const resetFileNameOnUpload = (default_text) => { // Update a component state variable to the value of base64ImageString
let def_text = document.getElementById("image_upload") });
def_text.files[0].name = default_text };
} const resetFileNameOnUpload = (default_text) => {
const defaultImageState = let def_text = document.getElementById("image_upload");
{ def_text.files[0].name = default_text;
album_id:0, };
picture:"" const defaultImageState = {
} album_id: 0,
picture: "",
};
// this code meant to randomize the display images. First concentrate on getting your images to display. Then worry about limiting them and randomization. // this code meant to randomize the display images. First concentrate on getting your images to display. Then worry about limiting them and randomization.
// const randomizeDisplayImages = () => { // const randomizeDisplayImages = () => {
// let count = 0 // let count = 0
// do ( // do (
// for pic of businessImages // for pic of businessImages
// ) // )
// while count <= 3 // while count <= 3
// }
// }
return( return (
<> <>
<h1>SmugFolio</h1> <h1>SmugFolio</h1>
<input label="Browse for image file to upload" type="file" id="image_upload" onChange={createImageString} /> <input
<input type="hidden" name="image_id" value={image.id} /> label="Browse for image file to upload"
<button onClick={ type="file"
() => id="image_upload"
{ postImages(image, file_name) onChange={createImageString}
.then((image) => history.push(`/SelectTags/${image.id}`)) />
// code to rename the browse label. This is not working but should be done after other views are complete .then(setfile_Name("").then(resetFileNameOnUpload("No file chosen")) <input type="hidden" name="image_id" value={image.id} />
// Upload the stringified image that is stored in state <button
}}>Upload</button> onClick={() => {
<div> postImages(image, file_name).then((image) =>
<img src={image1URL} width={616} height={408} ></img> history.push(`/SelectTags/${image.id}`),
<img src={image2URL} width={616} height={408} ></img> );
<img src={image3URL} width={616} height={408} ></img> // code to rename the browse label. This is not working but should be done after other views are complete .then(setfile_Name("").then(resetFileNameOnUpload("No file chosen"))
</div> // Upload the stringified image that is stored in state
</> }}
) >
} Upload
</button>
<div>
<img src={image1URL} width={616} height={408}></img>
<img src={image2URL} width={616} height={408}></img>
<img src={image3URL} width={616} height={408}></img>
</div>
</>
);
};
+15 -19
View File
@@ -1,22 +1,18 @@
export const getImages = () => { export const getImages = () => {
return fetch("http://localhost:8000/images", { return fetch("http://localhost:8000/images", {
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}` Authorization: `Token ${localStorage.getItem("sf_token")}`,
} },
}) }).then((response) => response.json());
.then(response => response.json()) };
}
export const postImages = (image, file_name) => { export const postImages = (image, file_name) => {
return fetch(`http://localhost:8000/images?file_name=${file_name}`, { return fetch(`http://localhost:8000/images?file_name=${file_name}`, {
method: "POST", method: "POST",
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}`, Authorization: `Token ${localStorage.getItem("sf_token")}`,
"Content-Type": "application/json" "Content-Type": "application/json",
}, },
body:JSON.stringify(image), body: JSON.stringify(image),
} }).then((response) => response.json());
) };
.then(response => response.json())
}
+19 -27
View File
@@ -1,32 +1,24 @@
export const getImageData = () => { export const getImageData = () => {
return fetch(`http://localhost:8000/images`, { return fetch(`http://localhost:8000/images`, {
headers: { headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}` Authorization: `Token ${localStorage.getItem("sf_token")}`,
} },
}) }).then((response) => response.json());
.then(response => response.json()) };
}
export const getImages = (URL) => { export const getImages = (URL) => {
return fetch(`http://localhost:8000/${URL}`, { return fetch(`http://localhost:8000/${URL}`, {
headers: { headers: {
"Authorization": `Token ${ Authorization: `Token ${localStorage.getItem("sf_token")}`,
localStorage.getItem("sf_token") },
}` }).then((response) => response.json());
} };
}
)
.then(response => response.json())
}
export const deleteImage = (id) => { export const deleteImage = (id) => {
return fetch(`http://localhost:8000/images/${id}`, { return fetch(`http://localhost:8000/images/${id}`, {
method:"DELETE", method: "DELETE",
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}` Authorization: `Token ${localStorage.getItem("sf_token")}`,
} },
} });
) };
}
+38 -30
View File
@@ -1,36 +1,44 @@
import React, {useState, useEffect} from "react"; import React, { useState, useEffect } from "react";
import { useHistory,useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { getImages, getImageData, deleteImage } from "./MyImageManager"; import { getImages, getImageData, deleteImage } from "./MyImageManager";
export const MyImages = () => { export const MyImages = () => {
const [allImages, setAllImages] = useState([]) const [allImages, setAllImages] = useState([]);
const [ imageData, setImageData] = useState([]) const [imageData, setImageData] = useState([]);
const history = useHistory() const history = useHistory();
let { id } = useParams(); let { id } = useParams();
useEffect(() => {
getImageData().then((data) => setImageData(data));
}, []);
useEffect( return (
() => { <>
getImageData().then(data => setImageData(data)) <h2> My Images</h2>
},[] <div>
) {imageData.map((image) => {
return (
<>
return( <img
<> src={`http://localhost:8000${image.picture}`}
<h2> My Images</h2> key={image.id}
<div> width={616}
{imageData.map((image) =>{ height={408}
return ( />
<> <button
<img src={`http://localhost:8000${image.picture}`} key={image.id} width={616} height={408} /> onClick={() => {
<button onClick={() => {deleteImage(image.id).then(() => getImageData().then(data => setImageData(data)))}}> Delete Image</button> deleteImage(image.id).then(() =>
</> getImageData().then((data) => setImageData(data)),
) );
} }}
)} >
</div> {" "}
Delete Image
</button>
</>
);
})}
</div>
</> </>
) );
} };
+3 -3
View File
@@ -1,13 +1,13 @@
body { body {
margin: 0; margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif; sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
code { code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace; monospace;
} }
+8 -8
View File
@@ -1,17 +1,17 @@
import React from 'react'; import React from "react";
import ReactDOM from 'react-dom'; import ReactDOM from "react-dom";
import './index.css'; import "./index.css";
import reportWebVitals from './reportWebVitals'; import reportWebVitals from "./reportWebVitals";
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter as Router } from "react-router-dom";
import { SmugFolio } from './SmugFolio'; import { SmugFolio } from "./SmugFolio";
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
<Router> <Router>
<SmugFolio/> <SmugFolio />
</Router> </Router>
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root') document.getElementById("root"),
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function
+46 -40
View File
@@ -1,42 +1,48 @@
import React from "react" import React from "react";
import { Link, useHistory } from "react-router-dom" import { Link, useHistory } from "react-router-dom";
export const NavBar = () => { export const NavBar = () => {
const history = useHistory() const history = useHistory();
return ( return (
<ul className="navbar">
<ul className="navbar"> <li className="navbar__item">
<li className="navbar__item"> <Link to={"/"}>Upload Images</Link>
<Link to={ "/"} >Upload Images</Link> </li>
</li> <li className="navbar__item">
<li className="navbar__item"> <Link to={"/MyImages"}>My Images</Link>
<Link to={"/MyImages"}>My Images</Link> </li>
</li> <li className="navbar__item">
<li className="navbar__item"> <Link to={"/PhotosByTag"}> Explore Images by Tag</Link>
<Link to={"/PhotosByTag"}> Explore Images by Tag</Link> </li>
</li> <li className="navbar__item">
<li className="navbar__item"> <Link to={"/Profile"}>My Profile</Link>
<Link to={"/Profile"}>My Profile</Link> </li>
</li> {localStorage.getItem("sf_token") !== null ? (
{ <li className="nav-item">
(localStorage.getItem("sf_token") !== null) ? <button
<li className="nav-item"> className="nav-link fakeLink"
<button className="nav-link fakeLink" onClick={() => {
onClick={() => { localStorage.removeItem("sf_token");
localStorage.removeItem("sf_token") history.push({ pathname: "/login" });
history.push({ pathname: "/login" }) }}
}} >
>Logout</button> Logout
</li> : </button>
<> </li>
<li className="nav-item"> ) : (
<Link className="nav-link" to="/login">Login</Link> <>
</li> <li className="nav-item">
<li className="nav-item"> <Link className="nav-link" to="/login">
<Link className="nav-link" to="/register">Register</Link> Login
</li> </Link>
</> </li>
} </ul> <li className="nav-item">
) <Link className="nav-link" to="/register">
} Register
</Link>
</li>
</>
)}{" "}
</ul>
);
};
+10 -17
View File
@@ -1,22 +1,15 @@
import React, {useState, useEffect} from "react"; import React, { useState, useEffect } from "react";
import { useHistory,useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { getSmug_UserById, putSmug_User } from "./ProfileManager"; import { getSmug_UserById, putSmug_User } from "./ProfileManager";
export const EditProfile = () => { export const EditProfile = () => {
const { id } = useParams() const { id } = useParams();
const history = useHistory() const history = useHistory();
const [ usertoedit, setusertoedit] = useState({}) const [usertoedit, setusertoedit] = useState({});
useEffect( useEffect(() => {
() => { getSmug_UserById().then((data) => setusertoedit(data));
getSmug_UserById().then(data => setusertoedit(data)) }, []);
},[]
)
return ( return <form></form>;
<form> };
</form>
)
}
+28 -22
View File
@@ -1,28 +1,34 @@
import React, {useState, useEffect} from "react"; import React, { useState, useEffect } from "react";
import { useHistory,useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { getSmug_UserById } from "./ProfileManager"; import { getSmug_UserById } from "./ProfileManager";
export const Profile = () => { export const Profile = () => {
const [currentuser, setcurrentuser] = useState(localStorage.getItem("smug_user_id")) const [currentuser, setcurrentuser] = useState(
const [smug_user, setsmuguser] = useState({}) localStorage.getItem("smug_user_id"),
);
const [smug_user, setsmuguser] = useState({});
useEffect( useEffect(() => {
() => { getSmug_UserById(currentuser).then((data) => setsmuguser(data));
getSmug_UserById(currentuser).then(data => setsmuguser(data)) }, []);
},[] // How to filter a user by their uid? Not quite sure
) return (
// How to filter a user by their uid? Not quite sure
return (
<> <>
<h2>My Profile</h2> <h2>My Profile</h2>
<div> <div>
<p> Username: {smug_user.user.username}</p> <p> Username: {smug_user.user.username}</p>
<p> Email: {smug_user.user.email}</p> <p> Email: {smug_user.user.email}</p>
<p> Name: {smug_user.user.first_name} {smug_user.user.last_name}</p> <p>
<p>{smug_user.business_owner ? "Current user is business owner" : "Current user is a standard user"}</p> {" "}
<p> User is staff? {smug_user.user.is_staff ? "Yes" : "No"}</p> Name: {smug_user.user.first_name} {smug_user.user.last_name}
</p>
</div> <p>
{smug_user.business_owner
? "Current user is business owner"
: "Current user is a standard user"}
</p>
<p> User is staff? {smug_user.user.is_staff ? "Yes" : "No"}</p>
</div>
</> </>
) );
} };
+15 -19
View File
@@ -1,22 +1,18 @@
export const getSmug_UserById = (id) => { export const getSmug_UserById = (id) => {
return fetch(`http://localhost:8000/smug_users/${id}`, { return fetch(`http://localhost:8000/smug_users/${id}`, {
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}` Authorization: `Token ${localStorage.getItem("sf_token")}`,
} },
}) }).then((response) => response.json());
.then(response => response.json()) };
}
export const putSmug_User = (editedProfile) => { export const putSmug_User = (editedProfile) => {
return fetch(`http://localhost:8000/games/${editedProfile.id}`, { return fetch(`http://localhost:8000/games/${editedProfile.id}`, {
method: "PUT", method: "PUT",
body: JSON.stringify( body: JSON.stringify(editedProfile),
editedProfile headers: {
), Authorization: `Token ${localStorage.getItem("sf_token")}`,
headers:{ "Content-Type": "Application/json",
"Authorization": `Token ${localStorage.getItem("sf_token")}`, },
"Content-Type": "Application/json" });
} };
}
)
}
+2 -2
View File
@@ -1,6 +1,6 @@
const reportWebVitals = onPerfEntry => { const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) { if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry); getCLS(onPerfEntry);
getFID(onPerfEntry); getFID(onPerfEntry);
getFCP(onPerfEntry); getFCP(onPerfEntry);
+1 -1
View File
@@ -2,4 +2,4 @@
// allows you to do things like: // allows you to do things like:
// expect(element).toHaveTextContent(/react/i) // expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom // learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom'; import "@testing-library/jest-dom";
+27 -27
View File
@@ -1,33 +1,33 @@
import React, {useState, useEffect} from "react"; import React, { useState, useEffect } from "react";
import { useHistory,useParams } from "react-router-dom"; import { useHistory, useParams } from "react-router-dom";
import { getImageData } from "../images/MyImageManager"; import { getImageData } from "../images/MyImageManager";
import { getTags } from "./TagManager"; import { getTags } from "./TagManager";
export const PhotosByTag = () => { export const PhotosByTag = () => {
const [ imageData, setImageData] = useState([]) const [imageData, setImageData] = useState([]);
const [ tagdata, settagdata ] = useState([]) const [tagdata, settagdata] = useState([]);
useEffect( useEffect(() => {
() => { getImageData().then((data) => setImageData(data));
getImageData().then(data => setImageData(data)) }, []);
},[]
)
return( return (
<> <>
<div> <div>
{imageData.map((image) =>{ {imageData.map((image) => {
return ( return (
// <p> {tagdata.map((tag)=> tag.image_tag_name )} </p> // <p> {tagdata.map((tag)=> tag.image_tag_name )} </p>
<> <>
<img
<img src={`http://localhost:8000${image.picture}`} key={image.id} width={616} height={408} /> src={`http://localhost:8000${image.picture}`}
key={image.id}
</> width={616}
) height={408}
} />
)} </>
</div> );
</> })}
) </div>
} </>
);
};
+56 -55
View File
@@ -1,60 +1,61 @@
import react, {useState, useEffect, useRef} from "react" import react, { useState, useEffect, useRef } from "react";
import { useHistory, useParams } from "react-router-dom" import { useHistory, useParams } from "react-router-dom";
import { getTags, addTagsToImages } from "./TagManager" import { getTags, addTagsToImages } from "./TagManager";
export const SelectTags = () => { export const SelectTags = () => {
const [tags, setTags] = useState([]) const [tags, setTags] = useState([]);
const [tag_selections, setTagSelections] = useState( new Array(tags.length).fill(0)) const [tag_selections, setTagSelections] = useState(
let { id } = useParams(); new Array(tags.length).fill(0),
const tagscopy = [...tags] );
let { id } = useParams();
useEffect( const tagscopy = [...tags];
() => {
getTags().then(data => setTags(data))
},[]
)
const changefunction = (e) => { useEffect(() => {
const checkboxID = e.target.value getTags().then((data) => setTags(data));
let tagselectioncopy = [...tag_selections] }, []);
if (tagselectioncopy.find((id) => id === checkboxID)) {
tagselectioncopy = tagselectioncopy.filter((id) => id !== checkboxID)
setTagSelections(tagselectioncopy)
} else {tagselectioncopy.push(checkboxID)
setTagSelections(tagselectioncopy)
}
}
return( const changefunction = (e) => {
<> const checkboxID = e.target.value;
<h2>Select Tags for Images</h2> let tagselectioncopy = [...tag_selections];
if (tagselectioncopy.find((id) => id === checkboxID)) {
tagselectioncopy = tagselectioncopy.filter((id) => id !== checkboxID);
setTagSelections(tagselectioncopy);
} else {
tagselectioncopy.push(checkboxID);
setTagSelections(tagselectioncopy);
}
};
<div> return (
<>
{tagscopy.map((tagname) => { <h2>Select Tags for Images</h2>
return(
<> <div>
<input type="checkbox" name="imagetags" value={tagname.id} id= "imagetags" onChange={ {tagscopy.map((tagname) => {
(e) => {changefunction(e) } return (
} /> <>
<label for="imagetags">{tagname.image_tag_name}</label> <input
</> type="checkbox"
) name="imagetags"
} value={tagname.id}
) id="imagetags"
onChange={(e) => {
} changefunction(e);
< button onClick = { }}
() => { />
const submitOBJ = {image_tags:tag_selections} <label for="imagetags">{tagname.image_tag_name}</label>
addTagsToImages( submitOBJ, id) </>
} );
} })}
<button
onClick={() => {
>Submit</button> const submitOBJ = { image_tags: tag_selections };
</div> addTagsToImages(submitOBJ, id);
}}
</> >
) Submit
} </button>
</div>
</>
);
};
+25 -32
View File
@@ -1,36 +1,29 @@
export const getTags = () => { export const getTags = () => {
return fetch("http://localhost:8000/image_tags", { return fetch("http://localhost:8000/image_tags", {
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}` Authorization: `Token ${localStorage.getItem("sf_token")}`,
} },
}) }).then((response) => response.json());
.then(response => response.json()) };
}
export const createTags = (tag) => { export const createTags = (tag) => {
return fetch(`http://localhost:8000/image_tags`, { return fetch(`http://localhost:8000/image_tags`, {
method: "POST", method: "POST",
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}`, Authorization: `Token ${localStorage.getItem("sf_token")}`,
"Content-Type": "Application/json" "Content-Type": "Application/json",
}, },
body:JSON.stringify(tag) body: JSON.stringify(tag),
} }).then((response) => response.json());
};
)
.then(response => response.json())
}
export const addTagsToImages = (tag_selections,id) => { export const addTagsToImages = (tag_selections, id) => {
return fetch(`http://localhost:8000/images/${id}`, { return fetch(`http://localhost:8000/images/${id}`, {
method: "PUT", method: "PUT",
headers:{ headers: {
"Authorization": `Token ${localStorage.getItem("sf_token")}`, Authorization: `Token ${localStorage.getItem("sf_token")}`,
"Content-Type": "Application/json" "Content-Type": "Application/json",
}, },
body:JSON.stringify(tag_selections) body: JSON.stringify(tag_selections),
} });
) };
}