Skip to content

Commit bb1ef9b

Browse files
committed
Add workout-tracker-nextjs
1 parent e564473 commit bb1ef9b

31 files changed

+2923
-7
lines changed

remix-pokemon-api/public/pokemon/type

Whitespace-only changes.

remix-pokemon-api/public/pokemon/type:-null.jpg

Lines changed: 0 additions & 7 deletions
This file was deleted.

workout-tracker-nextjs/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
NEXT_PUBLIC_SUPABASE_URL
2+
NEXT_PUBLIC_SUPABASE_ANON_KEY

workout-tracker-nextjs/.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

workout-tracker-nextjs/.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel

workout-tracker-nextjs/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2+
3+
## Getting Started
4+
5+
First, run the development server:
6+
7+
```bash
8+
npm run dev
9+
# or
10+
yarn dev
11+
```
12+
13+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14+
15+
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16+
17+
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18+
19+
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20+
21+
## Learn More
22+
23+
To learn more about Next.js, take a look at the following resources:
24+
25+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27+
28+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29+
30+
## Deploy on Vercel
31+
32+
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33+
34+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Link from "next/link";
2+
import styles from "../styles/Footer.module.css";
3+
4+
const Footer = () => {
5+
return (
6+
<div className={styles.container}>
7+
<h1 className={styles.text}>
8+
Built with{" "}
9+
<Link href="https://nextjs.org/">
10+
<span className={styles.stack}>Nextjs</span>
11+
</Link>{" "}
12+
and{" "}
13+
<Link href="https://supabase.com/">
14+
<span className={styles.stack}>Supabase</span>
15+
</Link>
16+
</h1>
17+
<Link href="">
18+
<p className={styles.repo}>Github Repo</p>
19+
</Link>
20+
</div>
21+
);
22+
};
23+
24+
export default Footer;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import Link from "next/link";
2+
import styles from "../styles/Navbar.module.css";
3+
import { supabase } from "../utils/supabase";
4+
5+
const Navbar = ({ session }) => {
6+
return (
7+
<div className={styles.container}>
8+
<div>
9+
<p className={styles.title}>Adrenargy</p>
10+
</div>
11+
{session?.user ? (
12+
<ul className={styles.navContent}>
13+
<Link href="/">
14+
<li className={styles.name}>Home</li>
15+
</Link>
16+
17+
<button
18+
className={styles.buttons}
19+
onClick={() => supabase.auth.signOut()}
20+
>
21+
Logout
22+
</button>
23+
<Link href="/create">
24+
<button className={styles.buttons}>Create New Workout</button>
25+
</Link>
26+
</ul>
27+
) : (
28+
<ul className={styles.navContent}>
29+
<Link href="/login">
30+
<li className={styles.buttons}>Login</li>
31+
</Link>
32+
<Link href="/signup">
33+
<li className={styles.buttons}>Signup</li>
34+
</Link>
35+
</ul>
36+
)}
37+
</div>
38+
);
39+
};
40+
41+
export default Navbar;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import Link from "next/link";
2+
import { useEffect, useState } from "react";
3+
import styles from "../styles/WorkoutCard.module.css";
4+
import { supabase } from "../utils/supabase";
5+
import { BsTrash } from "react-icons/bs";
6+
import { FiEdit } from "react-icons/fi";
7+
import { formatDistanceToNow } from "date-fns/";
8+
9+
const WorkoutCard = ({ data, handleDelete }) => {
10+
return (
11+
<div className={styles.workoutContainer}>
12+
{data?.map((item) => (
13+
<div key={item.id} className={styles.container}>
14+
<p className={styles.title}>
15+
{" "}
16+
Title: {""}
17+
{item.title}
18+
</p>
19+
<p className={styles.load}>
20+
{" "}
21+
Load(kg): {" "}
22+
{item.loads}
23+
</p>
24+
<p className={styles.reps}>Reps:{item.reps}</p>
25+
<p className={styles.time}>
26+
created:{" "}
27+
{formatDistanceToNow(new Date(item.inserted_at), {
28+
addSuffix: true,
29+
})}
30+
</p>
31+
32+
<div className={styles.buttons}>
33+
<Link href={`/edit/${item.id}`}>
34+
<a className={styles.edit}>
35+
<FiEdit />
36+
</a>
37+
</Link>
38+
<button
39+
onClick={() => handleDelete(item.id)}
40+
className={styles.delete}
41+
>
42+
<BsTrash />
43+
</button>
44+
</div>
45+
</div>
46+
))}
47+
</div>
48+
);
49+
};
50+
51+
export default WorkoutCard;

