Skip to content

Commit

Permalink
Likes, Sudo Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtyson123 committed May 5, 2024
1 parent e9ae050 commit b43b308
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 6 deletions.
10 changes: 10 additions & 0 deletions server/my_sql/create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,13 @@ CREATE TABLE IF NOT EXISTS posts (
FOREIGN KEY (post_plant_id) REFERENCES plants(id),
FOREIGN KEY (post_user_id) REFERENCES users(id)
);

-- Likes
CREATE TABLE IF NOT EXISTS likes (
id INT NOT NULL AUTO_INCREMENT,
like_post_id INT,
like_user_id INT,
PRIMARY KEY (id),
FOREIGN KEY (like_post_id) REFERENCES posts(id),
FOREIGN KEY (like_user_id) REFERENCES users(id)
);
4 changes: 4 additions & 0 deletions website/public/media/images/Liked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions website/src/lib/databse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ export class SQLDatabase {
post_date: string;
post_image: string;

// Likes Table
like_post_id: string;
like_user_id: string;


constructor() {
this.database = "rongoa8jwons3_rongoadb"
Expand Down Expand Up @@ -187,6 +191,10 @@ export class SQLDatabase {
this.post_date = "post_date";
this.post_image = "post_image";


// Likes Table
this.like_post_id = "like_post_id";
this.like_user_id = "like_user_id";
}
}

Expand Down
35 changes: 33 additions & 2 deletions website/src/pages/admin/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ import {useSession} from "next-auth/react";
import {makeRequestWithToken} from "@/lib/api_tools";
import {globalStyles} from "@/lib/global_css";
import { useLogger } from 'next-axiom';
import {FileInput, ValidationState} from "@/components/input_sections";
import {FileInput, SmallInput, ValidationState} from "@/components/input_sections";
import {useRouter} from "next/router";
import {Layout} from "@/components/layout";
import {RongoaUser, UserDatabaseDetails} from "@/lib/users";

export default function Admin(){
const pageName = "Admin";
const log = useLogger();
const router = useRouter()
const { data: session } = useSession()
const { data: session, update } = useSession()

// Back up file
const [fileError, setFileError] = useState<string>("");
const [fileState, setFileState] = useState<ValidationState>("normal");
const [userId, setUserId] = useState<string>("");

// Load the data
const [loadingMessage, setLoadingMessage] = useState("")
Expand Down Expand Up @@ -119,6 +121,31 @@ export default function Admin(){
window.location.reload()
}

const submitSudo = async () => {

// Get the user data
const user = await makeRequestWithToken('get', `/api/user/data?id=${userId}`)
const userData = user.data.data as UserDatabaseDetails

// Set the session
await update({
database: {
id: userData.id,
user_name: userData.user_name,
user_email: userData.user_email,
user_image: userData.user_image,
user_type: userData.user_type,
user_last_login: userData.user_last_login,
user_restricted_access: userData.user_restricted_access

}
}).then(r => console.log(r))

// Redirect to the account page
await router.push("/account")

}

return (
<>
<Layout pageName={pageName} loadingMessage={loadingMessage} error={error} loginRequired header={"Settings"} permissionRequired={"pages:admin:publicAccess"}>
Expand Down Expand Up @@ -158,6 +185,10 @@ export default function Admin(){

<h3> Import Back Up </h3>
<FileInput required={false} state={fileState} errorText={fileError} changeEventHandler={setFile} placeHolder={"Back Up File"}/>

<h1> Sudo Mode</h1>
<SmallInput placeHolder={"User ID"} required={true} state={"normal"} changeEventHandler={setUserId}/>
<button onClick={submitSudo}>Submit</button>
</div>
</div>
</div>
Expand Down
88 changes: 88 additions & 0 deletions website/src/pages/api/posts/likes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {NextApiRequest, NextApiResponse} from 'next';
import {getClient, getTables, makeQuery} from "@/lib/databse";
import {getServerSession} from "next-auth";
import {authOptions} from "@/pages/api/auth/[...nextauth]";
import {checkApiPermissions} from "@/lib/api_tools";
import {getStrings, RongoaUser} from "@/lib/users";
import { Logger } from 'next-axiom';
export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {

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

// Get the logger
const logger = new Logger()

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

// Check if the user is permitted to access the API
const session = await getServerSession(request, response, authOptions)
let permission = await checkApiPermissions(request, response, session, client, makeQuery, "api:user:follow:access")
if (!permission) return response.status(401).json({error: "Not Authorized"})

let query = ''

const {id, publicUserID} = request.query;

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 = session.user as RongoaUser;
const userId = user.database.id;

// Get the operation
const {operation, id} = request.query;
if (!operation) {
return response.status(400).json({error: 'No operation specified'});
}

switch (operation) {

case "likes":
query = `SELECT COUNT(*) FROM likes WHERE ${tables.like_post_id} = ${id}`;
break;

case "like":
query = `INSERT INTO likes (${tables.like_user_id}, ${tables.like_post_id}) VALUES (${userId}, ${id})`;
break;

case "unlike":
query = `DELETE FROM likes WHERE ${tables.like_user_id} = ${userId} AND ${tables.like_post_id} = ${id}`;
break;

case "check":
query = `SELECT COUNT(*) FROM likes WHERE ${tables.like_user_id} = ${userId} AND ${tables.like_post_id} = ${id}`;
break;

case "list":
query = `SELECT * FROM likes WHERE ${tables.like_user_id} = ${userId}`;
break;

default:
return response.status(400).json({error: 'Invalid operation'});

}

const follow = await makeQuery(query, client)
return response.status(200).json({data: follow});

// Execute the query


} catch (e : any) {
logger.error(e)
return response.status(500).json({error: 'Internal Server Error'})
}
}
34 changes: 31 additions & 3 deletions website/src/pages/media/components/cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function PostCard(props: PostCardProps) {
const [likes, setLikes] = useState(0)
const [plantName, setPlantName] = useState("Loading...")
const [width, setWidth] = useState(0)
const [liked, setLiked] = useState(false)

const router = useRouter();
const dataFetch = useRef(false);
Expand Down Expand Up @@ -116,7 +117,14 @@ export function PostCard(props: PostCardProps) {
}

// Get the likes
//todo
const likes = await makeRequestWithToken("get", `/api/posts/likes?operation=likes&id=${props.id}`);
setLikes(likes.data.data[0]["COUNT(*)"]);

// Check if the user has liked the post
const liked = await makeRequestWithToken("get", `/api/posts/likes?operation=check&id=${props.id}`);
if(liked.data.data[0]["COUNT(*)"] > 0) {
setLiked(true);
}

}

Expand All @@ -126,6 +134,26 @@ export function PostCard(props: PostCardProps) {
router.push("/media/profile?id="+props.post_user_id)
}

const likePost = async () => {
await makeRequestWithToken("post", `/api/posts/likes?operation=like&id=${props.id}`);
}

const unlikePost = async () => {
await makeRequestWithToken("post", `/api/posts/likes?operation=unlike&id=${props.id}`);
}

const toggleLike = async () => {
if(liked) {
setLiked(false);
await unlikePost();
setLikes(likes - 1);
} else {
setLiked(true);
await likePost();
setLikes(likes + 1);
}
}

return(
<>
<div className={stlyes.post} style={{width: width}}>
Expand All @@ -151,8 +179,8 @@ export function PostCard(props: PostCardProps) {
</div>
<div className={stlyes.postFooter}>
<img src="/media/images/Share.svg" alt="Share"/>
<button>
<img src="/media/images/Like.svg" alt="Comment"/>
<button onClick={toggleLike}>
<img src={liked ? "/media/images/Liked.svg" : "/media/images/Like.svg"} alt="Comment"/>
<p>{likes}</p>
</button>
<button onClick={() => {router.push("/plants/"+props.post_plant_id)}}>
Expand Down
2 changes: 1 addition & 1 deletion website/src/pages/media/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default function Page(){
<p>Posts</p>
{searchResults.posts.map((post: any, index: number) => {
return (
<div>
<div key={index}>
<PostCardApi id={post.id}/>
</div>
)
Expand Down

0 comments on commit b43b308

Please sign in to comment.