diff --git a/.github/workflows/client.yml b/.github/workflows/client.yml new file mode 100644 index 00000000..c7c4a083 --- /dev/null +++ b/.github/workflows/client.yml @@ -0,0 +1,26 @@ +name: Deploy Client + +on: + push: + paths: + - "apps/client/**" + - "packages/db/**" + - "packages/order-queue/**" + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: SSH and deploy + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + echo "$SSH_PRIVATE_KEY" > keyfile + chmod 600 keyfile + ssh -o StrictHostKeyChecking=no -t -i keyfile ubuntu@ec2-184-73-25-89.compute-1.amazonaws.com "sudo bash /home/ubuntu/offchain-orderbook/apps/client/deploy.sh" diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml new file mode 100644 index 00000000..2dc7dcfb --- /dev/null +++ b/.github/workflows/server.yml @@ -0,0 +1,26 @@ +name: Deploy Express Backend + +on: + push: + paths: + - "apps/server/**" + - "packages/db/**" + - "packages/order-queue/**" + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: SSH and deploy + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + run: | + echo "$SSH_PRIVATE_KEY" > keyfile + chmod 600 keyfile + ssh -o StrictHostKeyChecking=no -t -i keyfile ubuntu@ec2-184-73-25-89.compute-1.amazonaws.com "sudo bash /home/ubuntu/offchain-orderbook/apps/server/deploy.sh" diff --git a/apps/client/app/(lobby)/portfolio/page.tsx b/apps/client/app/(lobby)/portfolio/page.tsx index 9ef7f11b..03a8b93d 100644 --- a/apps/client/app/(lobby)/portfolio/page.tsx +++ b/apps/client/app/(lobby)/portfolio/page.tsx @@ -1,11 +1,13 @@ "use client"; -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { useSession } from "next-auth/react"; import { redirect } from "next/navigation"; import { getTrades } from "@/actions/Trade/getTrades"; import Portfolio from "../../../components/landing/Portfolio"; import { getEventDetails } from "@/actions/Event/getEventDetails"; import axios from "axios"; +import {toast, Toaster} from "react-hot-toast" + export interface Trade { id: string; createdAt: Date; @@ -30,40 +32,36 @@ const Page = () => { const [loading, setLoading] = useState(true); const [portfolioData, setPortfolioData] = useState(null); const [tradesWithTitles, setTradesWithTitles] = useState([]); - const { data } = useSession(); - console.log(data?.user); - - useEffect(() => { - if (!data?.user) { - redirect("/api/auth/signin"); - } - }, [data?.user]); - const userId = "cm1r277l500178uzhh6kiewxa"; //data?.user.id; - - useEffect(() => { - if (userId) { - getPortfolioDetails(userId); - } - }, [userId]); + const { status } = useSession(); + const userId = "cm1r277l500178uzhh6kiewxa"; - async function getPortfolioDetails(userId: string) { + const getPortfolioDetails = useCallback(async (userId: string) => { setLoading(true); try { const portfolio = await getTrades(userId); - console.log(portfolio); - + console.log("portfolio", portfolio); + setPortfolioData(portfolio); - if (!portfolio) { - return; + if (portfolio) { + const updatedTrades = await fetchTitles(portfolio.trades); + setTradesWithTitles(updatedTrades); } - const updatedTrades = await fetchTitles(portfolio.trades); - setTradesWithTitles(updatedTrades); } catch (e) { console.log("Error fetching portfolio", e); } finally { setLoading(false); } - } + }, []); + + useEffect(() => { + if (status === "unauthenticated") { + redirect("/api/auth/signin"); + } + if (status === "authenticated" && userId) { + getPortfolioDetails(userId); + } + }, [status, userId, getPortfolioDetails]); + async function fetchTitles(trades: Trade[]) { const titles = await Promise.all( trades.map(async (trade) => { @@ -84,7 +82,7 @@ const Page = () => { ); if (tradeToSell) { const response = await axios.post( - "http://localhost:3001/v1/order/sell-order", + `${process.env.NEXT_PUBLIC_API_PREFIX_URL}/v1/order/sell-order`, { tradeId: tradeToSell.id, eventId: tradeToSell.eventId, @@ -93,13 +91,13 @@ const Page = () => { side: tradeToSell.side == "YES" ? "yes" : "no", } ); - window.alert(response.data.message || "Order sold successfully!"); + toast.success(response.data.message || "Order sold successfully!"); } else { - window.alert("Trade not found."); + toast.error("Trade not found."); } } catch (error) { console.error("Error selling order", error); - window.alert("Failed to sell order."); + toast.error("Failed to sell order."); } } }; @@ -126,6 +124,7 @@ const Page = () => { status :trade.status }))} /> + ); }; diff --git a/apps/client/components/landing/Orderbook.tsx b/apps/client/components/landing/Orderbook.tsx index 0414b8a7..1988a656 100644 --- a/apps/client/components/landing/Orderbook.tsx +++ b/apps/client/components/landing/Orderbook.tsx @@ -15,6 +15,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import LineChart from "../ui/line-chart"; import { getEventDetails } from "@/actions/Event/getEventDetails"; import { ArrowUpDown } from "lucide-react"; +import {toast, Toaster} from "react-hot-toast" interface OrderBookItem { @@ -77,12 +78,12 @@ export default function OrderBook({ eventId }: OrderBookProps) { } } fetchInitialData(); + }, [eventId]); useEffect(() => { const ws = new WebSocket("ws://localhost:3001"); ws.onopen = () => { - console.log("Connected to server"); ws.send(JSON.stringify({ eventId })); }; ws.onmessage = (event: MessageEvent) => { @@ -107,7 +108,7 @@ export default function OrderBook({ eventId }: OrderBookProps) { }; async function handleTrade() { const response = await axios.post( - "http://localhost:3001/v1/order/place-order", + `${process.env.NEXT_PUBLIC_API_PREFIX_URL}/v1/order/place-order`, { userId: "cm1r277l500178uzhh6kiewxa", eventId : eventId, @@ -116,11 +117,10 @@ export default function OrderBook({ eventId }: OrderBookProps) { price: tradePrice, } ); - console.log(response); if(response.status === 200){ - window.alert("Order placed successfully!") + toast.success("Order placed successfully!") }else{ - window.alert("Error placing order!") + toast.error("Error placing order!") } } @@ -348,6 +348,7 @@ export default function OrderBook({ eventId }: OrderBookProps) {

{description}

+ ); } diff --git a/apps/client/deploy.sh b/apps/client/deploy.sh new file mode 100644 index 00000000..2bd4a22d --- /dev/null +++ b/apps/client/deploy.sh @@ -0,0 +1,8 @@ +#!/bin/bash +export PATH=$PATH:/home/ubuntu/.nvm/versions/node/v18.20.4/bin + +cd /home/ubuntu/offchain-orderbook +git pull origin master +npm run build +pm2 stop client +pm2 start npm --name "client" -- run "start:client" \ No newline at end of file diff --git a/apps/server/deploy.sh b/apps/server/deploy.sh new file mode 100644 index 00000000..af0220ec --- /dev/null +++ b/apps/server/deploy.sh @@ -0,0 +1,8 @@ +#!/bin/bash +export PATH=$PATH:/home/ubuntu/.nvm/versions/node/v18.20.4/bin + +cd /home/ubuntu/offchain-orderbook +git pull origin master +npm run build +pm2 stop server +pm2 start npm --name "server" -- run "start:server" \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 00000000..db899556 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,37 @@ +events { + worker_connections 1024; +} + +http { + # Configuration for the Next.js app + server { + server_name opinix.live; + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + + listen 80; + } + + # Configuration for the Express backend + server { + server_name server.opinix.live; + + location / { + proxy_pass http://localhost:3001; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + + listen 80; + } +} diff --git a/package.json b/package.json index db70a200..ad4c518f 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "build": "turbo build", "dev": "turbo dev", "lint": "turbo lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"" + "format": "prettier --write \"**/*.{ts,tsx,md}\"", + "start:client": "cd apps/client && npm run start", + "start:server": "cd apps/server && node dist/index.js" }, "devDependencies": { "prettier": "^3.2.5",