From 23079666d453cf1fe9df3d613cc6b7f8ce9f8000 Mon Sep 17 00:00:00 2001 From: behnamrhp <behnamrahimpour74@gmail.com> Date: Tue, 23 May 2023 15:38:16 +0300 Subject: [PATCH] [FEAT]: add qr code --- .env.development | 3 +- .env.production | 10 ++++ docker-compose.prod.yml | 13 +++- dockerfile.prod | 2 +- package-lock.json | 5 ++ package.json | 1 + public/assets/icons/qrcode.png | Bin 0 -> 10481 bytes .../core/places/common/entity/placeEntity.ts | 9 ++- .../core/places/common/model/placesModel.ts | 19 +++++- .../usecase/__test__/getPlacesUsecase.test.ts | 22 +++---- src/driven/utils/components/modal/Modal.tsx | 42 +++++++++++++ src/driven/utils/configs/appConfig.ts | 1 + src/driven/utils/constants/assertUrls.ts | 1 + src/driven/utils/constants/envs.ts | 1 + src/driven/utils/constants/staticMessages.ts | 4 ++ .../core/common/table-row/infra/protocols.ts | 4 +- .../core/common/table-row/view/TableRow.tsx | 5 +- .../core/common/table-row/view/protocols.ts | 4 +- .../view/table-row-item/view/RowItem.tsx | 51 ++++++++++++++-- .../core/places-list/infra/PlacesList.tsx | 56 +++++++++++++++++- .../core/places-list/view/PlacesListView.tsx | 3 +- src/driving/main/pages/index.tsx | 1 + 22 files changed, 230 insertions(+), 27 deletions(-) create mode 100644 .env.production create mode 100644 public/assets/icons/qrcode.png create mode 100644 src/driven/utils/components/modal/Modal.tsx diff --git a/.env.development b/.env.development index 233e901..50eda8e 100644 --- a/.env.development +++ b/.env.development @@ -7,4 +7,5 @@ VITE_API_CREATE_MEMBER = /user_place/members VITE_API_PLACES = /place VITE_API_USERS = /profile VITE_API_USERS_ACCOUNT = /account -VITE_API_USERS_PROFILE = /profile \ No newline at end of file +VITE_API_USERS_PROFILE = /profile +VITE_API_QR = /qr_code \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..233e901 --- /dev/null +++ b/.env.production @@ -0,0 +1,10 @@ +VITE_API_ORIGIN = https://admin.dev.dipal.ru/api/v1 +VITE_API_AUTH_ORIGIN = https://auth.dev.dipal.ru/api/v1/auth +VITE_API_AUTH_PHONENUMBER = /start-challenge +VITE_API_AUTH_LOGIN = /login +VITE_API_AUTH_REFRESH = /refresh-token +VITE_API_CREATE_MEMBER = /user_place/members +VITE_API_PLACES = /place +VITE_API_USERS = /profile +VITE_API_USERS_ACCOUNT = /account +VITE_API_USERS_PROFILE = /profile \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 55ebaaa..a430b0b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,8 +1,19 @@ version: "3.3" services: - dipal-admin-prod: + dipal-admin: ports: - 8000:80 + environment: + - VITE_API_ORIGIN=https://admin.dev.dipal.ru/api/v1 + - VITE_API_AUTH_ORIGIN=https://auth.dev.dipal.ru/api/v1/auth + - VITE_API_AUTH_PHONENUMBER=/start-challenge + - VITE_API_AUTH_LOGIN=/login + - VITE_API_AUTH_REFRESH=/refresh-token + - VITE_API_CREATE_MEMBER=/user_place/members + - VITE_API_PLACES=/place + - VITE_API_USERS=/profile + - VITE_API_USERS_ACCOUNT=/account + - VITE_API_USERS_PROFILE=/profile build: context: . dockerfile: dockerfile.prod \ No newline at end of file diff --git a/dockerfile.prod b/dockerfile.prod index 493cdd5..a2122da 100644 --- a/dockerfile.prod +++ b/dockerfile.prod @@ -18,4 +18,4 @@ USER nginx EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 78b9b10..4ca65cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7110,6 +7110,11 @@ "integrity": "sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==", "dev": true }, + "qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==" + }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", diff --git a/package.json b/package.json index 223f7a6..fea4397 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@reduxjs/toolkit": "^1.9.3", "axios": "^1.3.4", + "qrcode.react": "^3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-redux": "^8.0.5", diff --git a/public/assets/icons/qrcode.png b/public/assets/icons/qrcode.png new file mode 100644 index 0000000000000000000000000000000000000000..9e40ac1dac0899e2ad9521d140b98ba1aea6b8d2 GIT binary patch literal 10481 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 T@-L`85x}0eFsk|kclZAQffrDG literal 0 HcmV?d00001 diff --git a/src/business-logic/core/places/common/entity/placeEntity.ts b/src/business-logic/core/places/common/entity/placeEntity.ts index b171c44..d6cb290 100644 --- a/src/business-logic/core/places/common/entity/placeEntity.ts +++ b/src/business-logic/core/places/common/entity/placeEntity.ts @@ -1,7 +1,14 @@ +export type QrPlace = { + oneTime: false; + placeId: string; + userId: string; + id: string; +}; + type Places = { placeType: string; name: string; - qr: null | string; + qr: null | QrPlace; id: string; parentId: string | null; }; diff --git a/src/business-logic/core/places/common/model/placesModel.ts b/src/business-logic/core/places/common/model/placesModel.ts index 9b73779..bb96839 100644 --- a/src/business-logic/core/places/common/model/placesModel.ts +++ b/src/business-logic/core/places/common/model/placesModel.ts @@ -1,4 +1,4 @@ -import Places from '../entity/placeEntity'; +import Places, { QrPlace } from '../entity/placeEntity'; class PlacesModel { private placesList: Places[]; @@ -16,6 +16,23 @@ class PlacesModel { getTitle(): string { return this.modelTitle; } + + private updatePlaces(updatedPlaces: Places[]) { + this.placesList = updatedPlaces; + } + + setQrFor(qrCodesToAdd: QrPlace[]): Places[] { + const updatedPlaces = this.placesList.map((place) => { + const relatedQrCode = qrCodesToAdd.find((qrItem) => qrItem.placeId === place.id); + + return { + ...place, + qr: relatedQrCode || null, + }; + }); + this.updatePlaces(updatedPlaces); + return updatedPlaces; + } } export default PlacesModel; diff --git a/src/business-logic/core/places/get-places/usecase/__test__/getPlacesUsecase.test.ts b/src/business-logic/core/places/get-places/usecase/__test__/getPlacesUsecase.test.ts index 947836c..cc702b1 100644 --- a/src/business-logic/core/places/get-places/usecase/__test__/getPlacesUsecase.test.ts +++ b/src/business-logic/core/places/get-places/usecase/__test__/getPlacesUsecase.test.ts @@ -3,16 +3,18 @@ import IGetPlacesRepo from '../../data/repository/IGetPlacesRepo'; import { GetPlacesRO } from '../../data/response-object/protocols'; import GettingPlacesUsecase from '../getPlaceUsecase'; -const mockedRO: GetPlacesRO = { - availableServices: [''], - createdAt: 'createdAt', - id: 'id', - name: 'name', - parentId: null, - placeType: 'continent', - updatedAt: 'updatedTime', - qr: null, -}; +const mockedRO: GetPlacesRO = [ + { + availableServices: [''], + createdAt: 'createdAt', + id: 'id', + name: 'name', + parentId: null, + placeType: 'continent', + updatedAt: 'updatedTime', + qr: null, + }, +]; const model = new PlacesModel(mockedRO); const mockedRepo: IGetPlacesRepo = jest.fn().mockImplementation(async () => model); diff --git a/src/driven/utils/components/modal/Modal.tsx b/src/driven/utils/components/modal/Modal.tsx new file mode 100644 index 0000000..11740d9 --- /dev/null +++ b/src/driven/utils/components/modal/Modal.tsx @@ -0,0 +1,42 @@ +/* eslint-disable no-unused-expressions */ +import React from 'react'; +import ReactDOM from 'react-dom'; + +export interface ModalInterface { + onCloseCallback?: () => unknown; +} +export default function Modal({ onCloseCallback, children }: ModalInterface & React.PropsWithChildren) { + const modalRef = React.useRef<HTMLDivElement>(null); + const el = React.useRef(document.createElement('div')); + + const closeModal = () => { + el.current.remove(); + if (typeof onCloseCallback !== 'undefined') onCloseCallback(); + }; + React.useEffect(() => { + const portal = document.getElementById('root'); + portal?.appendChild(el.current); + + return () => { + if (typeof onCloseCallback !== 'undefined') onCloseCallback(); + return el.current?.remove(); + }; + }, []); + return ReactDOM.createPortal( + <div + onClick={closeModal} + ref={modalRef} + className='fixed top-0 left-0 z-20 w-screen h-screen p-2 rounded-md text-black flex justify-center items-center' + > + <div + className='max-w-[60%] max-h-[90%] p-4 rounded-sm shadow-lg bg-white overflow-auto' + onClick={(e) => { + e.stopPropagation(); + }} + > + {children} + </div> + </div>, + el.current, + ); +} diff --git a/src/driven/utils/configs/appConfig.ts b/src/driven/utils/configs/appConfig.ts index 93bd570..b4742ae 100644 --- a/src/driven/utils/configs/appConfig.ts +++ b/src/driven/utils/configs/appConfig.ts @@ -30,6 +30,7 @@ export const apiUrls = { core: { getPlaces: `${baseApiUrl}${ENVs.apiGetPlaces}`, getUsers: `${baseApiUrl}${ENVs.apiGetUsers}`, + getQrs: `${baseApiUrl}${ENVs.apiQr}`, createUserAccount: `${baseApiUrl}${ENVs.apiCreateUserAccount}`, createUserProfile: `${baseApiUrl}${ENVs.apiCreateUserProfile}`, createMember: `${baseApiUrl}${ENVs.apiCreateMember}`, diff --git a/src/driven/utils/constants/assertUrls.ts b/src/driven/utils/constants/assertUrls.ts index 66c35ac..938b105 100644 --- a/src/driven/utils/constants/assertUrls.ts +++ b/src/driven/utils/constants/assertUrls.ts @@ -5,4 +5,5 @@ export const icons = { logoBlack: `${baseIconsUrl}logo-black.svg`, users: `${baseIconsUrl}users.svg`, createUser: `${baseIconsUrl}createuser.svg`, + qrcode: `${baseIconsUrl}qrcode.png`, }; diff --git a/src/driven/utils/constants/envs.ts b/src/driven/utils/constants/envs.ts index 102978c..428a48c 100644 --- a/src/driven/utils/constants/envs.ts +++ b/src/driven/utils/constants/envs.ts @@ -7,6 +7,7 @@ export const ENVs = { apiGetPlaces: process.env.VITE_API_PLACES, apiGetUsers: process.env.VITE_API_USERS, apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT, + apiQr: process.env.VITE_API_QR, apiCreateUserProfile: process.env.VITE_API_USERS_PROFILE, apiCreateMember: process.env.VITE_API_CREATE_MEMBER, }; diff --git a/src/driven/utils/constants/staticMessages.ts b/src/driven/utils/constants/staticMessages.ts index 3acc2a0..a666000 100644 --- a/src/driven/utils/constants/staticMessages.ts +++ b/src/driven/utils/constants/staticMessages.ts @@ -24,6 +24,10 @@ export const staticMessages = { createUser: 'user created successfully', createMember: 'member created successfully', }, + and: 'and', + canUseFor: 'can use for', + oneTime: 'one time', + multipleTimes: 'multiple times', }, service: { errors: { diff --git a/src/driving/application/core/common/table-row/infra/protocols.ts b/src/driving/application/core/common/table-row/infra/protocols.ts index c2a94de..df9424d 100644 --- a/src/driving/application/core/common/table-row/infra/protocols.ts +++ b/src/driving/application/core/common/table-row/infra/protocols.ts @@ -1,7 +1,9 @@ +import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity'; + export interface ITableRowInfra { selectedRowId: string; rowData: { - rowItemsTitle: (string | null)[]; + rowItemsTitle: (string | null | QrPlace)[]; rowId: string; }; setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; diff --git a/src/driving/application/core/common/table-row/view/TableRow.tsx b/src/driving/application/core/common/table-row/view/TableRow.tsx index 5156de4..7185fbc 100644 --- a/src/driving/application/core/common/table-row/view/TableRow.tsx +++ b/src/driving/application/core/common/table-row/view/TableRow.tsx @@ -9,10 +9,11 @@ export default function TableRowView(props: ITableRowProps) { const columns = rowItemsTitle.map((rowItemTitle, index) => { return ( <RowItem - key={(rowItemTitle || 'row') + index} + rowData={rowData} + key={((rowItemTitle as string) || 'row') + index} hasCheckbox={index === 0} isSelected={isSelected} - title={rowItemTitle} + title={rowItemTitle as string} /> ); }); diff --git a/src/driving/application/core/common/table-row/view/protocols.ts b/src/driving/application/core/common/table-row/view/protocols.ts index eeba1fb..e9c9058 100644 --- a/src/driving/application/core/common/table-row/view/protocols.ts +++ b/src/driving/application/core/common/table-row/view/protocols.ts @@ -1,7 +1,9 @@ +import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity'; + export interface ITableRowProps { isSelected: boolean; rowData: { - rowItemsTitle: (string | null)[]; + rowItemsTitle: (string | null | QrPlace)[]; rowId: string; }; setSelectedRowId: React.Dispatch<React.SetStateAction<string>>; diff --git a/src/driving/application/core/common/table-row/view/table-row-item/view/RowItem.tsx b/src/driving/application/core/common/table-row/view/table-row-item/view/RowItem.tsx index e15e71b..d01181f 100644 --- a/src/driving/application/core/common/table-row/view/table-row-item/view/RowItem.tsx +++ b/src/driving/application/core/common/table-row/view/table-row-item/view/RowItem.tsx @@ -1,13 +1,56 @@ -import React from 'react'; +/* eslint-disable import/no-extraneous-dependencies */ +import React, { useState } from 'react'; +import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity'; +import Modal from '~/driven/utils/components/modal/Modal'; +import { icons } from '~/driven/utils/constants/assertUrls'; +import { QRCodeCanvas } from 'qrcode.react'; +import { staticMessages } from '~/driven/utils/constants/staticMessages'; +import { ITableRowInfra } from '../../../infra/protocols'; interface IRowItemProp { - title: string | null; + title: string | null | QrPlace; hasCheckbox: boolean; isSelected: boolean; + rowData: ITableRowInfra['rowData']; +} + +function QrCodeReader(props: { QrCodeData: QrPlace; rowData: ITableRowInfra['rowData'] }) { + const { QrCodeData, rowData } = props; + const placeType = rowData.rowItemsTitle[1]; + const placeTitle = rowData.rowItemsTitle[0]; + const isOneTime = !QrCodeData.oneTime ? staticMessages.global.multipleTimes : staticMessages.global.oneTime; + + const message = `${placeType} ${placeTitle} ${staticMessages.global.and} ${staticMessages.global.canUseFor} ${isOneTime}`; + return <QRCodeCanvas id='qrCode' value={message} size={150} bgColor='#fff' level='H' />; +} + +function QrCodeButton(props: { QrCodeData: QrPlace; rowData: ITableRowInfra['rowData'] }) { + const { QrCodeData, rowData } = props; + const [isShowModal, setIsShowModal] = useState(false); + + if (!QrCodeData) return null; + return ( + <> + {isShowModal && ( + <Modal onCloseCallback={() => setIsShowModal(false)}> + <QrCodeReader rowData={rowData} QrCodeData={QrCodeData} /> + </Modal> + )} + <button + onClick={(e) => { + e.stopPropagation(); + setIsShowModal(true); + }} + className='w-full h-full mx-auto flex justify-center items-center' + > + <img className='w-6 h-6' src={icons.qrcode} alt='qrcode' /> + </button> + </> + ); } export default function RowItem(props: IRowItemProp) { - const { title, hasCheckbox, isSelected } = props; + const { title, hasCheckbox, isSelected, rowData } = props; return ( <td className={`px-1 py-2 ${isSelected ? 'bg-primary-100' : ''}`}> <div className='w-full flex'> @@ -20,7 +63,7 @@ export default function RowItem(props: IRowItemProp) { <span className={`${isSelected ? 'visible' : 'hidden'} transition-all`}>✓</span> </span> )} - {title} + {typeof title === 'string' ? title : <QrCodeButton rowData={rowData} QrCodeData={title as QrPlace} />} </div> </td> ); diff --git a/src/driving/application/core/places-list/infra/PlacesList.tsx b/src/driving/application/core/places-list/infra/PlacesList.tsx index b3d0422..571b93f 100644 --- a/src/driving/application/core/places-list/infra/PlacesList.tsx +++ b/src/driving/application/core/places-list/infra/PlacesList.tsx @@ -1,3 +1,5 @@ +/* eslint-disable consistent-return */ +/* eslint-disable no-underscore-dangle */ import React from 'react'; import getPlaces from '~/business-logic/core/places/get-places'; import getPlacesAdapter from '~/driven/adapters/get-places-adapter/getPlacesAdapter'; @@ -5,10 +7,29 @@ import PlacesModel from '~/business-logic/core/places/common/model/placesModel'; import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers'; import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator'; import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel'; +import { apiUrls } from '~/driven/utils/configs/appConfig'; +import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols'; +import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary'; +import { QrPlace } from '~/business-logic/core/places/common/entity/placeEntity'; import PlacesListView from '../view/PlacesListView'; import usePlacesListVM from '../viewmodel/placesListVM'; import placesListModel from '../model/placesListModel'; +type QrCodeResponse = { + one_time: false; + place_id: string; + user_id: string; + _id: string; +}[]; +const QrCodeRO = (response: QrCodeResponse): QrPlace[] => { + return response.map((qrCode) => ({ + id: qrCode._id, + oneTime: qrCode.one_time, + placeId: qrCode.place_id, + userId: qrCode.user_id, + })); +}; + const prepareTheLogicForModel = () => { const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater(); @@ -26,12 +47,43 @@ export interface IPlacesListProps { export default function PlacessList(props: IPlacesListProps) { const { selectedRowId, setSelectedRowId } = props; - const { getingPlacesLogic, url } = prepareTheLogicForModel(); - const placesModel = async () => await placesListModel(getingPlacesLogic); + const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater(); + const getQrCodes = async () => { + try { + // url + const apiUrl = apiUrls.core.getQrs; + // options + const apiOptions: HttpOptionsType = { + url: apiUrl, + }; + // request + const userToken = { + accessToken: userData.user?.adminUserData.accessToken || null, + refreshToken: userData.user?.adminUserData.refreshToken || null, + }; + const httpProvider = new HTTPPovider(userToken, accessTokenUpdateHandler, notLoginAuth); + const response = await httpProvider.request<QrCodeResponse>(apiOptions); + const qrCodeList = QrCodeRO(response); + return qrCodeList; + // update the query + } catch (error) { + console.log(error); + } + }; + + const { getingPlacesLogic, url } = prepareTheLogicForModel(); + const getPlacesWithQrLogic = async () => { + const placesList = await getingPlacesLogic(); + const qrCodesList = await getQrCodes(); + placesList.setQrFor(qrCodesList || []); + return placesList; + }; + const placesModel = async () => await placesListModel(getPlacesWithQrLogic); const useGetPlacesList = prepareStateManagementForVM<PlacesModel>(url, placesModel); const { placesData } = usePlacesListVM({ useGetPlacesList, }); + return <PlacesListView placesList={placesData} selectedRowId={selectedRowId} setSelectedRowId={setSelectedRowId} />; } diff --git a/src/driving/application/core/places-list/view/PlacesListView.tsx b/src/driving/application/core/places-list/view/PlacesListView.tsx index 8258417..8409eb1 100644 --- a/src/driving/application/core/places-list/view/PlacesListView.tsx +++ b/src/driving/application/core/places-list/view/PlacesListView.tsx @@ -1,7 +1,6 @@ import React, { useMemo } from 'react'; import { staticMessages } from '~/driven/utils/constants/staticMessages'; import Loading from '~/driven/utils/components/loading/Loading'; -import Places from '~/business-logic/core/places/common/entity/placeEntity'; import TableRow from '../../common/table-row'; import { IPlacesListProps } from './protocols'; @@ -33,7 +32,7 @@ export default function UsersListView(props: IPlacesListProps) { <Loading /> </div> ); - const tableTitles: Pick<Places, 'name' | 'placeType' | 'qr'> = { + const tableTitles = { name: staticMessages.global.title, placeType: staticMessages.global.placeType, qr: staticMessages.global.qrCode, diff --git a/src/driving/main/pages/index.tsx b/src/driving/main/pages/index.tsx index 8573c65..f2edfca 100644 --- a/src/driving/main/pages/index.tsx +++ b/src/driving/main/pages/index.tsx @@ -17,6 +17,7 @@ export default function index() { const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater(); const [error, setError] = useState<{ message: string; type: 'error' | 'success' }>({ message: '', type: 'error' }); const [isSubmitDisabled, setIsSubmitDisabled] = useState(true); + const onSubmitMember = async (e: React.FormEvent) => { e.preventDefault(); try {