workout-tracker-nextjs/next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
reactStrictMode: true,
3+
}

workout-tracker-nextjs/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "nextjs-supabase",
3+
"private": true,
4+
"scripts": {
5+
"dev": "next dev",
6+
"build": "next build",
7+
"start": "next start",
8+
"lint": "next lint"
9+
},
10+
"dependencies": {
11+
"@supabase/supabase-js": "^1.35.4",
12+
"date-fns": "^2.29.1",
13+
"next": "12.2.3",
14+
"react": "18.2.0",
15+
"react-dom": "18.2.0",
16+
"react-hot-toast": "^2.3.0",
17+
"react-icons": "^4.4.0"
18+
},
19+
"devDependencies": {
20+
"eslint": "8.20.0",
21+
"eslint-config-next": "12.2.3"
22+
}
23+
}

workout-tracker-nextjs/pages/_app.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Link from "next/link";
2+
import { useState, useEffect } from "react";
3+
import Footer from "../components/Footer";
4+
import Navbar from "../components/Navbar";
5+
import "../styles/globals.css";
6+
import { supabase } from "../utils/supabase";
7+
8+
function MyApp({ Component, pageProps }) {
9+
const [session, setSession] = useState(null);
10+
11+
useEffect(() => {
12+
setSession(supabase.auth.session());
13+
supabase.auth.onAuthStateChange((_event, session) => {
14+
setSession(session);
15+
});
16+
}, []);
17+
return (
18+
<div>
19+
<Navbar session={session} />
20+
<Component {...pageProps} session={session} />
21+
<Footer />
22+
</div>
23+
);
24+
}
25+
26+
export default MyApp;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2+
3+
export default function handler(req, res) {
4+
res.status(200).json({ name: 'John Doe' })
5+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { supabase } from "../utils/supabase";
2+
import { useState, useEffect } from "react";
3+
import styles from "../styles/Create.module.css";
4+
import { useRouter } from "next/router";
5+
6+
const Create = () => {
7+
const initialState = {
8+
title: "",
9+
loads: "",
10+
reps: "",
11+
};
12+
13+
const router = useRouter();
14+
const [workoutData, setWorkoutData] = useState(initialState);
15+
16+
const { title, loads, reps } = workoutData;
17+
18+
const handleChange = (e) => {
19+
setWorkoutData({ ...workoutData, [e.target.name]: e.target.value });
20+
};
21+
22+
const createWorkout = async () => {
23+
const user = supabase.auth.user();
24+
25+
const { data, error } = await supabase
26+
.from("workouts")
27+
.insert({
28+
title,
29+
loads,
30+
reps,
31+
user_id: user?.id,
32+
})
33+
.single();
34+
alert("Workout created successfully");
35+
setWorkoutData(initialState);
36+
router.push("/");
37+
};
38+
39+
return (
40+
<>
41+
<div className={styles.container}>
42+
<div className={styles.form}>
43+
<p className={styles.title}>Create a New Workout</p>
44+
<label className={styles.label}>Title:</label>
45+
<input
46+
type="text"
47+
name="title"
48+
value={title}
49+
onChange={handleChange}
50+
className={styles.input}
51+
placeholder="Enter a title"
52+
/>
53+
<label className={styles.label}>Load (kg):</label>
54+
<input
55+
type="text"
56+
name="loads"
57+
value={loads}
58+
onChange={handleChange}
59+
className={styles.input}
60+
placeholder="Enter weight load"
61+
/>
62+
<label className={styles.label}>Reps:</label>
63+
<input
64+
type="text"
65+
name="reps"
66+
value={reps}
67+
onChange={handleChange}
68+
className={styles.input}
69+
placeholder="Enter number of reps"
70+
/>
71+
72+
<button className={styles.button} onClick={createWorkout}>
73+
Create Workout
74+
</button>
75+
</div>
76+
</div>
77+
</>
78+
);
79+
};
80+
81+
export default Create;

0 commit comments

Comments
 (0)