Skip to content

Commit

Permalink
Merge pull request #31 from 4chain-AG/runtime-vars
Browse files Browse the repository at this point in the history
feat(BUX-112): runtime variables for bux-wallet frontend
  • Loading branch information
kuba-4chain authored Jul 26, 2023
2 parents a7976db + ddd68ab commit 39b357b
Show file tree
Hide file tree
Showing 33 changed files with 371 additions and 226 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/dev-dist
**/node_modules/
**/dist
.git
npm-debug.log
2 changes: 0 additions & 2 deletions .env.template

This file was deleted.

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ dist-ssr
# docker compose
data/
bux-wallet-backend.env.private

# overriden config
env-config.json
33 changes: 27 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
version: "3.9"

services:
bux-wallet-frontend:
build:
context: .
dockerfile: release/Dockerfile
container_name: bux-wallet-frontend
ports:
- "3002:80"
depends_on:
- bux-wallet-backend
# volumes:
# - '/host/path/to/env-config.json:/usr/share/nginx/html/env-config.json'


db:
image: postgres:15.2-alpine
volumes:
- ./data/sql/db:/var/lib/postgresql/data:Z
- pgdata:/var/lib/postgresql/data
# - ./data/sql/db:/var/lib/postgresql/data:Z
environment:
- POSTGRES_NAME=postgres
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
# Uncomment following lines if you need to check database (ex. for debugging)
# ports:
# - 5432:5432
# Uncomment following lines if you need to check database (ex. for debugging)
# ports:
# - 5432:5432
healthcheck:
test: ["CMD-SHELL", "sh -c 'pg_isready -U postgres -d postgres'"]
timeout: 5s
Expand All @@ -21,15 +35,22 @@ services:
image: 4chain/bux-wallet-backend:latest
environment:
DB_HOST: 'db'
# For running bux-server locally
# BUX_SERVER_URL: 'http://host.docker.internal:3003/v1'
BUX_SERVER_URL: 'https://bux.4chain.space/v1'
BUX_PAYMAIL_DOMAIN: '4chain.space'
env_file:
- bux-wallet-backend.env.private
# Maybe this will be needed to have working session with frontend proxy
# HTTP_SERVER_COOKIE_DOMAIN: 'localhost:3000'
ports:
- "8080:8080"
links:
- db
# For running bux-server locally
# extra_hosts:
# - "host.docker.internal:host-gateway"
depends_on:
db:
condition: service_healthy
volumes:
pgdata:
driver: local
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"backend": "docker compose pull bux-wallet-backend && docker compose up",
"backend": "docker compose pull bux-wallet-backend && docker compose up db bux-wallet-backend",
"preview": "vite preview"
},
"dependencies": {
Expand Down
4 changes: 4 additions & 0 deletions public/config.default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"apiUrl": "http://localhost:3002",
"paymailDomain": "4chain.space"
}
6 changes: 1 addition & 5 deletions release/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@ FROM node:18-alpine as build

WORKDIR /app

RUN addgroup --system app && adduser -S -G app app && \
chown -R app:app /app
RUN addgroup --system app && adduser --system app --ingroup app && chown -R app:app /app

USER app

ARG VITE_API_URL
ARG VITE_BUX_PAYMAIL_DOMAIN

ENV NODE_PATH=/node_modules
ENV PATH=$PATH:/node_modules/.bin

Expand Down
67 changes: 36 additions & 31 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { getUser, LoggedInUser } from '@/api'
import { Loader } from '@/components/Loader'
import { useEffect, useState } from 'react'
import { ErrorBar } from '@/components/ErrorBar'
import { useMountEffect } from '@/hooks'
import { useApiUrl } from './api/apiUrl'

