Skip to content

Commit

Permalink
Merge pull request #5 from Lissone/dev
Browse files Browse the repository at this point in the history
Release v.2.0.0 - New version with Next
  • Loading branch information
Lissone authored Oct 22, 2021
2 parents 2bbc580 + e133343 commit cdd0535
Show file tree
Hide file tree
Showing 98 changed files with 15,653 additions and 2,395 deletions.
Binary file modified .github/demo-lix-attendance.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,22 +1,7 @@
.DS_Store
node_modules
/dist

# local env files
.env
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
pnpm-debug.log*
69 changes: 60 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h1 align="center">
LixAttendance
<img alt="LixAttendance" src="./packages/web/public/logo.svg" width="350px">
</h1>

<p align="center">
Expand Down Expand Up @@ -30,12 +30,15 @@

## Description

Project developed with the intention of getting deeper into WS requests and real-time applications. It consists of a messaging chat for a parent application, which can choose to enable or disable this type of support chat. Developed at the Next Level Week 5 (NLW) marathon, taught by Daniela Leão, from April 19th to 25th, 2021.
Project developed with the intention of deepening knowledge in websockets with real-time applications and integration with htttp servers.
It consists of a support chat site between customer with question and admin respondent, where admin can choose customer he wants to respond according to priority (based on time of message sent), and close his connection once queries are answered . Anyone can test the application in order to contract the service for their own website by contacting the responsible developer (myself).
The first version of the project was developed at the Next Level Week 5 (NLW) marathon, taught by Daniela Leão, from April 19 to 25, 2021.

## Requirements

* [Yarn](https://yarnpkg.com/)
* [Nodejs](https://nodejs.org/en/)
* [SqlServer](https://www.microsoft.com/pt-br/sql-server/sql-server-downloads)

## Technologies

Expand All @@ -45,14 +48,16 @@ Project developed with the intention of getting deeper into WS requests and real
* Express
* Socket.io
* TypeORM
* Sqlite
* SqlServer
* ESLint

### Front End
* Html
* Css
* Javascript
* Ejs
* Next
* Typescript
* StyledComponents
* Socket.io-client
* ESLint (Airbnb config + pessoal rules)
* Prettier

## Usage

Expand All @@ -70,14 +75,60 @@ yarn
npm run
```

### Database configuration

É necessário criar o database antes de executar a api (dbLixAttendance).

```typescript
// .\src\external\database\dbConfig.ts

const connection = createConnection({
type: 'mssql',
host: process.env.DB_HOST,
port: 1433,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
entities: [**Entities**],
synchronize: true,
logging: false,
options: {
enableArithAbort: true
}
})
```

Need to add environment variables in both projects:

```bash
# .\packages\web\.env.local

# DEFAULT
NEXT_PUBLIC_BASE_URL_API=http://localhost:5000
```

```bash
# .\.env
# .\packages\api\.env

# DEFAULT
PORT=5000
DB_USERNAME=sa
DB_PASSWORD=123456
DB_NAME=dbLixAttendance
DB_HOST=localhost
```

Run api:
```bash
cd .\packages\api\
yarn dev
#or
npm run dev
```

Run application:
Run web:
```bash
cd .\packages\web\
yarn dev
#or
npm run dev
Expand Down
9 changes: 0 additions & 9 deletions ormconfig.json

This file was deleted.

40 changes: 8 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,37 +1,13 @@
{
"name": "lix-attendance-api",
"version": "1.0.0",
"name": "lix-attendance",
"version": "2.0.0",
"main": "index.js",
"repository": "https://github.com/Lissone/lix-attendance.git",
"description": "Talk to an admin to clear all your doubts in real time.",
"main": "src/server.ts",
"repository": "https://github.com/Lissone/lix-attendance",
"author": "Leonardo Dias Lissone (leonardo.lissonez@gmail.com)",
"author": "Leonardo Dias Lissone Santomero <leonardo.lissonez@gmail.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "ts-node-dev .",
"typeorm": "ts-node-dev node_modules/typeorm/cli.js"
},
"dependencies": {
"ejs": "^3.1.6",
"express": "^4.17.1",
"reflect-metadata": "^0.1.13",
"socket.io": "^4.1.3",
"socket.io-client": "^4.1.3",
"sqlite3": "^5.0.2",
"typeorm": "^0.2.34",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/socket.io": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"eslint": "^7.31.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"ts-node-dev": "^1.1.8",
"typescript": "^4.3.5"
}
"workspaces": [
"packages/*"
]
}
File renamed without changes.
22 changes: 22 additions & 0 deletions packages/api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.DS_Store
node_modules
/dist

# local env files
.env
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
36 changes: 36 additions & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "lix-attendance-api",
"version": "2.0.0",
"main": "src/external/server.ts",
"repository": "https://github.com/Lissone/lix-attendance",
"author": "Leonardo Dias Lissone (leonardo.lissonez@gmail.com)",
"license": "MIT",
"private": true,
"scripts": {
"dev": "ts-node-dev --respawn --transpile-only --ignore-watch node_modules -r tsconfig-paths/register ."
},
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"mssql": "^6.2.1",
"reflect-metadata": "^0.1.13",
"socket.io": "^4.1.3",
"typeorm": "^0.2.32"
},
"devDependencies": {
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/socket.io": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^4.28.4",
"@typescript-eslint/parser": "^4.28.4",
"eslint": "^7.31.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"ts-node-dev": "^1.1.8",
"tsconfig-paths": "^3.11.0",
"typescript": "^4.3.5"
}
}
27 changes: 27 additions & 0 deletions packages/api/src/adapters/controllers/ConnectionController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Request, Response } from 'express'

