diff --git a/.vscode/easycode.ignore b/.vscode/easycode.ignore new file mode 100644 index 00000000..7f86f293 --- /dev/null +++ b/.vscode/easycode.ignore @@ -0,0 +1,14 @@ +node_modules/ +dist/ +vendor/ +cache/ +.*/ +*.min.* +*.test.* +*.spec.* +*.bundle.* +*.bundle-min.* +*.log +infra/ +apps/website +apps/client \ No newline at end of file diff --git a/apps/admin/next.config.js b/apps/admin/next.config.js index 5cba8eae..84d0e949 100644 --- a/apps/admin/next.config.js +++ b/apps/admin/next.config.js @@ -1,7 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - transpilePackages: ['@sahil/lib', 'ui', '@sahil/configs', "@sahil/features"], + transpilePackages: ['@sahil/lib', 'ui', '@sahil/configs', "@sahil/features", "tsconfig", "eslint-config-custom"], images: { remotePatterns: [ { @@ -9,13 +9,9 @@ const nextConfig = { hostname: 'res.cloudinary.com', port: '', }, - { - protocol: 'https', - hostname: 'https://lh3.googleusercontent.com', - port: '', - }, ], }, + output: "standalone" }; module.exports = nextConfig; diff --git a/apps/admin/package.json b/apps/admin/package.json index 58bacac8..2008def6 100644 --- a/apps/admin/package.json +++ b/apps/admin/package.json @@ -9,16 +9,41 @@ "lint": "next lint" }, "dependencies": { + "@apollo/client": "^3.8.1", + "@apollo/react-hooks": "^4.0.0", + "@formkit/auto-animate": "^0.7.0", + "@hookform/resolvers": "^3.3.0", + "@react-google-maps/api": "^2.19.2", "@sahil/configs": "*", "@sahil/features": "*", "@sahil/lib": "*", + "@types/jsonwebtoken": "^9.0.5", + "apollo-link-ws": "^1.0.20", + "autoprefixer": "10.4.15", "daisyui": "^4.12.2", - "next": "14.2.3", + "date-fns": "^2.30.0", + "eslint": "8.47.0", + "eslint-config-custom": "*", + "eslint-config-next": "^14.2.3", + "graphql": "^16.8.0", + "graphql-ws": "^5.14.0", + "jsonwebtoken": "^9.0.2", + "next": "^14.2.3", "next-auth": "^4.24.7", "next-auth-hasura-adapter": "^2.0.0", + "postcss": "8.4.28", "react": "^18.3.1", "react-dom": "^18.3.1", - "ui": "*" + "react-hook-form": "^7.45.4", + "react-hot-toast": "^2.4.1", + "react-icons": "^4.12.0", + "subscriptions-transport-ws": "^0.11.0", + "swr": "^2.2.1", + "tailwindcss": "3.3.3", + "tsconfig": "*", + "ui": "*", + "zod": "3.21.4", + "zustand": "^4.4.1" }, "devDependencies": { "@types/node": "^20", diff --git a/apps/admin/src/config.ts b/apps/admin/src/config.ts new file mode 100644 index 00000000..7931068f --- /dev/null +++ b/apps/admin/src/config.ts @@ -0,0 +1,48 @@ +import { z } from 'zod'; + +const envSchema = z.object({ + // Server + SERVER_URL: z.string().url(), + + // Hasura + HASURA_GRAPHQL_CORS_DOMAIN: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT: z.string().url(), + NEXT_PUBLIC_HASURA_GRAPHQL_ADMIN_SECRET: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_WS: z.string().url(), + + // Auth + SECRET: z.string(), + NEXTAUTH_SECRET: z.string(), + NEXT_PUBLIC_NEXTAUTH_URL: z.string().url(), + + // APIs + NEXT_PUBLIC_GITHUB_SECRET: z.string(), + NEXT_PUBLIC_GITHUB_ID: z.string(), + NEXT_PUBLIC_GOOGLE_SECRET: z.string(), + NEXT_PUBLIC_GOOGLE_API_KEY: z.string().optional(), + NEXT_PUBLIC_GOOGLE_ID: z.string(), + + // Database + POSTGRES_USER: z.string(), + POSTGRES_PASSWORD: z.string(), + POSTGRES_DATABASE: z.string(), + + // App URLs + ADMIN_URL: z.string().url(), + AGENT_URL: z.string().url(), + CLIENT_URL: z.string().url(), + COURIER_URL: z.string().url(), + API_URL: z.string().url(), + + // Email + EMAIL_SERVER_USER: z.string(), + EMAIL_SERVER_PASSWORD: z.string(), + EMAIL_SERVER_HOST: z.string(), + EMAIL_SERVER_PORT: z.string(), + EMAIL_FROM: z.string().email(), + EMAIL_SERVER: z.string(), +}); + +const env = envSchema.parse(process.env); + +export default env; diff --git a/apps/admin/types.d.ts b/apps/admin/types.d.ts new file mode 100644 index 00000000..46cd38d3 --- /dev/null +++ b/apps/admin/types.d.ts @@ -0,0 +1,11 @@ +// https://github.com/nextauthjs/next-auth/discussions/536#discussioncomment-1932922 +import NextAuth, { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user: { + id: string; + address: string; + } & DefaultSession["user"]; + } +} diff --git a/apps/agent/src/Layout/layout.tsx b/apps/agent/src/Layout/layout.tsx index e3a53c71..fbd9a357 100644 --- a/apps/agent/src/Layout/layout.tsx +++ b/apps/agent/src/Layout/layout.tsx @@ -46,8 +46,8 @@ export default function Layout({ children, ...props }: LayoutProps) { }; return ( <> - {session?.user && ( -
diff --git a/apps/agent/src/pages/couriers/[courierId].tsx b/apps/agent/src/pages/couriers/[courierId].tsx index 3f447c1f..7091d6b8 100644 --- a/apps/agent/src/pages/couriers/[courierId].tsx +++ b/apps/agent/src/pages/couriers/[courierId].tsx @@ -1,4 +1,5 @@ import { CourierProfileOverview } from "@sahil/features/Couriers/components/CourierProfileOverview"; +import { Couriers } from "@sahil/lib/graphql/__generated__/graphql"; import { useRouter } from "next/router"; import { useFetchCourierByPK } from "@sahil/lib/hooks/couriers"; @@ -23,11 +24,11 @@ export default function CourierPage() { return

Loading...

; } + return ( - <>
- +
@@ -37,6 +38,5 @@ export default function CourierPage() {
- ); } diff --git a/apps/agent/types.d.ts b/apps/agent/types.d.ts index 46cd38d3..7248a741 100644 --- a/apps/agent/types.d.ts +++ b/apps/agent/types.d.ts @@ -4,8 +4,8 @@ import NextAuth, { DefaultSession } from "next-auth"; declare module "next-auth" { interface Session { user: { - id: string; - address: string; + id?: string; + address?: string; } & DefaultSession["user"]; } } diff --git a/apps/client/next.config.js b/apps/client/next.config.js index 5cba8eae..8582905a 100644 --- a/apps/client/next.config.js +++ b/apps/client/next.config.js @@ -16,6 +16,7 @@ const nextConfig = { }, ], }, + output: "standalone" }; module.exports = nextConfig; diff --git a/apps/client/package.json b/apps/client/package.json index db40ba68..75b5b4b8 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -8,17 +8,41 @@ "start": "next start" }, "dependencies": { + "@apollo/client": "^3.8.1", + "@apollo/react-hooks": "^4.0.0", + "@formkit/auto-animate": "^0.7.0", + "@hookform/resolvers": "^3.3.0", + "@react-google-maps/api": "^2.19.2", "@sahil/configs": "*", "@sahil/features": "*", "@sahil/lib": "*", + "@types/jsonwebtoken": "^9.0.5", + "apollo-link-ws": "^1.0.20", + "autoprefixer": "10.4.15", "daisyui": "^4.12.2", + "date-fns": "^2.30.0", + "eslint": "8.47.0", + "eslint-config-custom": "*", "eslint-config-next": "^14.2.3", + "graphql": "^16.8.0", + "graphql-ws": "^5.14.0", + "jsonwebtoken": "^9.0.2", "next": "^14.2.3", "next-auth": "^4.24.7", "next-auth-hasura-adapter": "^2.0.0", + "postcss": "8.4.28", "react": "^18.3.1", "react-dom": "^18.3.1", - "ui": "*" + "react-hook-form": "^7.45.4", + "react-hot-toast": "^2.4.1", + "react-icons": "^4.12.0", + "subscriptions-transport-ws": "^0.11.0", + "swr": "^2.2.1", + "tailwindcss": "3.3.3", + "tsconfig": "*", + "ui": "*", + "zod": "3.21.4", + "zustand": "^4.4.1" }, "devDependencies": { "@types/node": "^20", diff --git a/apps/client/src/config.ts b/apps/client/src/config.ts new file mode 100644 index 00000000..7931068f --- /dev/null +++ b/apps/client/src/config.ts @@ -0,0 +1,48 @@ +import { z } from 'zod'; + +const envSchema = z.object({ + // Server + SERVER_URL: z.string().url(), + + // Hasura + HASURA_GRAPHQL_CORS_DOMAIN: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT: z.string().url(), + NEXT_PUBLIC_HASURA_GRAPHQL_ADMIN_SECRET: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_WS: z.string().url(), + + // Auth + SECRET: z.string(), + NEXTAUTH_SECRET: z.string(), + NEXT_PUBLIC_NEXTAUTH_URL: z.string().url(), + + // APIs + NEXT_PUBLIC_GITHUB_SECRET: z.string(), + NEXT_PUBLIC_GITHUB_ID: z.string(), + NEXT_PUBLIC_GOOGLE_SECRET: z.string(), + NEXT_PUBLIC_GOOGLE_API_KEY: z.string().optional(), + NEXT_PUBLIC_GOOGLE_ID: z.string(), + + // Database + POSTGRES_USER: z.string(), + POSTGRES_PASSWORD: z.string(), + POSTGRES_DATABASE: z.string(), + + // App URLs + ADMIN_URL: z.string().url(), + AGENT_URL: z.string().url(), + CLIENT_URL: z.string().url(), + COURIER_URL: z.string().url(), + API_URL: z.string().url(), + + // Email + EMAIL_SERVER_USER: z.string(), + EMAIL_SERVER_PASSWORD: z.string(), + EMAIL_SERVER_HOST: z.string(), + EMAIL_SERVER_PORT: z.string(), + EMAIL_FROM: z.string().email(), + EMAIL_SERVER: z.string(), +}); + +const env = envSchema.parse(process.env); + +export default env; diff --git a/apps/client/src/pages/account/index.tsx b/apps/client/src/pages/account/index.tsx index f4384f68..bc629dec 100644 --- a/apps/client/src/pages/account/index.tsx +++ b/apps/client/src/pages/account/index.tsx @@ -1,9 +1,9 @@ import { BusinessProfileOverview, BusinessOrderHistory, -} from "@sahil/features/Businesses"; +} from "@sahil/features/businesses"; // import { useGetAccountBalance, useGetMomoAccountInfo } from "@/hooks/accounts"; -import { useFetchBusinessByPK } from "@/hooks/businesses"; +import { useFetchBusinessByPK } from "@sahil/lib/hooks/businesses"; import { Card, JoinGrid } from "ui"; import { useState } from "react"; import { diff --git a/apps/client/src/pages/checkout/index.tsx b/apps/client/src/pages/checkout/index.tsx deleted file mode 100644 index bcececcf..00000000 --- a/apps/client/src/pages/checkout/index.tsx +++ /dev/null @@ -1,268 +0,0 @@ -import { FC } from "react"; -import { useFetchProducts } from "@sahil/lib/hooks/products"; -import { Card, QuantityInput } from "ui"; -import { formatCost } from "@sahil/lib"; -import { useOrderItemsStore } from "@sahil/lib/hooks/formStores/useOrderItemsStore"; -import { formatCurrency } from "@sahil/lib"; -import Image from "next/image"; -import { useRouter } from "next/router"; -import { - HiOutlineShoppingCart, - HiOutlineReceiptPercent, -} from "react-icons/hi2"; -import { - useInitBusinessOrder, - useOrderValidSubscription, - usePlaceBusinessOrder, -} from "@/hooks/orders"; -import { Key, useEffect, useState } from "react"; -import { Order_Item } from "@sahil/lib/graphql/__generated__/graphql"; - -export const OrderItem = ({ - price, - quantity, - title, - mainImage, -}: { - price: number; - quantity: number; - title: string; - mainImage?: string; -}) => { - return ( -
-
- Movie -
-
-
-
-

{title}

-
-
- -
-
-

- {formatCurrency(price)} -

-
-
- ); -}; - -export const OrderItems = ({ items }: { items: any }) => { - console.log(items); - const { totalItems, totalCost } = items?.reduce( - ( - totals: { totalItems: any; totalCost: number }, - product: { quantity: number; price: number } - ) => ({ - totalItems: totals.totalItems + product.quantity, - totalCost: totals.totalCost + product.price * product.quantity, - }), - { - totalItems: 0, - totalCost: 0, - } - ); - - return ( - <> - -
    - {items?.map( - (item: { - id: Key | null | undefined; - name: string; - quantity: number; - price: number; - mainImage?: string; - }) => ( - - ) - )} -
-
- - ); -}; - -function calculateTotal(arr: Order_Item[]) { - // Initialize total items and total price - let totalItems = 0; - let totalPrice = 0; - - // Iterate through the array - for (const item of arr) { - // Add quantity to total items - totalItems += item.quantity; - - // Calculate subtotal for the current item - const subtotal = item.price * item.quantity; - - // Add subtotal to total price - totalPrice += subtotal; - } - - // Return an object with total items and total price - return { - totalItems, - totalPrice, - }; -} - -export default function CheckoutPage() { - const { - initOrder, - loading: initLoading, - error: initError, - } = useInitBusinessOrder(); - const { orderItems } = useOrderItemsStore((state) => state); - // @ts-ignore - const { totalItems, totalPrice } = calculateTotal(orderItems); - const [actionId, setActionId] = useState(); - const router = useRouter(); - - const onConfirmOrder = async () => { - const orderItemsForInsert = orderItems.map((item) => ({ - productId: item.productId, - quantity: item.quantity, - price: item.price, - })); - - const object = { - order_items: { data: orderItemsForInsert }, - //ToDo: User Auth user id instead of hard-coded value - customerId: "e87924e8-69e4-4171-bd89-0c8963e03d08", - }; - - try { - const result = await initOrder({ - variables: { - object, - }, - }); - console.log(result); - setActionId(result.data.insertBusinessOrder); - } catch (error) { - console.error(error); - } - }; - - return ( -
-
-
- -
-
-
- -
-
-

Items

-

{totalItems} items

-
-
-

Total

-

{formatCurrency(totalPrice)}

-
-
-
- -
- -
- -
- brand -
-
-
-
-
- ); -} - -const ProcessOrderRequest = ({ - actionId, -}: { - actionId: string | undefined; -}) => { - const { - placeOrder, - loading: orderLoading, - error: orderError, - } = usePlaceBusinessOrder(); - const { data, loading, error } = useOrderValidSubscription(actionId!); - const [placeOrderResult, setPlaceOrderResult] = useState(); - - useEffect(() => { - const addOrderToDB = async () => { - if (data && data.insertBusinessOrder && data.insertBusinessOrder.output) { - try { - const order = removeTypename(data.insertBusinessOrder.output.order); - console.log("Order to be placed:", order); - const result = await placeOrder({ - variables: { - object: order, - }, - }); - setPlaceOrderResult(result); - } catch (err) { - console.error("Error placing order:", err); - } - } - }; - - addOrderToDB(); - }, [data, placeOrder]); - - if (error) return

An error occurred while placing order

; - if (loading) return

Processing order...

; - - if (placeOrderResult) { - return

Order successfully placed

; - } - - return <>; -}; - -const removeTypename = (value: any): any => { - if (value === null || value === undefined || typeof value !== "object") { - return value; - } - if (Array.isArray(value)) { - return value.map((v) => removeTypename(v)); - } - type GenericObject = { [key: string]: any }; - - const newValue: GenericObject = {}; - for (const key in value) { - if (key !== "__typename") { - newValue[key] = removeTypename(value[key]); - } - } - return newValue; -}; diff --git a/apps/client/src/pages/orders/[orderId].tsx b/apps/client/src/pages/orders/[orderId].tsx index 123937d4..b3c671d0 100644 --- a/apps/client/src/pages/orders/[orderId].tsx +++ b/apps/client/src/pages/orders/[orderId].tsx @@ -8,7 +8,7 @@ import { } from "@sahil/features/Orders"; import { Tabs } from "ui"; -import { useFetchOrderByPK } from "@/hooks/orders"; +import { useFetchOrderByPK } from "@sahil/lib/hooks/orders"; import { useRouter } from "next/router"; export default function OrderPage() { @@ -26,7 +26,7 @@ export default function OrderPage() {
- + {true ? ( <> diff --git a/apps/client/types.d.ts b/apps/client/types.d.ts new file mode 100644 index 00000000..46cd38d3 --- /dev/null +++ b/apps/client/types.d.ts @@ -0,0 +1,11 @@ +// https://github.com/nextauthjs/next-auth/discussions/536#discussioncomment-1932922 +import NextAuth, { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user: { + id: string; + address: string; + } & DefaultSession["user"]; + } +} diff --git a/apps/courier/next.config.mjs b/apps/courier/next.config.js similarity index 74% rename from apps/courier/next.config.mjs rename to apps/courier/next.config.js index 3be6379d..84d0e949 100644 --- a/apps/courier/next.config.mjs +++ b/apps/courier/next.config.js @@ -1,7 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - transpilePackages: ['@sahil/lib', 'ui', '@sahil/configs', "@sahil/features"], + transpilePackages: ['@sahil/lib', 'ui', '@sahil/configs', "@sahil/features", "tsconfig", "eslint-config-custom"], images: { remotePatterns: [ { @@ -11,6 +11,7 @@ const nextConfig = { }, ], }, + output: "standalone" }; -export default nextConfig; +module.exports = nextConfig; diff --git a/apps/courier/package.json b/apps/courier/package.json index 9d6c5eab..64594538 100644 --- a/apps/courier/package.json +++ b/apps/courier/package.json @@ -8,17 +8,41 @@ "start": "next start" }, "dependencies": { + "@apollo/client": "^3.8.1", + "@apollo/react-hooks": "^4.0.0", + "@formkit/auto-animate": "^0.7.0", + "@hookform/resolvers": "^3.3.0", + "@react-google-maps/api": "^2.19.2", "@sahil/configs": "*", "@sahil/features": "*", "@sahil/lib": "*", + "@types/jsonwebtoken": "^9.0.5", + "apollo-link-ws": "^1.0.20", + "autoprefixer": "10.4.15", "daisyui": "^4.12.2", + "date-fns": "^2.30.0", + "eslint": "8.47.0", + "eslint-config-custom": "*", "eslint-config-next": "^14.2.3", + "graphql": "^16.8.0", + "graphql-ws": "^5.14.0", + "jsonwebtoken": "^9.0.2", "next": "^14.2.3", "next-auth": "^4.24.7", "next-auth-hasura-adapter": "^2.0.0", + "postcss": "8.4.28", "react": "^18.3.1", "react-dom": "^18.3.1", - "ui": "*" + "react-hook-form": "^7.45.4", + "react-hot-toast": "^2.4.1", + "react-icons": "^4.12.0", + "subscriptions-transport-ws": "^0.11.0", + "swr": "^2.2.1", + "tailwindcss": "3.3.3", + "tsconfig": "*", + "ui": "*", + "zod": "3.21.4", + "zustand": "^4.4.1" }, "devDependencies": { "@types/node": "^20", diff --git a/apps/courier/src/config.ts b/apps/courier/src/config.ts new file mode 100644 index 00000000..7931068f --- /dev/null +++ b/apps/courier/src/config.ts @@ -0,0 +1,48 @@ +import { z } from 'zod'; + +const envSchema = z.object({ + // Server + SERVER_URL: z.string().url(), + + // Hasura + HASURA_GRAPHQL_CORS_DOMAIN: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT: z.string().url(), + NEXT_PUBLIC_HASURA_GRAPHQL_ADMIN_SECRET: z.string(), + NEXT_PUBLIC_HASURA_GRAPHQL_WS: z.string().url(), + + // Auth + SECRET: z.string(), + NEXTAUTH_SECRET: z.string(), + NEXT_PUBLIC_NEXTAUTH_URL: z.string().url(), + + // APIs + NEXT_PUBLIC_GITHUB_SECRET: z.string(), + NEXT_PUBLIC_GITHUB_ID: z.string(), + NEXT_PUBLIC_GOOGLE_SECRET: z.string(), + NEXT_PUBLIC_GOOGLE_API_KEY: z.string().optional(), + NEXT_PUBLIC_GOOGLE_ID: z.string(), + + // Database + POSTGRES_USER: z.string(), + POSTGRES_PASSWORD: z.string(), + POSTGRES_DATABASE: z.string(), + + // App URLs + ADMIN_URL: z.string().url(), + AGENT_URL: z.string().url(), + CLIENT_URL: z.string().url(), + COURIER_URL: z.string().url(), + API_URL: z.string().url(), + + // Email + EMAIL_SERVER_USER: z.string(), + EMAIL_SERVER_PASSWORD: z.string(), + EMAIL_SERVER_HOST: z.string(), + EMAIL_SERVER_PORT: z.string(), + EMAIL_FROM: z.string().email(), + EMAIL_SERVER: z.string(), +}); + +const env = envSchema.parse(process.env); + +export default env; diff --git a/apps/courier/src/pages/deliveries/[deliveryId].tsx b/apps/courier/src/pages/deliveries/[deliveryId].tsx index 19450373..f8ddc8c9 100644 --- a/apps/courier/src/pages/deliveries/[deliveryId].tsx +++ b/apps/courier/src/pages/deliveries/[deliveryId].tsx @@ -102,17 +102,17 @@ export default function DeliveryPage() { { icon: , label: "Payment Method", - value: delivery?.payment_method || "N/A", + value: "N/A", }, { icon: , label: "Client", - value: delivery?.client?.name || "N/A", + value: "N/A", }, { icon: , label: "Status", - value: delivery?.status || "N/A", + value: "N/A", }, ]; @@ -129,7 +129,7 @@ export default function DeliveryPage() { return (
- +
{deliveryInfoItems.map((item, index) => ( @@ -151,14 +151,16 @@ export default function DeliveryPage() { Navigate Independently
- {delivery.status === 'pending' && ( + {/* { + + delivery.status === 'pending' && ( - )} + )} */}
, label: "Order Date", - value: formatDateTime(deliveryRequest?.created_at), + value: formatDateTime(deliveryRequest[0].created_at), }, { icon: , label: "Payment Method", value: "Cash on Delivery", }, - { - icon: , - label: "Client", - value: deliveryRequest?.business?.name as string, - }, ]; - const isSingleOrder = deliveryRequest.delivery_request_orders.length === 1; + const isSingleOrder = deliveryRequest[0].delivery_request_orders.length === 1; return (
- +
{orderInfoItems.map((item, index) => ( @@ -106,7 +101,7 @@ export default function RequestPage() {
diff --git a/apps/courier/types.d.ts b/apps/courier/types.d.ts new file mode 100644 index 00000000..46cd38d3 --- /dev/null +++ b/apps/courier/types.d.ts @@ -0,0 +1,11 @@ +// https://github.com/nextauthjs/next-auth/discussions/536#discussioncomment-1932922 +import NextAuth, { DefaultSession } from "next-auth"; + +declare module "next-auth" { + interface Session { + user: { + id: string; + address: string; + } & DefaultSession["user"]; + } +} diff --git a/docker-compose.yml b/docker-compose.yml index 72da5f0a..940bc066 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,6 +65,36 @@ services: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DATABASE=${POSTGRES_DATABASE} + # ADMIN + sahil-admin: + container_name: sahil-admin + build: + context: . + dockerfile: ./infra/docker/Dockerfile.admin + image: sahil-admin + restart: always + ports: + - '3003:3000' + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DATABASE=${POSTGRES_DATABASE} + + # COURIER + sahil-courier: + container_name: sahil-courier + build: + context: . + dockerfile: ./infra/docker/Dockerfile.courier + image: sahil-courier + restart: always + ports: + - '3004:3000' + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DATABASE=${POSTGRES_DATABASE} + #### LOCAL DEV ENVIRONMENTS #### # HASURA ENGINE @@ -115,9 +145,9 @@ services: retries: 5 start_period: 5s - # API - sahil-api-local-dev: - container_name: sahil-redis-postgres + # Redis + sahil-redis: + container_name: sahil-redis image: redis:6.0-alpine restart: always environment: diff --git a/infra/docker/Dockerfile.admin b/infra/docker/Dockerfile.admin new file mode 100644 index 00000000..127c2480 --- /dev/null +++ b/infra/docker/Dockerfile.admin @@ -0,0 +1,56 @@ +ARG NODE_VERSION=18.17.0 + +FROM node:${NODE_VERSION}-alpine As base + +FROM base AS builder +RUN apk add --no-cache libc6-compat +RUN apk update +# Set working directory +WORKDIR /app +RUN yarn global add turbo +COPY . . +RUN turbo prune admin --docker + +# Add lockfile and package.json's of isolated subworkspace +FROM base AS installer +RUN apk add --no-cache libc6-compat +RUN apk update +WORKDIR /app + +# Install the dependencies +COPY .gitignore .gitignore +COPY --from=builder /app/out/json/ . +COPY --from=builder /app/out/yarn.lock ./yarn.lock +RUN yarn install --network-timeout 100000 + +# Build the project +COPY --from=builder /app/out/full/ . +COPY turbo.json turbo.json + +# Remote caching +# ARG TURBO_TEAM +# ENV TURBO_TEAM=$TURBO_TEAM + +# ARG TURBO_TOKEN +# ENV TURBO_TOKEN=$TURBO_TOKEN + +# || true +RUN yarn turbo build --filter=admin... + +FROM base AS runner +WORKDIR /app + +# Don't run production as root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +USER nextjs + +COPY --from=installer /app/apps/admin/next.config.js . +COPY --from=installer /app/apps/admin/package.json . + +# Reduce image size +COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/standalone ./ +COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/.next/static ./apps/admin/.next/static +COPY --from=installer --chown=nextjs:nodejs /app/apps/admin/public ./apps/admin/public + +CMD node apps/admin/server.js \ No newline at end of file diff --git a/infra/docker/Dockerfile.courier b/infra/docker/Dockerfile.courier new file mode 100644 index 00000000..554c282a --- /dev/null +++ b/infra/docker/Dockerfile.courier @@ -0,0 +1,56 @@ +ARG NODE_VERSION=18.17.0 + +FROM node:${NODE_VERSION}-alpine As base + +FROM base AS builder +RUN apk add --no-cache libc6-compat +RUN apk update +# Set working directory +WORKDIR /app +RUN yarn global add turbo +COPY . . +RUN turbo prune courier --docker + +# Add lockfile and package.json's of isolated subworkspace +FROM base AS installer +RUN apk add --no-cache libc6-compat +RUN apk update +WORKDIR /app + +# Install the dependencies +COPY .gitignore .gitignore +COPY --from=builder /app/out/json/ . +COPY --from=builder /app/out/yarn.lock ./yarn.lock +RUN yarn install --network-timeout 100000 + +# Build the project +COPY --from=builder /app/out/full/ . +COPY turbo.json turbo.json + +# Remote caching +# ARG TURBO_TEAM +# ENV TURBO_TEAM=$TURBO_TEAM + +# ARG TURBO_TOKEN +# ENV TURBO_TOKEN=$TURBO_TOKEN + +# || true +RUN yarn turbo build --filter=courier... + +FROM base AS runner +WORKDIR /app + +# Don't run production as root +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs +USER nextjs + +COPY --from=installer /app/apps/courier/next.config.js . +COPY --from=installer /app/apps/courier/package.json . + +# Reduce image size +COPY --from=installer --chown=nextjs:nodejs /app/apps/courier/.next/standalone ./ +COPY --from=installer --chown=nextjs:nodejs /app/apps/courier/.next/static ./apps/courier/.next/static +COPY --from=installer --chown=nextjs:nodejs /app/apps/courier/public ./apps/courier/public + +CMD node apps/courier/server.js \ No newline at end of file diff --git a/packages/features/Couriers/components/CourierProfileOverview.tsx b/packages/features/Couriers/components/CourierProfileOverview.tsx index 54d56495..27166ae2 100644 --- a/packages/features/Couriers/components/CourierProfileOverview.tsx +++ b/packages/features/Couriers/components/CourierProfileOverview.tsx @@ -7,6 +7,7 @@ type Props = { }; export const CourierProfileOverview: FC = ({ courier }) => { + console.log(courier) return (
{courier?.avatar && } diff --git a/packages/features/Deliveries/ListDeliveryRequests.tsx b/packages/features/Deliveries/ListDeliveryRequests.tsx index 646e5f29..f39d06c9 100644 --- a/packages/features/Deliveries/ListDeliveryRequests.tsx +++ b/packages/features/Deliveries/ListDeliveryRequests.tsx @@ -4,14 +4,14 @@ import { useFetchDeliveryRequests } from "@sahil/lib/hooks/deliveries"; export const ListDeliveryRequests = () => { const { loading, error, data: deliveryRequests } = useFetchDeliveryRequests(); - if (loading) return

Loading...

; - if (error) return

Error :(

; + if (error) return ; return (
( )} diff --git a/packages/features/Orders/CustomProductsCatalogue.tsx b/packages/features/Orders/CustomProductsCatalogue.tsx index 9eb6be11..3157acbd 100644 --- a/packages/features/Orders/CustomProductsCatalogue.tsx +++ b/packages/features/Orders/CustomProductsCatalogue.tsx @@ -20,16 +20,22 @@ import { export const CustomProductsCatalogue = () => { const [offset, setOffset] = useState(0); - const { data, error, loading, productsCount } = useFetchProducts({ offset }); + const { + data: products, + error, + loading, + productsCount, + } = useFetchProducts({ offset }); - const { addOrderItem, orderItems, setProducts, products } = - useOrderItemsStore((state) => state); + const { addOrderItem, orderItems, setProducts } = useOrderItemsStore( + (state) => state + ); const orderItemsMap = new Map(orderItems.map((item) => [item.id, item])); useEffect(() => { - setProducts(data); - }, [data, setProducts]); + if (products) setProducts(products); + }, [products, setProducts]); if (error) { return ( @@ -91,20 +97,23 @@ export const CustomProductsCatalogue = () => { > - + {productsCount && ( + + )}
-

{productsCount.count} Items

+

{productsCount?.count} Items

- +
+ + + +

{message}

+
+ + +
); + export const ListLoadingState: FC = ({ heading = "Loading Data", message, @@ -51,9 +57,8 @@ export const List = ({ if (error) { return ( ); } diff --git a/packages/ui/components/Navbar.tsx b/packages/ui/components/Navbar.tsx index f24e3932..22dc9ecb 100644 --- a/packages/ui/components/Navbar.tsx +++ b/packages/ui/components/Navbar.tsx @@ -10,6 +10,7 @@ import { HiOutlineCog6Tooth, HiOutlineBell, } from "react-icons/hi2"; +import { useRouter } from "next/router"; type NavbarLink = { name: string; @@ -33,6 +34,8 @@ export const Navbar: FC = ({ onSignOut, user, }) => { + const router = useRouter(); + return (
@@ -56,7 +59,9 @@ export const Navbar: FC = ({
  • {icon && } {name} @@ -83,6 +88,8 @@ const Right = ({ onSignOut?: () => void; children?: ReactNode; }) => { + const router = useRouter(); + if (!user) { return (
    @@ -125,7 +132,10 @@ const Right = ({ {links.map(({ name, href, icon }) => { return (
  • - + {name}
  • @@ -133,7 +143,10 @@ const Right = ({ })}
  • - + Settings
  • diff --git a/turbo.json b/turbo.json index 255461b8..31937712 100644 --- a/turbo.json +++ b/turbo.json @@ -1,5 +1,5 @@ { - "globalDotEnv": [".env"], + "globalEnv": [".env"], "$schema": "https://turbo.build/schema.json", "globalDependencies": ["**/.env.*local", ".env.development", ".env.production"], "remoteCache": { @@ -30,4 +30,4 @@ "persistent": true } } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d4c68e6e..94526747 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4429,7 +4429,7 @@ escodegen@^2.1.0: optionalDependencies: source-map "~0.6.1" -eslint-config-next@14.2.3, eslint-config-next@^14.2.3: +eslint-config-next@^14.2.3: version "14.2.3" resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-14.2.3.tgz#2fb0f7c4eccda530a4b5054438162b2303786d4f" integrity sha512-ZkNztm3Q7hjqvB1rRlOX8P9E/cXRL9ajRcs8jufEtwMfTVYRqnmtnaSu57QqHyBlovMuiB8LEzfLBkh5RYV6Fg== @@ -6763,7 +6763,7 @@ next-auth@^4.24.7: preact-render-to-string "^5.1.19" uuid "^8.3.2" -next@14.2.3, next@^14.2.3: +next@^14.2.3: version "14.2.3" resolved "https://registry.yarnpkg.com/next/-/next-14.2.3.tgz#f117dd5d5f20c307e7b8e4f9c1c97d961008925d" integrity sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A== @@ -8590,7 +8590,7 @@ tailwindcss@3.3.3: resolve "^1.22.2" sucrase "^3.32.0" -tailwindcss@^3.3.0, tailwindcss@^3.4.1: +tailwindcss@^3.3.0: version "3.4.1" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.1.tgz#f512ca5d1dd4c9503c7d3d28a968f1ad8f5c839d" integrity sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==