const ROUTES = [
{
Expand Down Expand Up @@ -59,45 +59,50 @@ const ROUTES_AUTHENTICATED = [

export const App = () => {
const { authorization, setAuthorization } = useAuthorization()
const apiUrl = useApiUrl()
const navigate = useNavigate()
const [loading, setLoading] = useState(true)
const [errors, setError] = useState('')

const location = useLocation()

useMountEffect(() => {
getUser()
.then((response) => {
const currentUserData: LoggedInUser = {
email: response.email,
paymail: response.paymail,
balance: response.balance,
}
useEffect(() => {
setError('')
apiUrl &&
getUser(apiUrl)
.then((response) => {
const currentUserData: LoggedInUser = {
email: response.email,
paymail: response.paymail,
balance: response.balance,
}

if (currentUserData) {
setAuthorization(currentUserData)
setLoading(false)
}
})
.catch((error) => {
let errorMsg
if (error.response.status === 401 || error.response.status === 400) {
setAuthorization(null)
navigate('/')
setLoading(false)
return
}
if (currentUserData) {
setAuthorization(currentUserData)
setLoading(false)
}
})
.catch((error) => {
let errorMsg
if (error.response.status === 401 || error.response.status === 400) {
setAuthorization(null)
navigate('/')
setLoading(false)
return
}

if (error.response.status === 404) {
errorMsg = error.response.data + ". If you can't log in again, please contact our support or try again later!"
} else {
errorMsg = error.response.data ? error.response.data : 'Something went wrong... Please, try again later!'
}
if (error.response.status === 404) {
errorMsg =
error.response.data + ". If you can't log in again, please contact our support or try again later!"
} else {
errorMsg = error.response.data ? error.response.data : 'Something went wrong... Please, try again later!'
}

setError(errorMsg)
setLoading(false)
})
})
setError(errorMsg)
setLoading(false)
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [apiUrl])

useEffect(() => {
if (location) {
Expand Down
6 changes: 6 additions & 0 deletions src/api/apiUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useConfig } from '@/providers'

export const useApiUrl = () => {
const { config } = useConfig()
return config.apiUrl ? `${config.apiUrl}/api/v1` : undefined
}
5 changes: 0 additions & 5 deletions src/api/client.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/api/requests/GetTransactionDetails.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const getTransactionsDetails = async (transactionId: string) => {
const { data: response } = await axiosClient.get(`/transaction/${transactionId}`)
export const getTransactionsDetails = async (apiUrl: string, transactionId: string) => {
const { data: response } = await axios.get(`${apiUrl}/transaction/${transactionId}`)
return response
}
16 changes: 12 additions & 4 deletions src/api/requests/GetTransactions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const getTransactions = async (PAGE?: number, PAGE_SIZE?: number, ORDER?: string, SORT?: 'desc' | 'asc') => {
const { data: transactions } = await axiosClient.get(
`/transaction?page=${PAGE || 1}&page_size=${PAGE_SIZE || 10}&order=${ORDER || 'created_at'}&sort=${SORT || 'desc'}`
export const getTransactions = async (
apiUrl: string,
PAGE?: number,
PAGE_SIZE?: number,
ORDER?: string,
SORT?: 'desc' | 'asc'
) => {
const { data: transactions } = await axios.get(
`${apiUrl}/transaction?page=${PAGE || 1}&page_size=${PAGE_SIZE || 10}&order=${ORDER || 'created_at'}&sort=${
SORT || 'desc'
}`
)
return {
transactions,
Expand Down
6 changes: 3 additions & 3 deletions src/api/requests/GetUser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const getUser = async () => {
const { data: response } = await axiosClient.get('/user')
export const getUser = async (apiUrl: string) => {
const { data: response } = await axios.get(`${apiUrl}/user`)
return response
}
6 changes: 3 additions & 3 deletions src/api/requests/LoginUser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { User } from '@/api/types/user'
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const loginUser = async (data: User) => {
const { data: response } = await axiosClient.post('/sign-in', data, { withCredentials: true })
export const loginUser = async (apiUrl: string, data: User) => {
const { data: response } = await axios.post(`${apiUrl}/sign-in`, data, { withCredentials: true })
return response
}
6 changes: 3 additions & 3 deletions src/api/requests/Logout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const logoutUser = async () => {
await axiosClient.post('/sign-out')
export const logoutUser = async (apiUrl: string) => {
await axios.post(`${apiUrl}/sign-out`)
}
6 changes: 3 additions & 3 deletions src/api/requests/RegisterUser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RegisterNewUserDto } from '@/api/types/user'
import { axiosClient } from '@/api/client'
import axios from 'axios'

export const registerUser = async (data: RegisterNewUserDto) => {
const { data: response } = await axiosClient.post('/user', data)
export const registerUser = async (apiUrl: string, data: RegisterNewUserDto) => {
const { data: response } = await axios.post(`${apiUrl}/user`, data)
return response
}
6 changes: 3 additions & 3 deletions src/api/requests/SendTransaction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { axiosClient } from '@/api/client'
import { SendNewTransaction } from '@/api/types/transaction'
import axios from 'axios'

export const sendTransaction = async (data: SendNewTransaction) => {
const { data: response } = await axiosClient.post('/transaction', data)
export const sendTransaction = async (apiUrl: string, data: SendNewTransaction) => {
const { data: response } = await axios.post(`${apiUrl}/transaction`, data)
return response
}
50 changes: 27 additions & 23 deletions src/components/AccountSummary/AccountSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useEffect, useState } from 'react'
import { getUser } from '@/api'
import { Loader } from '@/components/Loader'
import { ErrorBar } from '@/components/ErrorBar'
import { useApiUrl } from '@/api/apiUrl'

interface CurrencyRates {
usd?: number
Expand All @@ -22,37 +23,40 @@ interface AccountDetails {

export const AccountSummary = () => {
const { autoupdate } = useAutoupdate()
const apiUrl = useApiUrl()
const [details, setDetails] = useState<AccountDetails | null>(null)
const [loading, setLoading] = useState<boolean>(false)
const [errors, setErrors] = useState<string>('')

useEffect(() => {
setLoading(true)
getUser()
.then((response) => {
const accountDetails = {
balance: response.balance,
email: response.email,
paymail: response.paymail,
}
setDetails(accountDetails)
})
.catch((error) => {
let errorMsg
setErrors('')
apiUrl &&
getUser(apiUrl)
.then((response) => {
const accountDetails = {
balance: response.balance,
email: response.email,
paymail: response.paymail,
}
setDetails(accountDetails)
})
.catch((error) => {
let errorMsg

if (error.response.status === 404) {
errorMsg =
"User's account details not found. If you can't log in again, please contact our support or try again later!"
} else {
errorMsg = error.response.data ? error.response.data : 'Something went wrong... Please, try again later!'
}
if (error.response.status === 404) {
errorMsg =
"User's account details not found. If you can't log in again, please contact our support or try again later!"
} else {
errorMsg = error.response.data ? error.response.data : 'Something went wrong... Please, try again later!'
}

setErrors(errorMsg)
})
.finally(() => {
setLoading(false)
})
}, [autoupdate])
setErrors(errorMsg)
})
.finally(() => {
setLoading(false)
})
}, [apiUrl, autoupdate])

return (
<DashboardTile tileTitle="Your total balance" paymail={details?.paymail} titleIcon={<AccountBalanceWalletIcon />}>
Expand Down
Loading

0 comments on commit 39b357b

Please sign in to comment.