import { IConnectionUseCase } from '@useCases/connection/IConnectionUseCase'

export class ConnectionController {
useCase: IConnectionUseCase

constructor (useCase: IConnectionUseCase) {
this.useCase = useCase
}

async getOne (req: Request, res: Response): Promise<Response> {
try {
const { connectionId } = req.params

if (!connectionId) {
return res.sendStatus(400)
}

const connection = await this.useCase.getOne(connectionId)

return res.status(200).json(connection)
} catch (err) {
return res.status(500).json({ message: err.message })
}
}
}
57 changes: 57 additions & 0 deletions packages/api/src/adapters/controllers/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Request, Response } from 'express'

import { IUserUseCase } from '@useCases/user/IUserUseCase'
import { IConnectionUseCase } from '@useCases/connection/IConnectionUseCase'

export class UserController {
useCaseUser: IUserUseCase
useCaseConnection: IConnectionUseCase

constructor (useCaseUser: IUserUseCase, useCaseConnection: IConnectionUseCase) {
this.useCaseUser = useCaseUser
this.useCaseConnection = useCaseConnection
}

async signIn (req: Request, res: Response): Promise<Response> {
try {
const { user } = req.body

const userAlreadyExists = await this.useCaseUser.getOneByEmail(user.email)

if (!userAlreadyExists) {
const ret = await this.useCaseUser.create(user)

return res.status(200).json({ user: ret })
}

const userUpdated = await this.useCaseUser.update({
...userAlreadyExists,
socket: user.socket
})

const connectionByClient = await this.useCaseConnection.getOneByClientId(userUpdated.id)

if (user.type === 'client') {
const connectionByAdmin = await this.useCaseConnection.getAllByAdminId(userUpdated.id)

if (connectionByAdmin.length > 0) {
return res.status(406).json({ message: 'It is not acceptable for an admin to become a customer' })
}

if (!connectionByClient) {
return res.status(200).json({ user: userUpdated })
}

return res.status(200).json({ user: userUpdated, connectionId: connectionByClient.id })
} else {
if (connectionByClient) {
return res.status(406).json({ message: 'It is not accepted a client with connection to become an admin' })
}
}

return res.status(200).json({ user: userUpdated })
} catch (err) {
return res.status(500).json({ message: err.message })
}
}
}
55 changes: 55 additions & 0 deletions packages/api/src/adapters/repositories/ConnectionRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Repository, getRepository } from 'typeorm'

import { IConnection } from '@entities/IConnection'
import { ConnectionEntity } from '@external/database/entities/ConnectionEntity'
import { IConnectionCreate, IConnectionRepository, IConnectionUpdate } from '@useCases/connection/IConnectionRepository'

export class ConnectionRepository implements IConnectionRepository {
private get repository () : Repository<IConnection> {
return getRepository(ConnectionEntity)
}

async getAllWithoutAdmin () : Promise<IConnection[]> {
const connections = await this.repository.find({ where: { adminId: null }, relations: ['client'] })

return connections
}

async getAllByAdminId (adminId: string) : Promise<IConnection[]> {
const connections = await this.repository.find({ where: { adminId }, relations: ['client', 'admin'] })

return connections
}

async getAllUnclosedByAdminId (adminId: string) : Promise<IConnection[]> {
const connections = await this.repository.find({ where: { adminId, closedAt: null }, relations: ['client', 'admin'] })

return connections
}

async getOne (connectionId: string) : Promise<IConnection | undefined> {
const connection = await this.repository.findOne({ where: { id: connectionId }, relations: ['client', 'admin', 'messages'] })

return connection
}

async getOneByClientId (clientId: string) : Promise<IConnection | undefined> {
const connection = await this.repository.findOne({ clientId })

return connection
}

async create (connection: IConnectionCreate) : Promise<IConnection> {
this.repository.create(connection)

const ret = await this.repository.save(connection)

return ret
}

async update (connection: IConnectionUpdate) : Promise<IConnection> {
const ret = await this.repository.save(connection)

return ret
}
}
Loading

0 comments on commit cdd0535

Please sign in to comment.