Skip to content

Commit

Permalink
Add login/signup
Browse files Browse the repository at this point in the history
  • Loading branch information
anniegouchee committed Feb 28, 2024
2 parents 30753c7 + 3f5a66b commit 832df98
Show file tree
Hide file tree
Showing 17 changed files with 228 additions and 22 deletions.
7 changes: 7 additions & 0 deletions api/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"
1 change: 1 addition & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
build/
*.db
.env
26 changes: 26 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Greenpeace Backend

## Overview
The frontend of the application will serve the maps UI by accessing the Google Maps API and rendering the result using React, with additional components from Material UI. Our complete (frontend) tech stack is:
- Express.js
- Prisma


## Setup

To create the `.env` file, copy the `.env.example` file, make sure you are in the `backend` folder and run the following:
```
cp .env.example .env
```

Next, start the Docker Compose services, use the command:

```
docker-compose up
```


---


Feel free to add any issue in this file, or let the leads know!
13 changes: 13 additions & 0 deletions api/dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM node:lts

RUN mkdir -p /app/

COPY . /app/

WORKDIR /app/

EXPOSE 3000

RUN npm install

CMD ["npm", "run", "debug:watch"]
1 change: 0 additions & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prepare": "husky install",
"lint": "eslint --ignore-path .gitignore --ext .ts src",
"lint:fix": "npm run lint -- --fix",
"format": "prettier write src",
Expand Down
62 changes: 60 additions & 2 deletions api/src/pin/pin.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { Injectable } from '@decorators/di';
import { Controller, Get, Params, Response } from '@decorators/express';
import {
Body,
Controller,
Delete,
Get,
Params,
Post,
Put,
Response,
} from '@decorators/express';
import { Response as ExpressResponse } from 'express';
import PinService from './pin.service';
import { ManyPinResponseDto, PinDto, PinResponseDto } from './pin.dto';
Expand All @@ -23,7 +32,7 @@ class PinController {
}

@Get('/:id')
async getByID(
async getOne(
@Response() response: ExpressResponse,
@Params('id') id: string
) {
Expand All @@ -37,6 +46,55 @@ class PinController {
? response.status(200).send(dto)
: response.status(404).send(dto);
}

@Post('/')
async create(
@Response() response: ExpressResponse,
@Body('pin') pin: PinDto
) {
const result: PinDto | null = await this.service.create(pin);

const dto: PinResponseDto = result
? ({ status: 'Success', pin: result } as PinResponseDto)
: ({ status: 'Error' } as PinResponseDto);

return result
? response.status(200).send(dto)
: response.status(500).send(dto);
}

@Put('/:id')
async update(
@Response() response: ExpressResponse,
@Params('id') id: number,
@Body('pin') pin: Partial<PinDto>
) {
const result: PinDto | null = await this.service.update(id, pin);

const dto: PinResponseDto = result
? ({ status: 'Success', pin: result } as PinResponseDto)
: ({ status: 'Error' } as PinResponseDto);

return result
? response.status(200).send(dto)
: response.status(404).send(dto);
}

@Delete('/:id')
async delete(
@Response() response: ExpressResponse,
@Params('id') id: string
) {
const result: PinDto = await this.service.remove(Number(id));

const dto: PinResponseDto = result
? ({ status: 'Success', pin: result } as PinResponseDto)
: ({ status: 'Error' } as PinResponseDto);

return result
? response.status(200).send(dto)
: response.status(404).send(dto);
}
}

export { PinController };
4 changes: 3 additions & 1 deletion api/src/pin/pin.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ export interface PinDto {
coordinateY: number;
isValid?: boolean;
createdAt: Date;
}
category: string;
reactions?: string[];
}
33 changes: 33 additions & 0 deletions api/src/pin/pin.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@decorators/di';
import { PrismaClient } from '@prisma/client';
import { PinDto } from './pin.dto';

@Injectable()
class PinService {
Expand All @@ -16,6 +17,38 @@ class PinService {
},
});
}

async create(pin: PinDto) {
return await this.prisma.pin.create({
data: {
name: pin.name,
description: String(pin.description),
coordinateX: pin.coordinateX,
coordinateY: pin.coordinateY,
isValid: pin.isValid,
createdAt: pin.createdAt,
},
});
}

