Loading common/api/motherboard/schema.ts +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ const data = z.object({ price: z.coerce.number(), manufacturerId: z.string().nonempty(), socketId: z.string().nonempty(), memoryGenerationId: z.string().nonempty(), memorySlotCount: z.coerce.number(), formFactorId: z.string().nonempty(), chipsetId: z.string().nonempty(), Loading frontend/src/components/AddPart/AddMotherboard.tsx +108 −64 Original line number Diff line number Diff line import { Button, OutlinedInput } from '@mui/material'; import { useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { Motherboard, import schema, { Manufacturer, Socket, FormFactor, Loading @@ -10,27 +9,70 @@ import { } from '@pcbuilder/common/api'; import './AddPart.css'; import { useState } from 'react'; import { z } from 'zod'; import { pick } from '@pcbuilder/common/utils'; import { useMutation } from 'react-query'; import { ManufacturerAttr } from './PartAttributes/ManufacturerAttr.tsx'; import { SocketAttr } from './PartAttributes/SocketAttr.tsx'; import { FormFactorAttr } from './PartAttributes/FormFactorAttr.tsx'; import { MotherboardChipsetAttr } from './PartAttributes/MotherboardChipsetAttr.tsx'; import { PCIESlotsAttr, PCIESlot } from './PartAttributes/PCIESlotsAttr.tsx'; import { createMotherboard } from '../../services/motherboardApi'; import { ErrorView } from '../ErrorView.tsx'; import { uploadImage } from '../../services/uploadApi'; export function AddMotherboard() { const navigate = useNavigate(); const { register, handleSubmit } = useForm<Motherboard>(); function add(_motherboard: Motherboard) { // TODO: functionality navigate('/'); } const [manufacturer, setManufacturer] = useState<Manufacturer>(); const [socket, setSocket] = useState<Socket>(); const [formFactor, setFormFactor] = useState<FormFactor>(); const [chipset, setChipset] = useState<MotherboardChipset>(); const [pcieSlots, setPcieSlots] = useState<PCIESlot[]>(); const [pcieSlots, setPcieSlots] = useState<PCIESlot[]>([]); const { register, handleSubmit, getValues } = useForm<Motherboard>(); const { mutate, isLoading, error: responseError, isError, } = useMutation( 'createMotherboard', (motherboard: Motherboard) => createMotherboard(motherboard), { onSuccess: () => { navigate('/'); }, } ); type Motherboard = z.infer<typeof schema.motherboard.create>; async function add() { const stored = await uploadImage(getValues('image')); const motherboard = { name: getValues('name'), price: getValues('price'), manufacturerId: manufacturer.id, socketId: socket.id, formFactorId: formFactor.id, chipsetId: chipset.id, memorySlotCount: getValues('memorySlotCount'), pcieSlots: pcieSlots.map((p) => ({ ...pick(p, 'size', 'count'), pcieGenerationId: p.generation.id, })), image: stored[0].filename, }; mutate(motherboard); } return ( <> {isError === true && ( <ErrorView dataType="Processor" error={responseError} /> )} <form onSubmit={handleSubmit(add)} className="processor__formAdd"> <h1 className="formAdd__title">Add Motherboard</h1> <div className="formAdd__item"> Loading Loading @@ -76,11 +118,12 @@ export function AddMotherboard() { <input required type="file" {...register('name')} {...register('image')} className="formAdd__item--inputFile" /> </div> <Button disabled={isLoading} type="submit" color="info" variant="contained" Loading @@ -89,5 +132,6 @@ export function AddMotherboard() { Proceed </Button> </form> </> ); } frontend/src/components/AddPart/AddProcessor.tsx +88 −52 Original line number Diff line number Diff line import { Button, OutlinedInput } from '@mui/material'; import { useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { Processor, import schema, { Manufacturer, Socket, IntegratedGraphics, } from '@pcbuilder/common/api'; import './AddPart.css'; import { useState } from 'react'; import { z } from 'zod'; import { useMutation } from 'react-query'; import { ManufacturerAttr } from './PartAttributes/ManufacturerAttr.tsx'; import { SocketAttr } from './PartAttributes/SocketAttr.tsx'; import { IntegratedGraphicsAttr } from './PartAttributes/IntegratedGraphicsAttr.tsx'; import { createProcessor } from '../../services/processorApi'; import { ErrorView } from '../ErrorView.tsx'; import { uploadImage } from '../../services/uploadApi'; export function AddProcessor() { const navigate = useNavigate(); const { register, handleSubmit } = useForm<Processor>(); function add(_processor: Processor) { // TODO: functionality navigate('/'); } const [manufacturer, setManufacturer] = useState<Manufacturer>(); const [socket, setSocket] = useState<Socket>(); const [integratedGraphics, setIntegratedGraphics] = useState<IntegratedGraphics>(); const { register, handleSubmit, getValues } = useForm<Processor>(); const { mutate, isLoading, error: responseError, isError, } = useMutation( 'createProcessor', (processor: Processor) => createProcessor(processor), { onSuccess: () => { navigate('/'); }, } ); type Processor = z.infer<typeof schema.processor.create>; async function add() { const stored = await uploadImage(getValues('image')); const processor = { name: getValues('name'), price: getValues('price'), manufacturerId: manufacturer.id, socketId: socket.id, integratedGraphicsId: integratedGraphics.id, image: stored[0].filename, }; mutate(processor); } return ( <> {isError === true && ( <ErrorView dataType="Processor" error={responseError} /> )} <form onSubmit={handleSubmit(add)} className="processor__formAdd"> <h1 className="formAdd__title">Add Processor</h1> <div className="formAdd__item"> Loading Loading @@ -61,11 +95,12 @@ export function AddProcessor() { <input required type="file" {...register('name')} {...register('image')} className="formAdd__item--inputFile" /> </div> <Button disabled={isLoading} type="submit" color="info" variant="contained" Loading @@ -74,5 +109,6 @@ export function AddProcessor() { Proceed </Button> </form> </> ); } frontend/src/components/AddPart/PartAttributes/PCIESlotsAttr.tsx +6 −6 Original line number Diff line number Diff line Loading @@ -44,14 +44,14 @@ export function PCIESlotsAttr({ setPCIESlots }: PCIESlotsProps) { }; const handlePCIESlotAdd = () => { setPCIESlots((prev: PCIESlot[]) => { prev.push({ setPCIESlots((prev: PCIESlot[]) => [ ...prev, { generation, count, size, }); return prev; }); count, }, ]); }; return ( Loading frontend/src/components/SummaryItem.tsx +6 −1 Original line number Diff line number Diff line import { SellablePart, SellablePartName } from '../types/SellableParts'; import { priceToString } from '../services/helperFunctions'; import { backendURL } from '../services/base'; export interface SummaryItemItemInput { name: SellablePartName; Loading @@ -21,7 +22,11 @@ export function SummaryItem({ name, part }: SummaryItemItemInput) { <span className="part__info">Price:</span> <span>{`${priceToString(part.price)}`}</span> </div> <img src="../assets/scratch.png" alt="processor" className="part__img" /> <img src={`${backendURL}/upload/${part.image}`} alt="processor" className="part__img" /> </div> ); } Loading
common/api/motherboard/schema.ts +0 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,6 @@ const data = z.object({ price: z.coerce.number(), manufacturerId: z.string().nonempty(), socketId: z.string().nonempty(), memoryGenerationId: z.string().nonempty(), memorySlotCount: z.coerce.number(), formFactorId: z.string().nonempty(), chipsetId: z.string().nonempty(), Loading
frontend/src/components/AddPart/AddMotherboard.tsx +108 −64 Original line number Diff line number Diff line import { Button, OutlinedInput } from '@mui/material'; import { useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { Motherboard, import schema, { Manufacturer, Socket, FormFactor, Loading @@ -10,27 +9,70 @@ import { } from '@pcbuilder/common/api'; import './AddPart.css'; import { useState } from 'react'; import { z } from 'zod'; import { pick } from '@pcbuilder/common/utils'; import { useMutation } from 'react-query'; import { ManufacturerAttr } from './PartAttributes/ManufacturerAttr.tsx'; import { SocketAttr } from './PartAttributes/SocketAttr.tsx'; import { FormFactorAttr } from './PartAttributes/FormFactorAttr.tsx'; import { MotherboardChipsetAttr } from './PartAttributes/MotherboardChipsetAttr.tsx'; import { PCIESlotsAttr, PCIESlot } from './PartAttributes/PCIESlotsAttr.tsx'; import { createMotherboard } from '../../services/motherboardApi'; import { ErrorView } from '../ErrorView.tsx'; import { uploadImage } from '../../services/uploadApi'; export function AddMotherboard() { const navigate = useNavigate(); const { register, handleSubmit } = useForm<Motherboard>(); function add(_motherboard: Motherboard) { // TODO: functionality navigate('/'); } const [manufacturer, setManufacturer] = useState<Manufacturer>(); const [socket, setSocket] = useState<Socket>(); const [formFactor, setFormFactor] = useState<FormFactor>(); const [chipset, setChipset] = useState<MotherboardChipset>(); const [pcieSlots, setPcieSlots] = useState<PCIESlot[]>(); const [pcieSlots, setPcieSlots] = useState<PCIESlot[]>([]); const { register, handleSubmit, getValues } = useForm<Motherboard>(); const { mutate, isLoading, error: responseError, isError, } = useMutation( 'createMotherboard', (motherboard: Motherboard) => createMotherboard(motherboard), { onSuccess: () => { navigate('/'); }, } ); type Motherboard = z.infer<typeof schema.motherboard.create>; async function add() { const stored = await uploadImage(getValues('image')); const motherboard = { name: getValues('name'), price: getValues('price'), manufacturerId: manufacturer.id, socketId: socket.id, formFactorId: formFactor.id, chipsetId: chipset.id, memorySlotCount: getValues('memorySlotCount'), pcieSlots: pcieSlots.map((p) => ({ ...pick(p, 'size', 'count'), pcieGenerationId: p.generation.id, })), image: stored[0].filename, }; mutate(motherboard); } return ( <> {isError === true && ( <ErrorView dataType="Processor" error={responseError} /> )} <form onSubmit={handleSubmit(add)} className="processor__formAdd"> <h1 className="formAdd__title">Add Motherboard</h1> <div className="formAdd__item"> Loading Loading @@ -76,11 +118,12 @@ export function AddMotherboard() { <input required type="file" {...register('name')} {...register('image')} className="formAdd__item--inputFile" /> </div> <Button disabled={isLoading} type="submit" color="info" variant="contained" Loading @@ -89,5 +132,6 @@ export function AddMotherboard() { Proceed </Button> </form> </> ); }
frontend/src/components/AddPart/AddProcessor.tsx +88 −52 Original line number Diff line number Diff line import { Button, OutlinedInput } from '@mui/material'; import { useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; import { Processor, import schema, { Manufacturer, Socket, IntegratedGraphics, } from '@pcbuilder/common/api'; import './AddPart.css'; import { useState } from 'react'; import { z } from 'zod'; import { useMutation } from 'react-query'; import { ManufacturerAttr } from './PartAttributes/ManufacturerAttr.tsx'; import { SocketAttr } from './PartAttributes/SocketAttr.tsx'; import { IntegratedGraphicsAttr } from './PartAttributes/IntegratedGraphicsAttr.tsx'; import { createProcessor } from '../../services/processorApi'; import { ErrorView } from '../ErrorView.tsx'; import { uploadImage } from '../../services/uploadApi'; export function AddProcessor() { const navigate = useNavigate(); const { register, handleSubmit } = useForm<Processor>(); function add(_processor: Processor) { // TODO: functionality navigate('/'); } const [manufacturer, setManufacturer] = useState<Manufacturer>(); const [socket, setSocket] = useState<Socket>(); const [integratedGraphics, setIntegratedGraphics] = useState<IntegratedGraphics>(); const { register, handleSubmit, getValues } = useForm<Processor>(); const { mutate, isLoading, error: responseError, isError, } = useMutation( 'createProcessor', (processor: Processor) => createProcessor(processor), { onSuccess: () => { navigate('/'); }, } ); type Processor = z.infer<typeof schema.processor.create>; async function add() { const stored = await uploadImage(getValues('image')); const processor = { name: getValues('name'), price: getValues('price'), manufacturerId: manufacturer.id, socketId: socket.id, integratedGraphicsId: integratedGraphics.id, image: stored[0].filename, }; mutate(processor); } return ( <> {isError === true && ( <ErrorView dataType="Processor" error={responseError} /> )} <form onSubmit={handleSubmit(add)} className="processor__formAdd"> <h1 className="formAdd__title">Add Processor</h1> <div className="formAdd__item"> Loading Loading @@ -61,11 +95,12 @@ export function AddProcessor() { <input required type="file" {...register('name')} {...register('image')} className="formAdd__item--inputFile" /> </div> <Button disabled={isLoading} type="submit" color="info" variant="contained" Loading @@ -74,5 +109,6 @@ export function AddProcessor() { Proceed </Button> </form> </> ); }
frontend/src/components/AddPart/PartAttributes/PCIESlotsAttr.tsx +6 −6 Original line number Diff line number Diff line Loading @@ -44,14 +44,14 @@ export function PCIESlotsAttr({ setPCIESlots }: PCIESlotsProps) { }; const handlePCIESlotAdd = () => { setPCIESlots((prev: PCIESlot[]) => { prev.push({ setPCIESlots((prev: PCIESlot[]) => [ ...prev, { generation, count, size, }); return prev; }); count, }, ]); }; return ( Loading
frontend/src/components/SummaryItem.tsx +6 −1 Original line number Diff line number Diff line import { SellablePart, SellablePartName } from '../types/SellableParts'; import { priceToString } from '../services/helperFunctions'; import { backendURL } from '../services/base'; export interface SummaryItemItemInput { name: SellablePartName; Loading @@ -21,7 +22,11 @@ export function SummaryItem({ name, part }: SummaryItemItemInput) { <span className="part__info">Price:</span> <span>{`${priceToString(part.price)}`}</span> </div> <img src="../assets/scratch.png" alt="processor" className="part__img" /> <img src={`${backendURL}/upload/${part.image}`} alt="processor" className="part__img" /> </div> ); }