Skip to content

Commit

Permalink
Account Information
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtyson123 committed Nov 7, 2023
1 parent 34357b2 commit 9840ab9
Show file tree
Hide file tree
Showing 23 changed files with 455 additions and 14 deletions.
30 changes: 30 additions & 0 deletions website/src/components/dropdown_section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {useState} from "react";
import styles from "@/styles/components/dropdown_section.module.css";

interface DropdownSectionProps {
title: string;
children: React.ReactNode;
open?: boolean;
}


export function DropdownSection({title, children, open = false}: DropdownSectionProps){

const [opened, setOpened] = useState(open)


return(

<>
<div className={styles.titleBar}>
<h1 className={styles.title}>{title}</h1>
<button className={styles.button} onClick={() => setOpened(!opened)}> {opened ? "Close" : "Open"}</button>
</div>
<div className={styles.content + " " + (opened ? styles.open : styles.closed)}>
{opened && children}
</div>
</>

)

}
2 changes: 1 addition & 1 deletion website/src/components/stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default function Stats(){
}, []);

const goToIndex = (filter: string) => {
router.push("/plant_index?filter=" + filter)
router.push("/plants/plant_index?filter=" + filter)
}


Expand Down
22 changes: 21 additions & 1 deletion website/src/lib/users.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import {User} from "next-auth";

export const ADMIN_USER_TYPE = 0;
export const EDITOR_USER_TYPE = 1;
export const MEMBER_USER_TYPE = 2;

export const UNDEFINED_USER_TYPE = -1;
export const UNDEFINED_USER_TYPE = -1;

export interface RongoaUser extends User{

database: UserDatabaseDetails

}

export interface UserDatabaseDetails {

id: number,
user_name: string,
user_email: string,
user_type: number,
user_last_login: string,
user_api_keys: object,


}
218 changes: 218 additions & 0 deletions website/src/pages/account/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import HtmlHeader from "@/components/html_header";
import Navbar from "@/components/navbar";
import React, {useEffect, useRef} from "react";
import Section from "@/components/section";
import Footer from "@/components/footer";
import PageHeader from "@/components/page_header";
import styles from "@/styles/pages/account/index.module.css"
import statsStyles from "@/styles/components/stats.module.css"
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faCamera, faPerson, faSeedling} from "@fortawesome/free-solid-svg-icons";
import {signIn, signOut, useSession} from "next-auth/react";
import {ADMIN_USER_TYPE, EDITOR_USER_TYPE, MEMBER_USER_TYPE, RongoaUser} from "@/lib/users";
import axios from "axios";
import Image from "next/image";
import {globalStyles} from "@/lib/global_css";
import {DropdownSection} from "@/components/dropdown_section";
import {useRouter} from "next/router";

