user route for getting friendships
This commit is contained in:
17
client/src/components/derived/Friends.tsx
Normal file
17
client/src/components/derived/Friends.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { useEffect } from "react";
|
||||||
|
import { useAuthContext } from "../../context/AuthContext";
|
||||||
|
import { Panel } from "../ui";
|
||||||
|
|
||||||
|
export default function Friends() {
|
||||||
|
const { user } = useAuthContext();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Panel>
|
||||||
|
|
||||||
|
</Panel>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
|
import Protect from "../../util/Protect";
|
||||||
import { Button, Page } from "../ui";
|
import { Button, Page } from "../ui";
|
||||||
|
|
||||||
export default function Browser() {
|
export default function Browser() {
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Protect>
|
||||||
<h1>Search recipes</h1>
|
<h1>Search recipes</h1>
|
||||||
<div>
|
<div>
|
||||||
<input type="text"></input>
|
<input type="text"></input>
|
||||||
@@ -12,6 +13,6 @@ export default function Browser() {
|
|||||||
{/* divider */}
|
{/* divider */}
|
||||||
|
|
||||||
{/* recipe cards, or "no recipes matching your search" */}
|
{/* recipe cards, or "no recipes matching your search" */}
|
||||||
</Page>
|
</Protect>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -7,13 +7,14 @@ import Protect from "../../util/Protect";
|
|||||||
|
|
||||||
export default function Profile() {
|
export default function Profile() {
|
||||||
const [message, setMessage] = useState<JSX.Element>();
|
const [message, setMessage] = useState<JSX.Element>();
|
||||||
const { user } = useContext(AuthContext);
|
// const { user } = useAuthContext();
|
||||||
|
const { user } = useAuthContext();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Protect>
|
<Protect>
|
||||||
<div className="profile-authenticated">
|
<div className="profile-authenticated">
|
||||||
<h1>{user!.firstname}'s Profile</h1>
|
<h1>{user?.firstname}'s Profile</h1>
|
||||||
<p>Things and stuff!</p>
|
<p>Things and stuff!</p>
|
||||||
</div>
|
</div>
|
||||||
</Protect>
|
</Protect>
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default class Constructor {
|
||||||
|
|
||||||
|
}
|
||||||
13
client/src/components/pages/Subscriptions/Subscriptions.tsx
Normal file
13
client/src/components/pages/Subscriptions/Subscriptions.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { useContext } from "react";
|
||||||
|
import { useAuthContext } from "../../../context/AuthContext";
|
||||||
|
import Protect from "../../../util/Protect";
|
||||||
|
|
||||||
|
export default function Subscriptions() {
|
||||||
|
const { user } = useAuthContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Protect>
|
||||||
|
<h1>{user?.firstname}'s Subscriptions</h1>
|
||||||
|
</Protect>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import Button from "./Button";
|
|||||||
import "/src/sass/components/Navbar.scss";
|
import "/src/sass/components/Navbar.scss";
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useAuthContext();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const navbarLoggedIn = (
|
const navbarLoggedIn = (
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { Button, Page } from "../components/ui";
|
import { Button, Page } from "../components/ui";
|
||||||
import Divider from "../components/ui/Divider";
|
import Divider from "../components/ui/Divider";
|
||||||
import { AuthContext } from "../context/AuthContext";
|
import { AuthContext } from "../context/AuthContext";
|
||||||
|
import { ProtectPortal } from "./types";
|
||||||
|
|
||||||
export default function Protect({ children = <></> }) {
|
const Protect: ProtectPortal = ({ children = <></> }) => {
|
||||||
const { user } = useContext(AuthContext);
|
const { user } = useAuthContext();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -26,4 +27,6 @@ export default function Protect({ children = <></> }) {
|
|||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Protect;
|
||||||
@@ -87,6 +87,13 @@ export const getAllRecipes = async () => {
|
|||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
// const result = await fetch(API + 'recipe').then(response => response.json());
|
}
|
||||||
// return result;
|
|
||||||
|
// for user friendships
|
||||||
|
export const getFriendships = async () => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
} catch (e: any) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,11 @@ interface ButtonParams extends PortalBase {
|
|||||||
onClick?: (params?: any) => any
|
onClick?: (params?: any) => any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ModifiedPortal extends PortalBase {
|
||||||
|
children?: ReactNode | ReactNode[]
|
||||||
|
}
|
||||||
|
|
||||||
export type PageComponent = FC<PortalBase>
|
export type PageComponent = FC<PortalBase>
|
||||||
export type PanelComponent = FC<PortalBase>
|
export type PanelComponent = FC<PortalBase>
|
||||||
export type ButtonComponent = FC<ButtonParams>
|
export type ButtonComponent = FC<ButtonParams>
|
||||||
|
export type ProtectPortal = FC<ModifiedPortal>
|
||||||
@@ -43,4 +43,14 @@ export default class UserCtl {
|
|||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getFriends(id: string) {
|
||||||
|
try {
|
||||||
|
const result = await UserInstance.getFriends(id);
|
||||||
|
if (!result) throw createError(404, "You have no friends");
|
||||||
|
return result;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
13
server/db/sql/friendships.sql
Normal file
13
server/db/sql/friendships.sql
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
SELECT
|
||||||
|
recipin.cmp_userfriendships.id,
|
||||||
|
recipin.cmp_userfriendships.datecreated,
|
||||||
|
recipin.appusers.id,
|
||||||
|
recipin.appusers.firstname,
|
||||||
|
recipin.appusers.lastname,
|
||||||
|
recipin.appusers.handle,
|
||||||
|
recipin.appusers.email
|
||||||
|
FROM recipin.cmp_userfriendships
|
||||||
|
INNER JOIN recipin.appusers
|
||||||
|
ON recipin.appusers.id = recipin.cmp_userfriendships.seconduserid
|
||||||
|
WHERE firstuserid = $1
|
||||||
|
AND cmp_userfriendships.active = true;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import path from 'path';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
@@ -9,7 +10,10 @@ const port = 8080;
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
|
||||||
|
export const appRoot = path.resolve(__dirname);
|
||||||
|
|
||||||
(async function() {
|
(async function() {
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
await loaders(app);
|
await loaders(app);
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { IUser } from "../schemas";
|
import { IUser } from "../schemas";
|
||||||
|
import fs from "fs";
|
||||||
import pgPromise from "pg-promise";
|
import pgPromise from "pg-promise";
|
||||||
import pool from '../db';
|
import pool from '../db';
|
||||||
import now from "../util/now";
|
import now from "../util/now";
|
||||||
|
import { appRoot } from "..";
|
||||||
|
|
||||||
const pgp = pgPromise({ capSQL: true });
|
const pgp = pgPromise({ capSQL: true });
|
||||||
export class User {
|
export class User {
|
||||||
@@ -91,4 +93,15 @@ export class User {
|
|||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getFriends(id: string) {
|
||||||
|
try {
|
||||||
|
const sql = fs.readFileSync(appRoot + '/db/sql/friendships.sql').toString();
|
||||||
|
const result = await pool.query(sql, [id]);
|
||||||
|
if (result.rows.length) return result.rows;
|
||||||
|
return null;
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ export const userRoute = (app: Express) => {
|
|||||||
res.status(200).send(data);
|
res.status(200).send(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// get, put by id
|
||||||
router.get('/:id', async (req, res, next) => {
|
router.get('/:id', async (req, res, next) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
try {
|
try {
|
||||||
@@ -33,13 +34,21 @@ export const userRoute = (app: Express) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// create user
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
const response = userCtl.post(data);
|
const response = userCtl.post(data);
|
||||||
res.status(200).send(response);
|
res.status(200).send(response);
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get('/hidden-thing', (req, res) => {
|
// get friendships by requester ID
|
||||||
res.send('does this route actually work?');
|
router.get('/friends/:id', async (req, res, next) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
try {
|
||||||
|
const result = await userCtl.getFriends(id);
|
||||||
|
res.status(200).send(result);
|
||||||
|
} catch(e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user