Skip to content

22 Shortest Path Frontend

JP Barbosa edited this page Apr 15, 2023 · 1 revision

Shortest Path Frontend

API Helper

code ./packages/web/src/api/shortestPath.ts
import axios from 'axios';
import { GraphVisData } from 'react-graph-vis';

const url = `${import.meta.env.VITE_API_URL}/shortest-path`;

export const shortestPath = {
  get: (person1: string, person2: string) =>
    axios
      .get<GraphVisData>(`${url}?person1=${person1}&person2=${person2}`)
      .then((res) => res.data),
};
code ./packages/web/src/api/index.ts
...
export * from './shortestPath';

Page

code ./packages/web/src/pages/shortest-path/index.tsx
import { useState } from 'react';
import { useQuery } from 'react-query';
import { Person } from '@neo4j-crud/shared';
import * as api from '../../api';
import { Content } from './Content';
import { SelectPerson } from './SelectPerson';

export const ShortestPath: React.FC = () => {
  const [person1, setPerson1] = useState<string>('Tom Cruise');
  const [person2, setPerson2] = useState<string>('Tom Hanks');

  const { data: people } = useQuery<Person[]>('select-people', () =>
    api.people.getAll()
  );

  return (
    <div className="page">
      <div className="actions-bar">
        <h2>Shortest Path</h2>
        {people ? (
          <div className="filter">
            <SelectPerson
              data={people}
              value={person1}
              otherValue={person2}
              onChange={(e) => setPerson1(e.target.value)}
            />
            <SelectPerson
              data={people}
              value={person2}
              otherValue={person1}
              onChange={(e) => setPerson2(e.target.value)}
            />
          </div>
        ) : (
          <span>Loading</span>
        )}
      </div>
      <Content person1={person1} person2={person2} />
    </div>
  );
};
code ./packages/web/src/pages/shortest-path/Content.tsx
import { useQuery } from 'react-query';
import { GraphVisData } from 'react-graph-vis';
import { AxiosCustomError } from '@neo4j-crud/shared';
import * as api from '../../api';
import { AlertCombo, GraphVis } from '../../components';

type ContentProps = {
  person1: string;
  person2: string;
};

export const Content: React.FC<ContentProps> = ({ person1, person2 }) => {
  const { data, error, isLoading } = useQuery<GraphVisData, AxiosCustomError>(
    ['shortest-path', person1, person2],
    () => api.shortestPath.get(person1, person2)
  );

  const noData = !data || data.nodes.length === 0;

  if (error || isLoading || noData) {
    return <AlertCombo error={error} isLoading={isLoading} noData={noData} />;
  }

  return (
    <div
      style={{
        height: '100%',
      }}
    >
      <GraphVis graph={data} />
    </div>
  );
};
code ./packages/web/src/pages/shortest-path/SelectPerson.tsx
import { Person } from '@neo4j-crud/shared';

type SelectPersonProps = {
  value: string;
  otherValue: string;
  onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
  data: Person[] | undefined;
};

export const SelectPerson: React.FC<SelectPersonProps> = ({
  value,
  otherValue,
  onChange,
  data,
}) => {
  return (
    <span>
      <select value={value} onChange={onChange}>
        {data?.map((person) => (
          <option
            key={person.name}
            value={person.name}
            disabled={person.name === otherValue}
          >
            {person.name}
          </option>
        ))}
      </select>
    </span>
  );
};
code ./packages/web/src/pages/index.ts
...
export * from './shortest-path';
code ./packages/web/src/app/app.tsx
...
import { ..., ShortestPath } from '../pages';

export function App() {
  return (
    <>
      <Header />
      <Routes>
        ...
        <Route path="/shortest-path/*" element={<ShortestPath />} />
      </Routes>
    </>
  );
}

export default App;

Update Header

code ./packages/web/src/components/Header.tsx
...

export const Header: React.FC = () => {
  const navItems: NavItem[] = [
    ...
    { path: '/shortest-path', label: 'Shortest Path' },
  ];

  return ...;
};

Test

open http://localhost:3333/shortest-path
Example 1 Example 2

Commit

git add .
git commit -m "Shortest Path Frontend"

Next step: End-To-End Tests