├── backend ├── log │ └── .gitkeep ├── uploads │ └── abc.txt ├── downloads │ └── abc.txt ├── .gitignore ├── src │ ├── types │ │ ├── user.ts │ │ └── session.ts │ ├── services │ │ ├── languages │ │ │ ├── lang_email_success.ts │ │ │ ├── lang_email.ts │ │ │ └── lang_pdf.ts │ │ ├── platformAPIClient.ts │ │ ├── authen.ts │ │ └── aws-ses-service │ │ │ ├── index.ts │ │ │ └── templates │ │ │ └── send-invoice-success.html │ ├── models │ │ ├── users.ts │ │ └── invoices.ts │ └── environments.ts ├── docker │ └── processes.config.js ├── .env.example ├── Dockerfile └── package.json ├── .gitignore ├── frontend ├── src │ ├── react-app-env.d.ts │ ├── translation │ │ ├── fr │ │ │ └── translation.json │ │ ├── languages │ │ │ ├── home_text.ts │ │ │ ├── footerMenu_text.ts │ │ │ ├── history_text.ts │ │ │ ├── useMenu_text.ts │ │ │ ├── download_text.ts │ │ │ ├── previewInvoice.ts │ │ │ ├── payment_text.ts │ │ │ └── invoice_text.ts │ │ └── en │ │ │ └── translation.json │ ├── typedefs.d.ts │ ├── state │ │ ├── googleAuth │ │ │ ├── types.ts │ │ │ ├── actions.ts │ │ │ ├── index.ts │ │ │ └── reducer.ts │ │ ├── LanguageTrans │ │ │ ├── types.ts │ │ │ ├── actions.ts │ │ │ ├── index.ts │ │ │ └── reducer.ts │ │ ├── newInvoiceId │ │ │ ├── actions.ts │ │ │ ├── types.ts │ │ │ ├── index.ts │ │ │ └── reducer.ts │ │ ├── user │ │ │ ├── types.ts │ │ │ ├── actions.ts │ │ │ ├── index.ts │ │ │ └── reducer.ts │ │ ├── preview │ │ │ ├── index.ts │ │ │ ├── actions.ts │ │ │ ├── type.ts │ │ │ └── reducer.ts │ │ ├── global │ │ │ └── actions.ts │ │ ├── history │ │ │ ├── actions.ts │ │ │ ├── fetchData.ts │ │ │ ├── reducer.ts │ │ │ ├── type.ts │ │ │ └── index.ts │ │ ├── payment │ │ │ ├── actions.ts │ │ │ ├── reducer.ts │ │ │ ├── type.ts │ │ │ ├── index.ts │ │ │ └── fetchData.ts │ │ ├── invoice │ │ │ ├── actions.ts │ │ │ ├── types.ts │ │ │ └── reducer.ts │ │ └── index.ts │ ├── contexts │ │ ├── ToastsContext │ │ │ ├── index.tsx │ │ │ ├── Listener.tsx │ │ │ ├── types.ts │ │ │ └── Provider.tsx │ │ ├── Localization │ │ │ ├── index.tsx │ │ │ ├── useTranslation.ts │ │ │ ├── types.ts │ │ │ └── helpers.ts │ │ ├── Translate.tsx │ │ ├── InVoiceIdContext.tsx │ │ └── RefreshContext.tsx │ ├── config │ │ ├── index.ts │ │ ├── localization │ │ │ └── languages.ts │ │ ├── htttp.ts │ │ └── auth │ │ │ └── rules.tsx │ ├── views │ │ ├── Invoices │ │ │ ├── components │ │ │ │ ├── contentInvoice │ │ │ │ │ ├── SentContent.tsx │ │ │ │ │ └── ReceiveContent.tsx │ │ │ │ ├── SentTab.tsx │ │ │ │ ├── ReceiveTab.tsx │ │ │ │ ├── Header.tsx │ │ │ │ └── SubTab.tsx │ │ │ └── index.tsx │ │ ├── Register │ │ │ └── configLanguage.ts │ │ ├── SendInvoice │ │ │ ├── components │ │ │ │ └── ErrorMessage.tsx │ │ │ └── index.tsx │ │ ├── CreateInvoices │ │ │ ├── components │ │ │ │ └── HeaderCreateinVoice.tsx │ │ │ └── index.tsx │ │ ├── Home │ │ │ └── components │ │ │ │ └── ModalAlertLogin.tsx │ │ ├── UpdateInvoice │ │ │ └── index.tsx │ │ ├── History │ │ │ └── components │ │ │ │ └── Header.tsx │ │ └── Payment │ │ │ └── hook │ │ │ └── payment.ts │ ├── components │ │ ├── Toast │ │ │ ├── index.tsx │ │ │ ├── types.ts │ │ │ ├── DescriptionWithTx.tsx │ │ │ ├── ToastContainer.tsx │ │ │ └── Toast.tsx │ │ ├── Layout │ │ │ ├── Container.tsx │ │ │ ├── Flex.tsx │ │ │ ├── mainLayout.tsx │ │ │ ├── Column.tsx │ │ │ ├── PageFullWidth.tsx │ │ │ ├── Row.tsx │ │ │ └── Page.tsx │ │ ├── Svg │ │ │ ├── IconComponent.tsx │ │ │ ├── Icons │ │ │ │ ├── CloseIcon.tsx │ │ │ │ ├── AddIcon.tsx │ │ │ │ ├── AddIcon2.tsx │ │ │ │ ├── RefreshIcon.tsx │ │ │ │ ├── Lock.tsx │ │ │ │ ├── LoginIcon.tsx │ │ │ │ ├── AccountIcon.tsx │ │ │ │ ├── LogoutIcon.tsx │ │ │ │ ├── RemoveIcon.tsx │ │ │ │ ├── UserIcon.tsx │ │ │ │ ├── Home.tsx │ │ │ │ ├── Mail.tsx │ │ │ │ ├── DowloadIcon.tsx │ │ │ │ ├── EyeOpenIcon.tsx │ │ │ │ ├── Clocked.tsx │ │ │ │ ├── AccpetIcon.tsx │ │ │ │ ├── Invoice.tsx │ │ │ │ └── EyeCloseIcon.tsx │ │ │ ├── types.ts │ │ │ ├── Svg.tsx │ │ │ ├── index.tsx │ │ │ └── styles.tsx │ │ ├── Loader │ │ │ ├── Dots.tsx │ │ │ ├── PageLoader.tsx │ │ │ └── CircleLoader.tsx │ │ ├── Box │ │ │ ├── Box.tsx │ │ │ └── types.ts │ │ ├── Menu │ │ │ ├── config.ts │ │ │ ├── UserMenu │ │ │ │ ├── type.ts │ │ │ │ ├── AccpetModal.tsx │ │ │ │ ├── LogoutModal.tsx │ │ │ │ └── CopyAddress.tsx │ │ │ ├── utils.ts │ │ │ ├── index.tsx │ │ │ ├── Translate │ │ │ │ └── ModalLanguages.tsx │ │ │ ├── SubNav.tsx │ │ │ └── Footer.tsx │ │ ├── TranslateButton │ │ │ └── index.tsx │ │ ├── TranSlatorModal │ │ │ └── TranSlatorModal.tsx │ │ ├── BottomDrawer │ │ │ └── styles.ts │ │ ├── widgets │ │ │ └── Modal │ │ │ │ ├── ModalContext.tsx │ │ │ │ └── ModalV2.tsx │ │ ├── SuspenseWithChunkError │ │ │ └── index.tsx │ │ ├── DeleteModal │ │ │ └── index.tsx │ │ ├── ErrorMessages │ │ │ └── ErrorMessage.tsx │ │ └── Header │ │ │ └── index.tsx │ ├── routerHistory.ts │ ├── utils │ │ ├── getPortalRoot.ts │ │ ├── getThemeValue.ts │ │ ├── truncateHash.ts │ │ ├── sumTotalItems.ts │ │ ├── translateText.ts │ │ └── animationToolkit.ts │ ├── defaults.css │ ├── hooks │ │ ├── useToast.ts │ │ └── TranSlateHolder.ts │ ├── style │ │ ├── Global.tsx │ │ └── ResetCSS.tsx │ ├── i18n.tsx │ ├── Providers.tsx │ ├── Shop │ │ └── components │ │ │ ├── SignIn.tsx │ │ │ ├── Header.tsx │ │ │ └── ProductCard.tsx │ ├── firebase.config.js │ ├── index.tsx │ └── App.tsx ├── public │ ├── logo.png │ ├── favicon.ico │ ├── robots.txt │ ├── images │ │ ├── ImgPi │ │ │ ├── logo.png │ │ │ ├── Group.png │ │ │ ├── Header.png │ │ │ ├── LogoPi.png │ │ │ ├── Group1111.png │ │ │ ├── Header1.png │ │ │ ├── HeaderV2.png │ │ │ ├── calendar.png │ │ │ ├── fram-note.png │ │ │ ├── logoPib.png │ │ │ ├── pi-Frame.png │ │ │ ├── pi-Frame2.png │ │ │ ├── piSuccess.png │ │ │ ├── sentIcon.png │ │ │ ├── demo_videos.png │ │ │ ├── DeltaLab_logo.png │ │ │ ├── HeaderV2Test.png │ │ │ ├── PhisingWarning.png │ │ │ ├── Pibridge_ball.png │ │ │ ├── commingSoonPi.png │ │ │ ├── pi-revolution.png │ │ │ ├── receivedIcon.png │ │ │ ├── pi-Frame2Mobile.png │ │ │ ├── PhisingWarning2560.png │ │ │ ├── PhisingWarning680.png │ │ │ ├── PhisingWarning680V2.png │ │ │ └── PhisingWarningMobile.png │ │ └── pisuccess.png │ ├── validation-key.txt │ └── manifest.json ├── .env.development ├── .gitignore ├── tsconfig.json ├── README.md ├── docker │ ├── entrypoint.sh │ └── nginx.conf └── Dockerfile ├── doc └── img │ ├── api_key.png │ ├── register_app.PNG │ ├── sandbox_url.png │ ├── app_checklist.png │ ├── domain_verified.png │ ├── sandbox_firefox.png │ ├── developer_portal.png │ └── domain_verification.png ├── yarn.lock ├── .github └── workflows │ └── deploy.yml ├── reverse-proxy ├── Dockerfile └── docker │ ├── nginx.conf.template │ ├── entrypoint.sh │ └── nginx-ssl.conf.template ├── docker-compose.yml ├── .env.example └── LICENSE.md /backend/log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/uploads/abc.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/downloads/abc.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | docker-data 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /frontend/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /frontend/src/translation/fr/translation.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Bonjour" 3 | } -------------------------------------------------------------------------------- /frontend/src/typedefs.d.ts: -------------------------------------------------------------------------------- 1 | declare interface Window { 2 | Pi: any; 3 | } 4 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | /log/* 4 | !/log/.gitkeep 5 | .env -------------------------------------------------------------------------------- /doc/img/api_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/api_key.png -------------------------------------------------------------------------------- /doc/img/register_app.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/register_app.PNG -------------------------------------------------------------------------------- /doc/img/sandbox_url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/sandbox_url.png -------------------------------------------------------------------------------- /frontend/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/logo.png -------------------------------------------------------------------------------- /doc/img/app_checklist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/app_checklist.png -------------------------------------------------------------------------------- /doc/img/domain_verified.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/domain_verified.png -------------------------------------------------------------------------------- /doc/img/sandbox_firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/sandbox_firefox.png -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /frontend/src/state/googleAuth/types.ts: -------------------------------------------------------------------------------- 1 | export interface AccessTokenType { 2 | access_Token: any; 3 | } 4 | -------------------------------------------------------------------------------- /doc/img/developer_portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/developer_portal.png -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /doc/img/domain_verification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/doc/img/domain_verification.png -------------------------------------------------------------------------------- /frontend/src/state/LanguageTrans/types.ts: -------------------------------------------------------------------------------- 1 | export interface LanguageTransType { 2 | languageTrans?: any; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/logo.png -------------------------------------------------------------------------------- /frontend/public/images/pisuccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/pisuccess.png -------------------------------------------------------------------------------- /frontend/src/translation/languages/home_text.ts: -------------------------------------------------------------------------------- 1 | export const home_new:any = { 2 | "text_start_now": "Start now", 3 | } 4 | -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/Group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/Group.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/Header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/Header.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/LogoPi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/LogoPi.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/Group1111.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/Group1111.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/Header1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/Header1.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/HeaderV2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/HeaderV2.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/calendar.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/fram-note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/fram-note.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/logoPib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/logoPib.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/pi-Frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/pi-Frame.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/pi-Frame2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/pi-Frame2.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/piSuccess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/piSuccess.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/sentIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/sentIcon.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/demo_videos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/demo_videos.png -------------------------------------------------------------------------------- /frontend/src/contexts/ToastsContext/index.tsx: -------------------------------------------------------------------------------- 1 | 2 | export * from './Provider' 3 | export { default as ToastListener } from './Listener' 4 | -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/DeltaLab_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/DeltaLab_logo.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/HeaderV2Test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/HeaderV2Test.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/PhisingWarning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/PhisingWarning.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/Pibridge_ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/Pibridge_ball.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/commingSoonPi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/commingSoonPi.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/pi-revolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/pi-revolution.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/receivedIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/receivedIcon.png -------------------------------------------------------------------------------- /frontend/src/contexts/Localization/index.tsx: -------------------------------------------------------------------------------- 1 | 2 | export * from './Provider' 3 | export { default as useTranslation } from './useTranslation' 4 | -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/pi-Frame2Mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/pi-Frame2Mobile.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/PhisingWarning2560.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/PhisingWarning2560.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/PhisingWarning680.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/PhisingWarning680.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/PhisingWarning680V2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/PhisingWarning680V2.png -------------------------------------------------------------------------------- /frontend/public/images/ImgPi/PhisingWarningMobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pi-apps/ez-invoice/HEAD/frontend/public/images/ImgPi/PhisingWarningMobile.png -------------------------------------------------------------------------------- /frontend/public/validation-key.txt: -------------------------------------------------------------------------------- 1 | 8544299a5d2e97b3b62e27a84ad58802fc26c7db328cb7560814a392fbf251484e5c669bb42f33383fb2dfad3c436589ec6032868cd23b8b33b2b4a75ebedf1c -------------------------------------------------------------------------------- /frontend/src/translation/languages/footerMenu_text.ts: -------------------------------------------------------------------------------- 1 | export const footerMenu_text:any = { 2 | "text_home": "Home", 3 | "text_invoice": "Invoice", 4 | } 5 | -------------------------------------------------------------------------------- /frontend/src/state/newInvoiceId/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from "@reduxjs/toolkit"; 2 | 3 | export const setInvoiceIdRedux = createAction("invoiceId"); 4 | -------------------------------------------------------------------------------- /frontend/src/state/newInvoiceId/types.ts: -------------------------------------------------------------------------------- 1 | export interface InvoiceIdType { 2 | invoiceId?: any; 3 | } 4 | 5 | export interface LanguageTransType { 6 | languageTrans?: any; 7 | } 8 | -------------------------------------------------------------------------------- /frontend/src/state/LanguageTrans/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from "@reduxjs/toolkit"; 2 | 3 | export const setLanguageTransRedux = createAction("languageTrans"); 4 | -------------------------------------------------------------------------------- /frontend/.env.development: -------------------------------------------------------------------------------- 1 | PORT=3314 2 | REACT_APP_BACKEND_URL=http://localhost:8000 3 | REACT_APP_SANDBOX_SDK=true 4 | 5 | REACT_APP_APIKEY_GOOGLE="AIzaSyAMjXwmyrFo2Y_OVU_JXbXyIrTCZPiFWUs" 6 | 7 | GENERATE_SOURCEMAP=false -------------------------------------------------------------------------------- /frontend/src/config/index.ts: -------------------------------------------------------------------------------- 1 | export const MONTHS = [ "January", "February", "March", "April", "May", "June", 2 | "July", "August", "September", "October", "November", "December" ]; 3 | export const MAX_LENGTH_TERMS = 500 -------------------------------------------------------------------------------- /frontend/src/state/googleAuth/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from "@reduxjs/toolkit"; 2 | import { AccessTokenType } from "./types"; 3 | 4 | export const setAccessToken = createAction("loginGoogle"); 5 | -------------------------------------------------------------------------------- /frontend/src/views/Invoices/components/contentInvoice/SentContent.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const SentContent = () => { 4 | return ( 5 |
SentContent
6 | ) 7 | } 8 | 9 | export default SentContent -------------------------------------------------------------------------------- /frontend/src/views/Invoices/components/contentInvoice/ReceiveContent.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const ReceiveContent = () => { 4 | return
ReceiveContent
; 5 | }; 6 | 7 | export default ReceiveContent; 8 | -------------------------------------------------------------------------------- /frontend/src/views/Register/configLanguage.ts: -------------------------------------------------------------------------------- 1 | export const datamapoption = [ 2 | { 3 | label: "EN", 4 | value: 'en', 5 | }, 6 | { 7 | label: "VI", 8 | value: 'vi', 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /frontend/src/components/Toast/index.tsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | export { default as ToastContainer } from './ToastContainer' 4 | export { types as toastTypes } from './types' 5 | export type { ToastContainerProps, Toast, Types as ToastTypes } from './types' 6 | -------------------------------------------------------------------------------- /frontend/src/routerHistory.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserHistory } from 'history' 2 | 3 | // Manually create the history object so we can access outside the Router e.g. in modals 4 | const history = createBrowserHistory() 5 | 6 | export default history 7 | -------------------------------------------------------------------------------- /frontend/src/state/user/types.ts: -------------------------------------------------------------------------------- 1 | export interface UserType { 2 | uid: string; 3 | username: string; 4 | firstName: string; 5 | lastName: string; 6 | email: string; 7 | roles: Array; 8 | language: string; 9 | accessToken: string; 10 | } 11 | -------------------------------------------------------------------------------- /frontend/src/utils/getPortalRoot.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 2 | const getPortalRoot = () => typeof window !== "undefined" && (document.getElementById("portal-root") ?? document.body); 3 | 4 | export default getPortalRoot; 5 | -------------------------------------------------------------------------------- /frontend/src/utils/getThemeValue.ts: -------------------------------------------------------------------------------- 1 | import get from "lodash/get"; 2 | import { DefaultTheme } from "styled-components"; 3 | 4 | const getThemeValue = (theme: DefaultTheme, path: string, fallback?: any): string => 5 | get(theme, path, fallback); 6 | 7 | export default getThemeValue; 8 | -------------------------------------------------------------------------------- /frontend/src/state/preview/index.ts: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { AppState } from "state"; 3 | 4 | export const GetDataPreview = () => { 5 | const dataPreview = useSelector( 6 | (state) => state.preview) 7 | return dataPreview; 8 | }; -------------------------------------------------------------------------------- /backend/src/types/user.ts: -------------------------------------------------------------------------------- 1 | import { ObjectId } from "mongodb"; 2 | 3 | export interface UserData { 4 | _id: ObjectId, 5 | firstName: string, 6 | lastName: string, 7 | username: string, 8 | uid: string, 9 | roles: Array, 10 | accessToken: string, 11 | isActive: boolean 12 | } 13 | -------------------------------------------------------------------------------- /frontend/src/defaults.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | } 4 | 5 | h1, h2, h3 { 6 | margin-top: 0; 7 | margin-bottom: 16px; 8 | } 9 | 10 | h4, h5, h6 { 11 | margin-top: 0; 12 | margin-bottom: 8px; 13 | } 14 | 15 | *, *::before, *::after { 16 | box-sizing: border-box; 17 | } 18 | -------------------------------------------------------------------------------- /frontend/src/translation/languages/history_text.ts: -------------------------------------------------------------------------------- 1 | export const history_text:any = { 2 | "text_no_data": "No Data", 3 | 4 | "text_history": "History", 5 | "text_let_ezinvoice_account": "Last 6 latest invoices", 6 | "text_export": "Export", 7 | "text_new_invoice": "New invoice", 8 | } 9 | -------------------------------------------------------------------------------- /backend/src/services/languages/lang_email_success.ts: -------------------------------------------------------------------------------- 1 | export const lang_email_success:any = { 2 | "text_new_invoice": "New Payment Received", 3 | "text_sent_invoice": "has paid an invoice", 4 | "text_invoice_no": "Invoice", 5 | "text_invoice_total": "Total", 6 | "text_pay": "View Detail" 7 | } 8 | -------------------------------------------------------------------------------- /backend/src/types/session.ts: -------------------------------------------------------------------------------- 1 | import { UserData } from "./user"; 2 | 3 | // https://stackoverflow.com/questions/65108033/property-user-does-not-exist-on-type-session-partialsessiondata 4 | declare module 'express-session' { 5 | export interface SessionData { 6 | currentUser: UserData | null, 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /frontend/src/views/Invoices/components/SentTab.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SentContent from './contentInvoice/SentContent' 3 | 4 | const SentTab = () => { 5 | return ( 6 |
7 | sent tab 8 | 9 |
10 | ) 11 | } 12 | 13 | export default SentTab -------------------------------------------------------------------------------- /backend/src/services/platformAPIClient.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import env from "../environments"; 3 | 4 | const platformAPIClient = axios.create({ 5 | baseURL: env.platform_api_url, 6 | timeout: 20000, 7 | headers: { 'Authorization': `Key ${env.pi_api_key}` } 8 | }); 9 | 10 | export default platformAPIClient; -------------------------------------------------------------------------------- /frontend/src/views/Invoices/components/ReceiveTab.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReceiveContent from './contentInvoice/ReceiveContent' 3 | 4 | const ReceiveTab = () => { 5 | return ( 6 |
7 | Receive tab 8 | 9 |
10 | ) 11 | } 12 | 13 | export default ReceiveTab -------------------------------------------------------------------------------- /frontend/src/utils/truncateHash.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Truncate a transaction or address hash 3 | */ 4 | 5 | 6 | const truncateHash = (address: string, startLength = 4, endLength = 4) => { 7 | return `${address.substring(0, startLength)}...${address.substring(address.length - endLength)}` 8 | } 9 | 10 | export default truncateHash 11 | -------------------------------------------------------------------------------- /backend/docker/processes.config.js: -------------------------------------------------------------------------------- 1 | // PM2 config file to run the app in production mode. 2 | // Make sure the name of this file ends with config.js 3 | 4 | module.exports = { 5 | apps: [{ 6 | name: "demoapp-backend", 7 | script: "/usr/src/app/build/index.js", 8 | exec_mode: "cluster", 9 | instances: 4, 10 | }] 11 | } -------------------------------------------------------------------------------- /frontend/src/state/user/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from '@reduxjs/toolkit' 2 | import { UserType } from "./types" 3 | 4 | export const setUser = createAction('user') 5 | export const accessToken = createAction<{accessToken:string}>('user/getAccessToken') 6 | export const isLoading = createAction<{isLoading:boolean}>('user/isLoading') -------------------------------------------------------------------------------- /frontend/src/state/newInvoiceId/index.ts: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { AppDispatch, AppState } from "state"; 3 | 4 | export const getInvoiceId = () => { 5 | const newInvoiceId = useSelector( 6 | (state) => state.invoiceId 7 | ); 8 | return newInvoiceId.invoiceId; 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /frontend/src/components/Layout/Container.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Box } from '@devfedeltalabs/pibridge_uikit' 3 | 4 | 5 | 6 | const Container: React.FC = ({ children, ...props }) => ( 7 | 8 | {children} 9 | 10 | ) 11 | 12 | export default Container 13 | -------------------------------------------------------------------------------- /frontend/src/state/global/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from '@reduxjs/toolkit' 2 | 3 | 4 | 5 | // fired once when the app reloads but before the app renders 6 | // allows any updates to be applied to store data loaded from localStorage 7 | export const updateVersion = createAction('global/updateVersion') 8 | 9 | export default updateVersion 10 | -------------------------------------------------------------------------------- /frontend/src/state/LanguageTrans/index.ts: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { AppDispatch, AppState } from "state"; 3 | 4 | export const getLanguageTrans = () => { 5 | const newInvoiceId = useSelector( 6 | (state) => state.languageTrans 7 | ); 8 | return newInvoiceId.languageTrans; 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /frontend/src/state/googleAuth/index.ts: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { AppDispatch, AppState } from "state"; 3 | 4 | export const getAccessTokenAuth = () => { 5 | const accessTokenAuth = useSelector( 6 | (state) => state.loginGoogle 7 | ); 8 | return accessTokenAuth.accessTokenAuth; 9 | }; 10 | -------------------------------------------------------------------------------- /frontend/src/state/preview/actions.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from '@reduxjs/toolkit' 2 | import { PreviewType } from './type' 3 | 4 | export const getDataPreview = createAction('preview/getDataPreview') 5 | export const getDataImages = createAction<{images: any}>('preview/getDataImages') 6 | export const fetchStatusPreview = createAction<{isPreview: boolean}>('preview/fetchStatusPreview') -------------------------------------------------------------------------------- /backend/src/services/languages/lang_email.ts: -------------------------------------------------------------------------------- 1 | export const lang_email:any = { 2 | "text_new_invoice": "New Invoice", 3 | "text_sent_invoice": "has sent you a new invoice", 4 | "text_invoice_no": "Invoice", 5 | "text_invoice_total": "Total", 6 | "text_pay": "Pay Now", 7 | "text_other_way": "If above button doesn't work, try copying this following link to Pi Browser to pay the invoice" 8 | } -------------------------------------------------------------------------------- /frontend/src/hooks/useToast.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import { ToastsContext } from 'contexts/ToastsContext' 3 | 4 | 5 | 6 | const useToast = () => { 7 | const toastContext = useContext(ToastsContext) 8 | 9 | if (toastContext === undefined) { 10 | throw new Error('Toasts context undefined') 11 | } 12 | 13 | return toastContext 14 | } 15 | 16 | export default useToast 17 | -------------------------------------------------------------------------------- /frontend/src/config/localization/languages.ts: -------------------------------------------------------------------------------- 1 | import { Language } from '@devfedeltalabs/pibridge_uikit' 2 | 3 | export const EN: Language = { locale: 'en-US', language: 'English', code: 'en' } 4 | export const VI: Language = { locale: 'vi-VN', language: 'Tiếng Việt', code: 'vi' } 5 | 6 | export const languages = { 7 | 'en-US': EN, 8 | 'vi-VN': VI 9 | } 10 | 11 | export const languageList = Object.values(languages) 12 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /frontend/src/components/Layout/Flex.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components' 2 | 3 | 4 | 5 | const FlexLayout = styled.div` 6 | display: flex; 7 | justify-content: center; 8 | flex-wrap: wrap; 9 | & > * { 10 | min-width: 280px; 11 | // max-width: 31.5%; 12 | max-width: 395px; 13 | width: 100%; 14 | margin: 0 8px; 15 | margin-bottom: 32px; 16 | } 17 | ` 18 | 19 | export default FlexLayout 20 | -------------------------------------------------------------------------------- /frontend/src/utils/sumTotalItems.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from 'bignumber.js'; 2 | 3 | export const totalPrice = (fields) => { 4 | return fields?.reduce((sum, i) => { 5 | if(i.price === undefined || i.quantity === undefined){ 6 | return 0 7 | } else{ 8 | return ( 9 | new BigNumber(sum).plus(new BigNumber(i.price).multipliedBy(i.quantity).toString()).toString() 10 | ) 11 | } 12 | },0) 13 | } -------------------------------------------------------------------------------- /frontend/src/contexts/Localization/useTranslation.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import { LanguageContext } from './Provider' 3 | 4 | 5 | 6 | const useTranslation = () => { 7 | const languageContext = useContext(LanguageContext) 8 | 9 | if (languageContext === undefined) { 10 | throw new Error('Language context is undefined') 11 | } 12 | 13 | return languageContext 14 | } 15 | 16 | export default useTranslation 17 | -------------------------------------------------------------------------------- /frontend/src/contexts/ToastsContext/Listener.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ToastContainer } from 'components/Toast' 3 | import useToast from 'hooks/useToast' 4 | 5 | 6 | 7 | const ToastListener = () => { 8 | const { toasts, remove } = useToast() 9 | 10 | const handleRemove = (id: string) => remove(id) 11 | 12 | return 13 | } 14 | 15 | export default ToastListener 16 | -------------------------------------------------------------------------------- /frontend/src/contexts/ToastsContext/types.ts: -------------------------------------------------------------------------------- 1 | import { Toast } from 'components/Toast' 2 | 3 | 4 | 5 | type ToastSignature = (title: Toast['title'], description?: Toast['description']) => void 6 | export interface ToastContextApi { 7 | toasts: Toast[] 8 | clear: () => void 9 | remove: (id: string) => void 10 | toastError: ToastSignature 11 | toastInfo: ToastSignature 12 | toastSuccess: ToastSignature 13 | toastWarning: ToastSignature 14 | } 15 | -------------------------------------------------------------------------------- /frontend/src/components/Layout/mainLayout.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | import { Outlet } from "react-router-dom" 3 | import styled from "styled-components" 4 | import Footer from "../Footer" 5 | import Header from "../Header" 6 | 7 | const Wrapper = styled.div`` 8 | 9 | const MainLayout = () => { 10 | 11 | return 12 |
13 | 14 |