Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
riv-k committed Jul 12, 2024
2 parents 931d3ba + 17c5937 commit c02c709
Show file tree
Hide file tree
Showing 20 changed files with 604 additions and 164 deletions.
91 changes: 1 addition & 90 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,90 +1 @@
# React Template

## Tech Stack

This

## Setup Runbook

1. Create a new repository with UoAWDCC as owner
2. Select repository template as `UoAWDCC/react-template`

![Create Repo](images/create-repo.png)

3. Clone the app to your local machine

4. In `/api/fly.production.toml` change the app name to `wdcc-app-name-api` . For example, passport will be `wdcc-passport-api`
Then create the app on fly with this command:

```jsx
PS C:\Users\alexw\OneDrive\Documents\GitHub\UoAWDCC\passport> fly apps create --name wdcc-passport-api --org wdcc-projects
New app created: wdcc-passport-api
```

5. In the`/api` directory run

```jsx
PS C:\Users\alexw\OneDrive\Documents\GitHub\UoAWDCC\passport\api> fly tokens create deploy --config fly.production.toml
FlyV1 ...IFIc=
```

- Copy the output to your clipboard
- Go to repository settings on Github
- In secrets and variables select actions

![Untitled](images/secrets.png)

- Create a new repository secret
- Name it `FLY_API_PRODUCTION_API_TOKEN` and paste in the secret

6. In `/api/fly.staging.toml` change the app name to `wdcc-app-name-api-staging`
Then create the app on fly with this command

PS C:\Users\alexw\OneDrive\Documents\GitHub\UoAWDCC\passport> fly apps create --name wdcc-passport-api-staging --org wdcc-projects
New app created: wdcc-passport-api-staging

7. In the `/api` directory run

```jsx
PS C:\Users\alexw\OneDrive\Documents\GitHub\UoAWDCC\passport\api> fly tokens create deploy --config fly.staging.toml
FlyV1 ...IFIc=
```

- Copy the output to your clipboard
- Go to repository settings on Github
- In secrets and variables select actions
- Create a new repository secret
- Name it `FLY_API_STAGING_API_TOKEN` and paste in the secret

8. In `/web/Dockerfile.production` change

```jsx
ENV VITE_API_URL="https://react-template-api.fly.dev"
```

to

```jsx
ENV VITE_API_URL="https://wdcc-app-name-api.fly.dev"
```