async remove(id: number) {
return await this.prisma.pin.delete({
where: {
id: id,
},
});
}

async update(id: number, pin: Partial<PinDto>) {
return await this.prisma.pin.update({
where: {
id: id,
},
data: {
...pin,
},
});
}
}

export default PinService;
Binary file added api/src/prisma/app.db-journal
Binary file not shown.
10 changes: 0 additions & 10 deletions api/src/prisma/migrations/20231018232930_added_pin/migration.sql

This file was deleted.

17 changes: 17 additions & 0 deletions api/src/prisma/migrations/20240131234713_initial_pin/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- CreateEnum
CREATE TYPE "Reaction" AS ENUM ('LIKE', 'DISLIKE', 'GOOD_VALUE', 'BAD_VALUE');

-- CreateTable
CREATE TABLE "Pin" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT NOT NULL,
"coordinateX" DOUBLE PRECISION NOT NULL,
"coordinateY" DOUBLE PRECISION NOT NULL,
"isValid" BOOLEAN NOT NULL DEFAULT true,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"category" TEXT NOT NULL DEFAULT '',
"reactions" "Reaction"[],

CONSTRAINT "Pin_pkey" PRIMARY KEY ("id")
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Warnings:
- The `reactions` column on the `Pin` table would be dropped and recreated. This will lead to data loss if there is data in the column.
*/
-- AlterTable
ALTER TABLE "Pin" DROP COLUMN "reactions",
ADD COLUMN "reactions" TEXT[];

-- DropEnum
DROP TYPE "Reaction";
2 changes: 1 addition & 1 deletion api/src/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "sqlite"
provider = "postgresql"
8 changes: 5 additions & 3 deletions api/src/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ generator client {
}

datasource db {
provider = "sqlite"
url = "file:app.db"
provider = "postgresql"
url = "postgresql://[email protected]:5432/greenpeace"
}

model Pin {
Expand All @@ -16,6 +16,8 @@ model Pin {
description String
coordinateX Float
coordinateY Float
isVaid Boolean @default(true)
isValid Boolean @default(true)
createdAt DateTime @default(now())
category String @default("")
reactions String[]
}
28 changes: 28 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "3.8"

services:
database:
image: postgres
container_name: greenpeace-postgres
ports:
- 5432:5432
volumes:
- greenpeace-postgres-data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=greenpeace
- POSTGRES_PASSWORD=greenpeace
- POSTGRES_DATABASE=greenpeace
restart: unless-stopped
api:
build: api/
container_name: greenpeace-api
ports:
- 3000:3000
volumes:
- ./api/:/app/
environment:
- DATABASE_URL=postgresql://greenpeace:[email protected]:5432/greenpeace
restart: unless-stopped

volumes:
greenpeace-postgres-data:
24 changes: 20 additions & 4 deletions frontend/src/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,30 @@ import mapStyles from './mapStyles';

function Map() {
const [selectedPin, setSelectedPin] = useState(null);
const [pins] = useState([])
const [pins, setPins] = useState([]);
const [isListening, setIsListening] = useState(false);

const createPin = (coordinates, name, description) => {
setPins([...pins, {
id: pins.length,
coordinates: coordinates,
location: name,
description: description
}])
}

return (
<GoogleMap
defaultZoom={19}
defaultCenter={{ lat: 45.5048, lng: -73.5772}}
options={{ styles: mapStyles }}
options={{styles: mapStyles}}
onClick={( event ) => {
if (isListening) {
createPin([event.latLng.lat(), event.latLng.lng()], "New Pin", "New Description");
setIsListening(false);
}
}
}
>
{pins.map(pin => (
<Marker
Expand All @@ -32,8 +49,7 @@ function Map() {
setSelectedPin(pin);
}}
icon={{
url: "https://img.icons8.com/color/48/000000/map-pin.png",
scaledSize: new window.google.maps.Size(50, 50)
scaledSize: new window.google.maps.Size(70, 70)
}}
/>
))}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/LoginSignup/LoginSignup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ const LoginSignup = () => {

const handleEmailChange = (event) => {
setEmail(event.target.value);
setErrorEmail(false);
};

const handlePasswordChange = (event) => {
setPassword(event.target.value);
setErrorPassword(false);
};

const handleLoginSignup = () => {
Expand Down

0 comments on commit 832df98

Please sign in to comment.