Commit 28d042a3 authored by Jan Minář's avatar Jan Minář
Browse files

feat(frontend): post requests for processor and motherboard

parent 9352f724
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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(),
+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,
@@ -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">
@@ -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"
@@ -89,5 +132,6 @@ export function AddMotherboard() {
          Proceed
        </Button>
      </form>
    </>
  );
}
+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">
@@ -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"
@@ -74,5 +109,6 @@ export function AddProcessor() {
          Proceed
        </Button>
      </form>
    </>
  );
}
+6 −6
Original line number Diff line number Diff line
@@ -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 (
+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;
@@ -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