(change it to to the name of your production api app that you just created before

9. In `/web/Dockerfile.staging`change

```jsx
ENV VITE_API_URL="https://react-template-api-staging.fly.dev"
```

to

```jsx
ENV VITE_API_URL="https://wdcc-app-name-api-staging.fly.dev"
```

(change it to to the name of your staging api app that you just created before

10. In `/web/fly.production.toml` change the name of the app to `wdcc-app-name` and run `fly apps create --name wdcc-app-name --org wdcc-projects`
11. Now run `fly tokens create deploy --config fly.production.toml` and save that as a Github repository secret with the name `FLY_WEB_PRODUCTION_API_TOKEN`
12. In `/web/fly.staging.toml` change the name of the app to `wdcc-app-name-staging` and run `fly apps create --name wdcc-app-name-staging --org wdcc-projects`
13. Now run `fly tokens create deploy --config fly.staging.toml` and save that as a Github repository secret with the name `FLY_WEB_STAGING_API_TOKEN`
This is a project created by team Braincells for the DEVS 2024 Hackathon
9 changes: 3 additions & 6 deletions api/db/User.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Schema, model } from 'mongoose';

const userSchema = new Schema({
firstName: {
email: {
type: String,
required: true,
unique: true,
},
lastName: String,
email: {
password: {
type: String,
required: true,
unique: true,
maxLength: 40,
minLength: 1,
},
});

Expand Down
93 changes: 93 additions & 0 deletions api/routes/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Request, Response } from "express"
import { Router } from "express"
import User from "../db/User"

const userRoutes = Router()

// GET /api/users
userRoutes.get("/", async (req: Request, res: Response) => {
// Logic to fetch all users from the database
try {
const results = await User.find()
const users = results.map((user) => user.toObject())
return res.json(users)
} catch (error: any) {
res.status(500).json({ message: error.message })
}
})


userRoutes.post("/check-user", async (req: Request, res: Response) => {
const accessToken = req.body.accessToken;
try {
const response = await User.findOne({ accessToken: accessToken }).exec()
console.log(response)
if (response != undefined && response !== null) {
res.status(200).json({ user: response, success: true })

} else {
res.status(200).json({
success: false,
error: "User not found"
})
}
} catch (error) {
res.status(400).json({ success: false, errorMessage: error })
}


})

// GET /api/user/:upi
userRoutes.get("/:upi", async (req: Request, res: Response) => {
const upi = req.params.upi
try {
const user = await User.findOne({ upi: upi }).exec() // Await the result or use exec()
if (user) {
res.json(user)
} else {
res.status(404).json({ message: "User not found" })
}
} catch (error: any) {
res.status(500).json({ message: error.message })
}
})

// POST /api/user
userRoutes.post("/", (req: Request, res: Response) => {
const userData = req.body

// Logic to create a new user in the database
const newUser = new User({
email: req.body.email,
password: req.body.password,
})

try {
const savedUser = newUser.save()
res.status(201).json(savedUser)
} catch (error: any) {
res.status(400).json({ message: error.message })
}
})

// PUT /api/user/:email
userRoutes.put("/:email", async (req: Request, res: Response) => {
try {
const updatedUser = await User.findOneAndUpdate(
{ upi: req.params.upi }, // Filter criteria
req.body, // Updated data
{ new: true } // Return the updated document
).exec() // Execute the query

if (updatedUser) {
res.json(updatedUser)
} else {
res.status(404).json({ message: "User not found" })
}
} catch (error: any) {
res.status(400).json({ message: error.message })
}
})

export default userRoutes
6 changes: 5 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@
"@tanstack/react-query": "^5.18.1",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
"axios": "^1.6.7",
"add": "^2.0.6",
"axios": "^1.7.2",
"ldrs": "^1.0.2",
"react": "^18.2.0",
"react-cookies": "^0.1.1",
"react-dom": "^18.2.0",
"react-oauth-google": "^0.9.0",
"react-router": "^6.22.0",
"react-router-dom": "^6.22.0",
"tailwind-merge": "^2.2.1",
"universal-cookie": "^7.0.2",
"yarn": "^1.22.22",
"zod": "^3.22.4"
},
"devDependencies": {
Expand Down
1 change: 0 additions & 1 deletion web/public/vite.svg

This file was deleted.

7 changes: 6 additions & 1 deletion web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import { useState } from 'react';
import Home from '@pages/Home';
import Form from '@pages/Form';

const router = createBrowserRouter([
{
path: '/:name',
path: '/',
element: <Home />,
},
{
path: '/sign-in',
element: <Form />
}
]);

export default function App() {
Expand Down
Binary file added web/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion web/src/assets/react.svg

This file was deleted.

118 changes: 118 additions & 0 deletions web/src/components/login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import axios from "axios";
import { useNavigate } from "react-router-dom";

interface UserData {
firstName: string;
lastName: string;
email: string;
}

// New user to MongoDB
const postUserData = async (data: UserData) => {
await fetch(`${import.meta.env.VITE_SERVER_URL}/api/user`, {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
}),
})
.then((response) => {
console.log("New User added!!");
console.log(response);
})
.catch((error) => {
console.log(error);
});
};

//updating User in MongoDB
const updateUserData = async (data: UserData) => {
try {
const response = await fetch(
`${import.meta.env.VITE_SERVER_URL}/api/user/` + data.email,
{
method: "PUT",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
firstName: data.firstName,
lastName: data.lastName,
email: data.email,
}),
}
);

if (!response.ok) {
throw new Error("Failed to update user data");
} else {
console.log("User Data Updated");
}
} catch (error) {
console.error(error);
}
};

// Passes UPI to WDCC member checker API
const signIn = (
currentPage: string,
setLoading: (loading: boolean) => void
) => {

const handleSignIn = signIn({
onSuccess: async (tokenResponse) => {
try {
setLoading(true);

const getUserData = async () => {
await fetch(
`${import.meta.env.VITE_SERVER_URL}/api/user/` +
userInfo.data.email,
{
method: "GET",
}
)
.then((response) => {
console.log(
"Fetch response for user data - Checking if user is in DB"
);
// If we get something then, update the user data. Else post.

if (response.status == 200) {
console.log("Updating User Data");

updateUserData({
firstName: userInfo.data.firstName,
lastName: userInfo.data.lastName,
email: userInfo.data.email,
});
} else {
console.log("Posting User Data");
postUserData({
firstName: userInfo.data.firstName,
lastName: userInfo.data.lastName,
email: userInfo.data.email,
});
}
})
.catch((error) => {
console.log(error);
});
};

// Check MongoDB if user is in DB, then updates/posts user data accordingly
getUserData();
} catch (error) {
console.error("Failed to fetch user info:", error);
}
},
onError: (error) => {
console.log("Login failed:", error);
},
// Assuming implicit flow as default; no need to specify unless changing
});
console.log(currentPage);
return handleSignIn;
};

export default useGoogleSignIn;
16 changes: 16 additions & 0 deletions web/src/components/sign-in-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import '../styles/sign-in-button.css';

interface GoogleSignin {
onClick: () => void;
adminLogin?: boolean;
}

const GoogleSigninBtn = ({ onClick }: GoogleSignin) => {
return(
<button className={"button"} onClick={onClick}>
<h3>Sign In</h3>
</button>
);
};

export default GoogleSigninBtn;
Loading

0 comments on commit c02c709

Please sign in to comment.