Skip to content

Commit

Permalink
Add order preview
Browse files Browse the repository at this point in the history
  • Loading branch information
andrii-balitskyi committed Oct 18, 2024
1 parent a60c997 commit 4f374e9
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 72 deletions.
3 changes: 2 additions & 1 deletion fake-snippets-api/lib/db/schema.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AnyCircuitElement } from "circuit-json"
import { z } from "zod"

export const snippetSchema = z.object({
Expand Down Expand Up @@ -65,7 +66,7 @@ export const orderSchema = z.object({
should_be_blank_pcb: z.boolean(),
should_include_stencil: z.boolean(),
jlcpcb_order_params: z.record(z.any()),
circuit_json: z.record(z.any()),
circuit_json: z.array(z.record(z.any())),
created_at: z.string(),
updated_at: z.string(),
})
Expand Down
16 changes: 9 additions & 7 deletions fake-snippets-api/lib/db/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,15 @@ export const SquareWaveModule = () => (
should_be_blank_pcb: false,
should_include_stencil: false,
jlcpcb_order_params: {},
circuit_json: {
type: "source_component",
ftype: "simple_resistor",
source_component_id: "source_component_1",
name: "R1",
resistane: "1k",
},
circuit_json: [
{
type: "source_component",
ftype: "simple_resistor",
source_component_id: "source_component_1",
name: "R1",
resistane: "1k",
},
],
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
})
Expand Down
2 changes: 1 addition & 1 deletion fake-snippets-api/routes/api/orders/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default withRouteSpec({
methods: ["POST"],
auth: "session",
jsonBody: z.object({
circuit_json: z.record(z.any()),
circuit_json: z.array(z.record(z.any())),
}),
jsonResponse: z.object({
order: orderSchema,
Expand Down
2 changes: 1 addition & 1 deletion fake-snippets-api/routes/api/orders/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default withRouteSpec({
should_be_blank_pcb: z.boolean().optional(),
should_include_stencil: z.boolean().optional(),
jlcpcb_order_params: z.record(z.any()).optional(),
circuit_json: z.record(z.any()).optional(),
circuit_json: z.array(z.record(z.any())).optional(),
}),
}),
jsonResponse: z.object({
Expand Down
16 changes: 9 additions & 7 deletions fake-snippets-api/tests/fixtures/get-test-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@ const seedDatabase = (db: DbClient) => {
should_be_blank_pcb: false,
should_include_stencil: false,
jlcpcb_order_params: {},
circuit_json: {
type: "source_component",
ftype: "simple_resistor",
source_component_id: "source_component_1",
name: "R1",
resistance: "1k",
},
circuit_json: [
{
type: "source_component",
ftype: "simple_resistor",
source_component_id: "source_component_1",
name: "R1",
resistance: "1k",
},
],
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
})
Expand Down
2 changes: 1 addition & 1 deletion fake-snippets-api/tests/routes/order_files/upload.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test("upload order file with for_provider", async () => {
const { axios, db } = await getTestServer()

const orderResponse = await axios.post("/api/orders/create", {
circuit_json: { test: "circuit data" },
circuit_json: [{ test: "circuit data" }],
})

const orderId = orderResponse.data.order.order_id
Expand Down
61 changes: 61 additions & 0 deletions src/components/OrderPreviewContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from "react"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { PCBViewer } from "@tscircuit/pcb-viewer"
import { CadViewer } from "@tscircuit/3d-viewer"
import { CircuitJsonTableViewer } from "./TableViewer/CircuitJsonTableViewer"
import { AnyCircuitElement } from "circuit-json"

interface OrderPreviewContentProps {
circuitJson: AnyCircuitElement[] | null
className?: string
}

export const OrderPreviewContent: React.FC<OrderPreviewContentProps> = ({
circuitJson,
className,
}) => {
return (
<div className={className}>
<Tabs defaultValue="pcb" className="w-full">
<TabsList>
<TabsTrigger value="pcb">PCB</TabsTrigger>
<TabsTrigger value="cad">3D</TabsTrigger>
<TabsTrigger value="table">JSON</TabsTrigger>
</TabsList>
<TabsContent value="pcb">
<div className="h-[500px]">
{circuitJson ? (
<PCBViewer soup={circuitJson} />
) : (
<div className="flex items-center justify-center h-full bg-gray-100">
No PCB data available
</div>
)}
</div>
</TabsContent>
<TabsContent value="cad">
<div className="h-[500px]">
{circuitJson ? (
<CadViewer soup={circuitJson as any} />
) : (
<div className="flex items-center justify-center h-full bg-gray-100">
No 3D data available
</div>
)}
</div>
</TabsContent>
<TabsContent value="table">
<div className="h-[500px] overflow-auto">
{circuitJson ? (
<CircuitJsonTableViewer elements={circuitJson} />
) : (
<div className="flex items-center justify-center h-full bg-gray-100">
No JSON data available
</div>
)}
</div>
</TabsContent>
</Tabs>
</div>
)
}
120 changes: 66 additions & 54 deletions src/pages/view-order.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Footer from "@/components/Footer"
import { Order } from "fake-snippets-api/lib/db/schema"
import { Link, useParams } from "wouter"
import { Button } from "@/components/ui/button"
import { OrderPreviewContent } from "@/components/OrderPreviewContent"
import { AnyCircuitElement } from "circuit-json"

export const ViewOrderPage = () => {
const { orderId } = useParams()
Expand Down Expand Up @@ -41,64 +43,74 @@ export const ViewOrderPage = () => {
return (
<div>
<Header />
<div className="container mx-auto px-4 py-8">
<div className="container mx-auto px-4 py-4">
<h1 className="text-3xl font-bold mb-6">Order Details</h1>
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
<div className="px-4 py-5 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
Order #{order.order_id}
</h3>
<p className="mt-1 max-w-2xl text-sm text-gray-500">
Created at: {new Date(order.created_at).toLocaleString()}
</p>
</div>
<div className="border-t border-gray-200">
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Status</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_shipped ? "Shipped" : "Processing"}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Is Draft</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_draft ? "Yes" : "No"}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
Pending Validation
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_pending_validation_by_fab ? "Yes" : "No"}
</dd>
<div className="flex flex-col md:flex-row gap-6">
<div className="w-full md:w-1/2 md:max-w-[50%]">
<div className="bg-white shadow overflow-hidden sm:rounded-lg mb-6">
<div className="px-4 py-5 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
Order #{order.order_id}
</h3>
<p className="mt-1 max-w-2xl text-sm text-gray-500">
Created at: {new Date(order.created_at).toLocaleString()}
</p>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
Approved by Fab
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_approved_by_fab_review ? "Yes" : "No"}
</dd>
<div className="border-t border-gray-200">
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Status</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_shipped ? "Shipped" : "Processing"}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">Is Draft</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_draft ? "Yes" : "No"}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
Pending Validation
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_pending_validation_by_fab ? "Yes" : "No"}
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
Approved by Fab
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_approved_by_fab_review ? "Yes" : "No"}
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
In Production
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_in_production ? "Yes" : "No"}
</dd>
</div>
</dl>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500">
In Production
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{order.is_in_production ? "Yes" : "No"}
</dd>
</div>
</dl>
</div>
<div className="mt-6">
<Link href={`/my-orders`}>
<Button variant="outline" onClick={() => window.history.back()}>
Back to Orders
</Button>
</Link>
</div>
</div>
<div className="w-full md:w-1/2 md:max-w-[50%]">
<OrderPreviewContent
circuitJson={order.circuit_json as AnyCircuitElement[]}
className="h-[calc(100vh-200px)]"
/>
</div>
</div>
<div className="mt-6">
<Link href={`/my-orders`}>
<Button variant="outline" onClick={() => window.history.back()}>
Back to Orders
</Button>
</Link>
</div>
</div>
<Footer />
Expand Down

0 comments on commit 4f374e9

Please sign in to comment.