export default function Account() {

const pageName = "Account";

const { data: session } = useSession()

const router = useRouter()

const [userName, setUserName] = React.useState<string | null | undefined>("")
const [userEmail, setUserEmail] = React.useState<string | null | undefined>("")
const [userRole, setUserRole] = React.useState<string | null | undefined>("")
const [userImage, setUserImage] = React.useState<string | null | undefined>("")
const [userLastLogin, setUserLastLogin] = React.useState<string | null | undefined>("")
const [userPlants, setUserPlants] = React.useState<string | null | undefined>("")
const [userPosts, setUserPosts] = React.useState<string | null | undefined>("")
const [userPlantsData, setUserPlantsData] = React.useState(null)



// Don't fetch the data again if it has already been fetched
const dataFetch = useRef(false)


useEffect(() => {

// If there is session data
if(session?.user) {

let user = session.user as RongoaUser
if(!user) return

setUserName(user.name)
setUserEmail(user.email)
switch (user.database.user_type){
case MEMBER_USER_TYPE:
setUserRole("Member")
break

case ADMIN_USER_TYPE:
setUserRole("Admin")
break

case EDITOR_USER_TYPE:
setUserRole("Editor")
break
}
setUserImage(user.image)
setUserLastLogin(user.database.user_last_login.split("T")[0])
setUserPosts("0")

// Prevent the data from being fetched again
if (dataFetch.current)
return
dataFetch.current = true

// Get the users data
fetchData()

}

}, [session])


const fetchData = async () => {


// Get the users plants
try {
const plants = await axios.get("/api/user/plants/")
if(!plants.data.error){
setUserPlants(plants.data.data.length.toString())
}
setUserPlantsData(plants.data.data)
} catch (e) {
console.log(e)
setUserPlants("0")
}
}

const signOutUser = async () => {
await signOut()
await router.push("/")
}

const deleteAccount = async () => {
await axios.delete("/api/user/delete/")
await signOutUser()
}


return(

<>

{/* Set up the page header and navbar */}
<HtmlHeader currentPage={pageName}/>
<Navbar currentPage={pageName}/>


{/* Header for the page */}
<Section>
<PageHeader size={"small"}>
<div className={styles.welcomeContainer}>
<h1>Your Account</h1>
</div>
</PageHeader>
</Section>

{ !session ?
<>
<div className={globalStyles.gridCentre}>
<button className={styles.signInButton} onClick={() => signIn()}><FontAwesomeIcon icon={faPerson}/> Sign in</button>
</div>
</>
:
<>
{/* Users Information */}
<Section autoPadding>
<div className={globalStyles.gridCentre}>
<div className={styles.accountContainer}>

<div className={styles.lastLogin}>
<p> Last Login: {userLastLogin} </p>
</div>

<div className={styles.mainInfo}>
<div className={styles.accountImage}>
<Image src={userImage ? userImage.replaceAll("s96-c", "s192-c") : "/media/images/logo.svg"} alt={userName ? userName : ""} fill={true}/>
</div>
<h1> {userName}</h1>
<h2> {userEmail}</h2>
<h2> {userRole}</h2>
</div>

<div className={statsStyles.statsRowContainer + " " + statsStyles.twoCols}>

{/* Each stat is a div with the number central and the icon and value inline */}
<div className={statsStyles.stat}>
<h2> {userPlants}</h2>
<FontAwesomeIcon icon={faSeedling} className={statsStyles.inline}/>
<p className={statsStyles.inline}> Plants </p>
</div>

{/* Each stat is a div with the number central and the icon and value inline */}
<div className={statsStyles.stat}>
<h2> N/A </h2>
<FontAwesomeIcon icon={faCamera} className={statsStyles.inline}/>
<p className={statsStyles.inline}> Posts </p>
</div>

</div>
</div>
</div>

</Section>

{/* Users Plants */}
<Section autoPadding>
<DropdownSection title={"Plants Created"} open>
<div><p>asd</p></div>
</DropdownSection>
</Section>

{/* Users Posts */}
<Section autoPadding>
<DropdownSection title={"Posts"} open>
<div><p>asd</p></div>
</DropdownSection>
</Section>

{/* Users Api Keys */}
<Section autoPadding>
<DropdownSection title={"Api Keys"} open>
<div><p>asd</p></div>
</DropdownSection>
</Section>

{/* Actions */}
<Section autoPadding>
<div className={globalStyles.gridCentre}>

<div className={styles.actionItem}>
<button onClick={signOutUser} className={styles.signOutButton}>Sign Out</button>
</div>

<div className={styles.actionItem}>
<button onClick={deleteAccount} className={styles.deleteAccountButton}>Delete Account</button>
</div>
</div>
</Section>
</>
}
{/* Footer */}
<Section>
<Footer/>
</Section>
</>

)
}
2 changes: 1 addition & 1 deletion website/src/pages/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Section from "@/components/section";
import Footer from "@/components/footer";
import ScrollToTop from "@/components/scroll_to_top";
import PageHeader from "@/components/page_header";
import styles from "@/styles/admin.module.css";
import styles from "@/styles/pages/admin.module.css";
import {signIn, signOut, useSession} from "next-auth/react";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faDoorOpen, faPerson} from "@fortawesome/free-solid-svg-icons";
Expand Down
51 changes: 51 additions & 0 deletions website/src/pages/api/user/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {NextApiRequest, NextApiResponse} from 'next';
import {getClient, getTables} from "@/lib/databse";
import {GetOrigin} from "@/lib/api_tools";
import {getServerSession} from "next-auth";
import {authOptions} from "@/pages/api/auth/[...nextauth]";

export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {

// Get the origin of the request
const origin = GetOrigin(request);

// Get the client
const client = await getClient()

// Get the tables
const tables = getTables();

try {

// Get the session
const session = await getServerSession(request, response, authOptions)

// If there is no session then return an error
if(!session || !session.user) {
return response.status(401).json({ error: 'User not logged in'});
}

// Get the user details
const user_email = session.user.email;
const user_name = session.user.name;

// Remove the user
let query = `DELETE FROM users WHERE ${tables.user_email} = '${user_email}' AND ${tables.user_name} = '${user_name}'`;
console.log(query);
const removed = await client.query(query);

// Return the user
return response.status(200).json({removed: removed.affectedRows});


} catch (error) {
console.log("Error");
console.log(error);

// If there is an error, return the error
return response.status(500).json({ error: error });
}
}
2 changes: 1 addition & 1 deletion website/src/pages/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Section from "@/components/section";
import Footer from "@/components/footer";
import ScrollToTop from "@/components/scroll_to_top";
import PageHeader from "@/components/page_header";
import styles from "@/styles/calendar.module.css";
import styles from "@/styles/pages/calendar.module.css";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faArrowLeft, faArrowRight} from "@fortawesome/free-solid-svg-icons";
import {MONTHS, USE_POSTGRES} from "@/lib/constants"
Expand Down
2 changes: 1 addition & 1 deletion website/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import React, {useEffect, useRef} from "react";

import styles from "@/styles/index.module.css"
import styles from "@/styles/pages/index.module.css"
import Navbar from "@/components/navbar";
import HtmlHeader from "@/components/html_header";
import Section from "@/components/section";
Expand Down
2 changes: 1 addition & 1 deletion website/src/pages/plants/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Navbar from "@/components/navbar";
import PageHeader from "@/components/page_header";
import ScrollToTop from "@/components/scroll_to_top";
import {fetchPlant, getNamesInPreference, ImageMetaData, PlantData} from "@/lib/plant_data";
import styles from "@/styles/plants/id.module.css";
import styles from "@/styles/pages/plants/id.module.css";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faArrowLeft, faArrowRight} from "@fortawesome/free-solid-svg-icons";
import {convertUseTag} from "@/components/plant_card";
Expand Down
Loading

1 comment on commit 9840ab9

@vercel
Copy link

@vercel vercel bot commented on 9840ab9 Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.