diff --git a/.prettierr b/.prettierr index 1dc7164..974a4f8 100644 --- a/.prettierr +++ b/.prettierr @@ -2,5 +2,6 @@ "trailingComma": "es5", "tabWidth": 2, "semi": true, - "singleQuote": true + "singleQuote": true, + "endOfLine": "auto" } \ No newline at end of file diff --git a/coverage/App.tsx.html b/coverage/App.tsx.html deleted file mode 100644 index 62bcc62..0000000 --- a/coverage/App.tsx.html +++ /dev/null @@ -1,460 +0,0 @@ - - - - - - Code coverage report for App.tsx - - - - - - - - - -
-
-

All files App.tsx

-
- -
- 95.29% - Statements - 81/85 -
- - -
- 95.83% - Branches - 23/24 -
- - -
- 88.88% - Functions - 8/9 -
- - -
- 95.29% - Lines - 81/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -1261x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -13x -  -13x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -13x -  -  -  -13x -2x -2x -  -13x -16x -16x -16x -16x -4x -12x -1x -1x -1x -  -  -1x -1x -16x -  -13x -3x -3x -3x -  -13x -13x -13x -13x -13x -13x -  -13x -37x -37x -  -13x -74x -  -74x -4x -4x -  -70x -70x -70x -70x -1x -69x -74x -74x -74x -74x -74x -45x -  -25x -25x -4x -  -21x -21x -11x -21x -21x -  -25x -  -74x -74x -  -74x -13x -  -1x - 
import React from "react";
-import "./App.css";
-import ErrorButton from "./ErrorButton";
-import Button from "./Button";
-import Input from "./Input";
-import PlanetCard from "./PlanetCard";
-import Spinner from "./Spinner";
-import { PlanetApi } from "./PlanetFetch";
-interface PlanetProperties {
-  name?: string;
-  diameter: string;
-  rotation_period: string;
-  orbital_period: string;
-  population: string;
-  climate: string;
-  terrain: string;
-}
- 
-interface Planet {
-  uid?: string;
-  name?: string;
-  properties: PlanetProperties;
-}
- 
-interface AppState {
-  inputValue: string;
-  searchResults: Planet[];
-  isLoading: boolean;
-  error: string | null;
-  throwBoolean: boolean;
-}
- 
-class App extends React.Component<object, AppState> {
-  localStorageKey: string = "starWarsQuery";
- 
-  constructor(props: object) {
-    super(props);
-    this.state = {
-      inputValue: localStorage.getItem(this.localStorageKey) || "",
-      searchResults: [],
-      isLoading: false,
-      error: null,
-      throwBoolean: false,
-    };
-  }
- 
-  resetErrorState = () => {
-    this.setState({ throwBoolean: false });
-  };
- 
-  triggerError = () => {
-    this.setState({ throwBoolean: true });
-  };
- 
-  fetchPlanets = async (searchQuery: string = "") => {
-    let errorMessage = "Unknown error";
-    this.setState({ isLoading: true, error: null });
-    try {
-      const planets = await PlanetApi.fetchPlanets(searchQuery);
-      this.setState({ searchResults: planets, isLoading: false });
-    } catch (error) {
-      if (error instanceof Error) {
-        errorMessage = error.message;
-      } else if (typeof error === "string") {
-        errorMessage = error;
-      }
-      this.setState({ error: errorMessage, isLoading: false });
-    }
-  };
- 
-  handleSearch = () => {
-    localStorage.setItem(this.localStorageKey, this.state.inputValue.trim());
-    this.fetchPlanets(this.state.inputValue);
-  };
- 
-  componentDidMount() {
-    this.setState({
-      inputValue: localStorage.getItem(this.localStorageKey) || "",
-    });
-    this.fetchPlanets(this.state.inputValue);
-  }
- 
-  handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
-    this.setState({ inputValue: e.target.value });
-  };
- 
-  render() {
-    const { inputValue, searchResults, isLoading, throwBoolean } = this.state;
- 
-    if (throwBoolean) {
-      throw new Error("Test error");
-    }
- 
-    return (
-      <div className="app-container" data-testid="app">
-        <h1 className="title">Star Wars Planets</h1>
-        {this.state.error ? (
-          <div data-testid="error-message">{this.state.error}</div>
-        ) : null}
-        <div className="search-container">
-          <Input value={inputValue} onChange={this.handleInputChange} />
-          <Button onClick={this.handleSearch}>{"Search"}</Button>
-        </div>
-        {isLoading ? (
-          <Spinner />
-        ) : (
-          <div className="results-container">
-            {inputValue.trim() !== "" && searchResults.length === 0 ? (
-              <div className="nothing">Nothing</div>
-            ) : (
-              <div className="results-grid">
-                {searchResults.map((planet: Planet) => (
-                  <PlanetCard key={planet.uid} planet={planet} />
-                ))}
-              </div>
-            )}
-          </div>
-        )}
-        <ErrorButton onClick={this.triggerError} />
-      </div>
-    );
-  }
-}
- 
-export default App;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/Button.tsx.html b/coverage/Button.tsx.html deleted file mode 100644 index 94a3ef6..0000000 --- a/coverage/Button.tsx.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - Code coverage report for Button.tsx - - - - - - - - - -
-
-

All files Button.tsx

-
- -
- 100% - Statements - 7/7 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 7/7 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -151x -  -  -  -  -  -  -1x -1x -70x -70x -1x -  -1x - 
import React from "react";
- 
-interface ButtonProps {
-  onClick: () => void;
-  children: React.ReactNode;
-}
- 
-class Button extends React.Component<ButtonProps> {
-  render() {
-    return <button onClick={this.props.onClick}>{this.props.children}</button>;
-  }
-}
- 
-export default Button;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/ErrorBoundary.tsx.html b/coverage/ErrorBoundary.tsx.html deleted file mode 100644 index 680cffc..0000000 --- a/coverage/ErrorBoundary.tsx.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - Code coverage report for ErrorBoundary.tsx - - - - - - - - - -
-
-

All files ErrorBoundary.tsx

-
- -
- 100% - Statements - 31/31 -
- - -
- 100% - Branches - 8/8 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 31/31 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -501x -  -  -  -  -  -  -  -  -  -  -1x -2x -3x -3x -3x -3x -3x -3x -  -2x -4x -4x -  -2x -2x -2x -  -2x -1x -1x -  -2x -9x -6x -6x -6x -6x -  -6x -6x -  -6x -  -3x -9x -2x -  -1x - 
import React from "react";
- 
-interface Props {
-  children: React.ReactNode;
-}
- 
-interface State {
-  hasError: boolean;
-  error: Error | null;
-}
- 
-class ErrorBoundary extends React.Component<Props, State> {
-  constructor(props: Props) {
-    super(props);
-    this.state = {
-      hasError: false,
-      error: null,
-    };
-  }
- 
-  static getDerivedStateFromError(error: Error): State {
-    return { hasError: true, error: error };
-  }
- 
-  componentDidCatch(error: Error) {
-    this.setState({ error });
-  }
- 
-  resetError = () => {
-    this.setState({ hasError: false, error: null });
-  };
- 
-  render() {
-    if (this.state.hasError) {
-      return (
-        <div className="error-boundary">
-          <p className="error-message">{this.state.error?.toString()}</p>
-          <button className="error-test-button" onClick={this.resetError}>
-            Reboot
-          </button>
-        </div>
-      );
-    }
- 
-    return this.props.children;
-  }
-}
- 
-export default ErrorBoundary;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/ErrorButton.tsx.html b/coverage/ErrorButton.tsx.html deleted file mode 100644 index 05e141c..0000000 --- a/coverage/ErrorButton.tsx.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - Code coverage report for ErrorButton.tsx - - - - - - - - - -
-
-

All files ErrorButton.tsx

-
- -
- 100% - Statements - 7/7 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 7/7 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -161x -  -  -  -  -  -1x -70x -70x -  -70x -  -70x -  -1x - 
import React from "react";
- 
-interface ErrorButtonProps {
-  onClick: () => void;
-}
- 
-const ErrorButton: React.FC<ErrorButtonProps> = ({ onClick }) => {
-  return (
-    <button onClick={onClick} className="error-test-button">
-      Test Error
-    </button>
-  );
-};
- 
-export default ErrorButton;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/Input.tsx.html b/coverage/Input.tsx.html deleted file mode 100644 index 204605e..0000000 --- a/coverage/Input.tsx.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Code coverage report for Input.tsx - - - - - - - - - -
-
-

All files Input.tsx

-
- -
- 100% - Statements - 12/12 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 12/12 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -201x -  -  -  -  -  -1x -1x -70x -70x -70x -70x -70x -70x -  -70x -1x -  -1x - 
import React from "react";
- 
-interface InputProps {
-  value: string;
-  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
-}
-class Input extends React.Component<InputProps> {
-  render() {
-    return (
-      <input
-        type="text"
-        value={this.props.value}
-        onChange={this.props.onChange}
-      />
-    );
-  }
-}
- 
-export default Input;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/PlanetCard.tsx.html b/coverage/PlanetCard.tsx.html deleted file mode 100644 index 88c3158..0000000 --- a/coverage/PlanetCard.tsx.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - Code coverage report for PlanetCard.tsx - - - - - - - - - -
-
-

All files PlanetCard.tsx

-
- -
- 100% - Statements - 41/41 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 41/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -611x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -1x -  -1x - 
import React from "react";
- 
-interface Planet {
-  uid?: string;
-  name?: string;
-  properties: PlanetProperties;
-}
- 
-interface PlanetProperties {
-  name?: string;
-  diameter: string;
-  rotation_period: string;
-  orbital_period: string;
-  population: string;
-  climate: string;
-  terrain: string;
-}
- 
-class PlanetCard extends React.Component<{ planet: Planet }> {
-  render() {
-    const { planet } = this.props;
-    return (
-      <div className="planet-card" role="article">
-        <div className="planet-details">
-          <h3 className="planet-name">{planet.name}</h3>
-          <div className="detail-row">
-            <span className="detail-label">Diameter:</span>
-            <span className="prop_planet">{planet.properties.diameter}</span>
-          </div>
-          <div className="detail-row">
-            <span className="detail-label">Climate:</span>
-            <span className="prop_planet">{planet.properties.climate}</span>
-          </div>
-          <div className="detail-row">
-            <span className="detail-label">Terrain:</span>
-            <span className="prop_planet">{planet.properties.terrain}</span>
-          </div>
-          <div className="detail-row">
-            <span className="detail-label">Population:</span>
-            <span className="prop_planet">{planet.properties.population}</span>
-          </div>
-          <div className="detail-row">
-            <span className="detail-label">Rotation Period:</span>
-            <span className="prop_planet">
-              {planet.properties.rotation_period}
-            </span>
-          </div>
-          <div className="detail-row">
-            <span className="detail-label">Orbital Period:</span>
-            <span className="prop_planet">
-              {planet.properties.orbital_period}
-            </span>
-          </div>
-        </div>
-      </div>
-    );
-  }
-}
- 
-export default PlanetCard;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/Spinner.tsx.html b/coverage/Spinner.tsx.html deleted file mode 100644 index c069862..0000000 --- a/coverage/Spinner.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for Spinner.tsx - - - - - - - - - -
-
-

All files Spinner.tsx

-
- -
- 100% - Statements - 10/10 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 10/10 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -141x -  -1x -1x -45x -45x -45x -45x -  -45x -1x -  -1x - 
import React from "react";
- 
-class Spinner extends React.Component {
-  render() {
-    return (
-      <div className="spinner-container">
-        <div className="spinner"></div>
-      </div>
-    );
-  }
-}
- 
-export default Spinner;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/base.css b/coverage/base.css deleted file mode 100644 index f418035..0000000 --- a/coverage/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js deleted file mode 100644 index cc12130..0000000 --- a/coverage/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selecter that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/clover.xml b/coverage/clover.xml deleted file mode 100644 index 2b087bf..0000000 --- a/coverage/clover.xml +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json deleted file mode 100644 index 347ceaa..0000000 --- a/coverage/coverage-final.json +++ /dev/null @@ -1,10 +0,0 @@ -{"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\App.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\App.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":19}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":40}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":30}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":28}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":38}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":32}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":42}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":53}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":44}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":30}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":17}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":18}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":67}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":24}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":23}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":18}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":26}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":6}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":3}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":27}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":43}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":4}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":24}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":42}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":4}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":54}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":39}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":52}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":9}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":64}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":66}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":21}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":35}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":37}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":45}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":29}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":7}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":63}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":5}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":4}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":24}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":77}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":45}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":4}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":23}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":19}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":67}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":7}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":45}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":3}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":67}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":50}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":4}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":12}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":78}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":23}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":36}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":5}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":12}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":55}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":52}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":29}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":67}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":17}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":42}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":72}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":65}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":14}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":22}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":21}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":45}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":71}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":52}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":44}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":56}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":65}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":19}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":20}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":16}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":51}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":12}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":3}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":1}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":19}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"32":1,"33":13,"35":13,"36":14,"37":14,"38":14,"39":14,"40":14,"41":14,"42":14,"43":14,"44":14,"46":13,"47":0,"48":0,"50":13,"51":2,"52":2,"54":13,"55":16,"56":16,"57":16,"58":16,"59":4,"60":12,"61":1,"62":1,"63":1,"64":0,"65":0,"66":1,"67":1,"68":16,"70":13,"71":3,"72":3,"73":3,"75":13,"76":13,"77":13,"78":13,"79":13,"80":13,"82":13,"83":37,"84":37,"86":13,"87":74,"89":74,"90":4,"91":4,"93":70,"94":70,"95":70,"96":70,"97":1,"98":69,"99":74,"100":74,"101":74,"102":74,"103":74,"104":45,"106":25,"107":25,"108":4,"110":21,"111":21,"112":11,"113":21,"114":21,"116":25,"118":74,"119":74,"121":74,"122":13,"124":1},"branchMap":{"0":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":52},"end":{"line":123,"column":1}},"locations":[{"start":{"line":33,"column":52},"end":{"line":123,"column":1}}]},"1":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":45,"column":3}},"locations":[{"start":{"line":36,"column":2},"end":{"line":45,"column":3}}]},"2":{"type":"branch","line":39,"loc":{"start":{"line":39,"column":59},"end":{"line":39,"column":67}},"locations":[{"start":{"line":39,"column":59},"end":{"line":39,"column":67}}]},"3":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":17},"end":{"line":53,"column":4}},"locations":[{"start":{"line":51,"column":17},"end":{"line":53,"column":4}}]},"4":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":17},"end":{"line":69,"column":4}},"locations":[{"start":{"line":55,"column":17},"end":{"line":69,"column":4}}]},"5":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":62},"end":{"line":68,"column":5}},"locations":[{"start":{"line":59,"column":62},"end":{"line":68,"column":5}}]},"6":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":62},"end":{"line":61,"column":13}},"locations":[{"start":{"line":59,"column":62},"end":{"line":61,"column":13}}]},"7":{"type":"branch","line":61,"loc":{"start":{"line":61,"column":4},"end":{"line":68,"column":5}},"locations":[{"start":{"line":61,"column":4},"end":{"line":68,"column":5}}]},"8":{"type":"branch","line":64,"loc":{"start":{"line":64,"column":6},"end":{"line":66,"column":7}},"locations":[{"start":{"line":64,"column":6},"end":{"line":66,"column":7}}]},"9":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":17},"end":{"line":74,"column":4}},"locations":[{"start":{"line":71,"column":17},"end":{"line":74,"column":4}}]},"10":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"locations":[{"start":{"line":76,"column":2},"end":{"line":81,"column":3}}]},"11":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":59},"end":{"line":78,"column":67}},"locations":[{"start":{"line":78,"column":59},"end":{"line":78,"column":67}}]},"12":{"type":"branch","line":83,"loc":{"start":{"line":83,"column":22},"end":{"line":85,"column":4}},"locations":[{"start":{"line":83,"column":22},"end":{"line":85,"column":4}}]},"13":{"type":"branch","line":87,"loc":{"start":{"line":87,"column":2},"end":{"line":122,"column":3}},"locations":[{"start":{"line":87,"column":2},"end":{"line":122,"column":3}}]},"14":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":22},"end":{"line":92,"column":5}},"locations":[{"start":{"line":90,"column":22},"end":{"line":92,"column":5}}]},"15":{"type":"branch","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":29}},"locations":[{"start":{"line":92,"column":4},"end":{"line":97,"column":29}}]},"16":{"type":"branch","line":97,"loc":{"start":{"line":97,"column":20},"end":{"line":98,"column":67}},"locations":[{"start":{"line":97,"column":20},"end":{"line":98,"column":67}}]},"17":{"type":"branch","line":98,"loc":{"start":{"line":98,"column":61},"end":{"line":99,"column":17}},"locations":[{"start":{"line":98,"column":61},"end":{"line":99,"column":17}}]},"18":{"type":"branch","line":104,"loc":{"start":{"line":104,"column":9},"end":{"line":105,"column":21}},"locations":[{"start":{"line":104,"column":9},"end":{"line":105,"column":21}}]},"19":{"type":"branch","line":105,"loc":{"start":{"line":105,"column":19},"end":{"line":117,"column":16}},"locations":[{"start":{"line":105,"column":19},"end":{"line":117,"column":16}}]},"20":{"type":"branch","line":108,"loc":{"start":{"line":108,"column":35},"end":{"line":108,"column":71}},"locations":[{"start":{"line":108,"column":35},"end":{"line":108,"column":71}}]},"21":{"type":"branch","line":108,"loc":{"start":{"line":108,"column":66},"end":{"line":109,"column":52}},"locations":[{"start":{"line":108,"column":66},"end":{"line":109,"column":52}}]},"22":{"type":"branch","line":109,"loc":{"start":{"line":109,"column":46},"end":{"line":115,"column":20}},"locations":[{"start":{"line":109,"column":46},"end":{"line":115,"column":20}}]},"23":{"type":"branch","line":112,"loc":{"start":{"line":112,"column":35},"end":{"line":113,"column":65}},"locations":[{"start":{"line":112,"column":35},"end":{"line":113,"column":65}}]}},"b":{"0":[13],"1":[14],"2":[10],"3":[2],"4":[16],"5":[12],"6":[4],"7":[1],"8":[0],"9":[3],"10":[13],"11":[10],"12":[37],"13":[74],"14":[4],"15":[70],"16":[1],"17":[69],"18":[45],"19":[25],"20":[14],"21":[4],"22":[21],"23":[11]},"fnMap":{"0":{"name":"","decl":{"start":{"line":33,"column":52},"end":{"line":123,"column":1}},"loc":{"start":{"line":33,"column":52},"end":{"line":123,"column":1}},"line":33},"1":{"name":"App","decl":{"start":{"line":36,"column":2},"end":{"line":45,"column":3}},"loc":{"start":{"line":36,"column":2},"end":{"line":45,"column":3}},"line":36},"2":{"name":"resetErrorState","decl":{"start":{"line":47,"column":20},"end":{"line":49,"column":4}},"loc":{"start":{"line":47,"column":20},"end":{"line":49,"column":4}},"line":47},"3":{"name":"triggerError","decl":{"start":{"line":51,"column":17},"end":{"line":53,"column":4}},"loc":{"start":{"line":51,"column":17},"end":{"line":53,"column":4}},"line":51},"4":{"name":"fetchPlanets","decl":{"start":{"line":55,"column":17},"end":{"line":69,"column":4}},"loc":{"start":{"line":55,"column":17},"end":{"line":69,"column":4}},"line":55},"5":{"name":"handleSearch","decl":{"start":{"line":71,"column":17},"end":{"line":74,"column":4}},"loc":{"start":{"line":71,"column":17},"end":{"line":74,"column":4}},"line":71},"6":{"name":"componentDidMount","decl":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"loc":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"line":76},"7":{"name":"handleInputChange","decl":{"start":{"line":83,"column":22},"end":{"line":85,"column":4}},"loc":{"start":{"line":83,"column":22},"end":{"line":85,"column":4}},"line":83},"8":{"name":"render","decl":{"start":{"line":87,"column":2},"end":{"line":122,"column":3}},"loc":{"start":{"line":87,"column":2},"end":{"line":122,"column":3}},"line":87}},"f":{"0":13,"1":14,"2":0,"3":2,"4":16,"5":3,"6":13,"7":37,"8":74}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Button.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Button.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":51}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":12}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":79}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":3}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":1}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":22}}},"s":{"0":1,"7":1,"8":1,"9":70,"10":70,"11":1,"13":1},"branchMap":{"0":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":2},"end":{"line":11,"column":3}},"locations":[{"start":{"line":9,"column":2},"end":{"line":11,"column":3}}]}},"b":{"0":[70]},"fnMap":{"0":{"name":"render","decl":{"start":{"line":9,"column":2},"end":{"line":11,"column":3}},"loc":{"start":{"line":9,"column":2},"end":{"line":11,"column":3}},"line":9}},"f":{"0":70}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\ErrorBoundary.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\ErrorBoundary.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":59}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":29}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":17}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":18}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":22}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":18}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":6}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":3}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":56}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":44}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":3}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":35}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":29}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":3}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":22}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":52}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":12}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":30}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":14}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":40}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":73}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":74}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":19}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":14}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":5}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":31}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":3}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":1}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":29}}},"s":{"0":1,"11":1,"12":2,"13":3,"14":3,"15":3,"16":3,"17":3,"18":3,"20":2,"21":4,"22":4,"24":2,"25":2,"26":2,"28":2,"29":1,"30":1,"32":2,"33":9,"34":6,"35":6,"36":6,"37":6,"39":6,"40":6,"42":6,"44":3,"45":9,"46":2,"48":1},"branchMap":{"0":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":58},"end":{"line":47,"column":1}},"locations":[{"start":{"line":12,"column":58},"end":{"line":47,"column":1}}]},"1":{"type":"branch","line":13,"loc":{"start":{"line":13,"column":2},"end":{"line":19,"column":3}},"locations":[{"start":{"line":13,"column":2},"end":{"line":19,"column":3}}]},"2":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":9},"end":{"line":23,"column":3}},"locations":[{"start":{"line":21,"column":9},"end":{"line":23,"column":3}}]},"3":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":27,"column":3}},"locations":[{"start":{"line":25,"column":2},"end":{"line":27,"column":3}}]},"4":{"type":"branch","line":29,"loc":{"start":{"line":29,"column":15},"end":{"line":31,"column":4}},"locations":[{"start":{"line":29,"column":15},"end":{"line":31,"column":4}}]},"5":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":46,"column":3}},"locations":[{"start":{"line":33,"column":2},"end":{"line":46,"column":3}}]},"6":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":29},"end":{"line":43,"column":5}},"locations":[{"start":{"line":34,"column":29},"end":{"line":43,"column":5}}]},"7":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":31}},"locations":[{"start":{"line":43,"column":4},"end":{"line":45,"column":31}}]}},"b":{"0":[2],"1":[3],"2":[4],"3":[2],"4":[1],"5":[9],"6":[6],"7":[3]},"fnMap":{"0":{"name":"","decl":{"start":{"line":12,"column":58},"end":{"line":47,"column":1}},"loc":{"start":{"line":12,"column":58},"end":{"line":47,"column":1}},"line":12},"1":{"name":"ErrorBoundary","decl":{"start":{"line":13,"column":2},"end":{"line":19,"column":3}},"loc":{"start":{"line":13,"column":2},"end":{"line":19,"column":3}},"line":13},"2":{"name":"getDerivedStateFromError","decl":{"start":{"line":21,"column":9},"end":{"line":23,"column":3}},"loc":{"start":{"line":21,"column":9},"end":{"line":23,"column":3}},"line":21},"3":{"name":"componentDidCatch","decl":{"start":{"line":25,"column":2},"end":{"line":27,"column":3}},"loc":{"start":{"line":25,"column":2},"end":{"line":27,"column":3}},"line":25},"4":{"name":"resetError","decl":{"start":{"line":29,"column":15},"end":{"line":31,"column":4}},"loc":{"start":{"line":29,"column":15},"end":{"line":31,"column":4}},"line":29},"5":{"name":"render","decl":{"start":{"line":33,"column":2},"end":{"line":46,"column":3}},"loc":{"start":{"line":33,"column":2},"end":{"line":46,"column":3}},"line":33}},"f":{"0":2,"1":3,"2":4,"3":2,"4":1,"5":9}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\ErrorButton.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\ErrorButton.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":66}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":10}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":60}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":13}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":2}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":27}}},"s":{"0":1,"6":1,"7":70,"8":70,"10":70,"12":70,"14":1},"branchMap":{"0":{"type":"branch","line":7,"loc":{"start":{"line":7,"column":48},"end":{"line":13,"column":2}},"locations":[{"start":{"line":7,"column":48},"end":{"line":13,"column":2}}]}},"b":{"0":[70]},"fnMap":{"0":{"name":"ErrorButton","decl":{"start":{"line":7,"column":48},"end":{"line":13,"column":2}},"loc":{"start":{"line":7,"column":48},"end":{"line":13,"column":2}},"line":7}},"f":{"0":70}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Input.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Input.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":49}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":12}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":12}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":12}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":19}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":32}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":38}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":8}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":3}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":1}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":21}}},"s":{"0":1,"6":1,"7":1,"8":70,"9":70,"10":70,"11":70,"12":70,"13":70,"15":70,"16":1,"18":1},"branchMap":{"0":{"type":"branch","line":8,"loc":{"start":{"line":8,"column":2},"end":{"line":16,"column":3}},"locations":[{"start":{"line":8,"column":2},"end":{"line":16,"column":3}}]}},"b":{"0":[70]},"fnMap":{"0":{"name":"render","decl":{"start":{"line":8,"column":2},"end":{"line":16,"column":3}},"loc":{"start":{"line":8,"column":2},"end":{"line":16,"column":3}},"line":8}},"f":{"0":70}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\PlanetCard.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\PlanetCard.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":62}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":12}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":34}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":12}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":50}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":40}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":56}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":38}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":59}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":77}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":16}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":38}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":58}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":76}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":16}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":38}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":58}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":76}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":16}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":38}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":61}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":79}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":16}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":38}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":66}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":42}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":49}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":19}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":16}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":38}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":65}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":42}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":48}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":19}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":16}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":14}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":12}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":3}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":1}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":26}}},"s":{"0":1,"18":1,"19":1,"20":11,"21":11,"22":11,"23":11,"24":11,"25":11,"26":11,"27":11,"28":11,"29":11,"30":11,"31":11,"32":11,"33":11,"34":11,"35":11,"36":11,"37":11,"38":11,"39":11,"40":11,"41":11,"42":11,"43":11,"44":11,"45":11,"46":11,"47":11,"48":11,"49":11,"50":11,"51":11,"52":11,"53":11,"54":11,"56":11,"57":1,"59":1},"branchMap":{"0":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":57,"column":3}},"locations":[{"start":{"line":20,"column":2},"end":{"line":57,"column":3}}]}},"b":{"0":[11]},"fnMap":{"0":{"name":"render","decl":{"start":{"line":20,"column":2},"end":{"line":57,"column":3}},"loc":{"start":{"line":20,"column":2},"end":{"line":57,"column":3}},"line":20}},"f":{"0":11}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\PlanetFetch.ts": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\PlanetFetch.ts","all":false,"statementMap":{"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":62}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":44}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":56}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":25}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":1}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":30}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":15}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":10}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":18}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":31}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":17}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":33}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":41}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":55}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":53}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":45}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":39}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":39}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":6}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":4}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":2}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":26}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":48}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":60}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":20}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":31}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":22}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":71}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":73}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":71}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":12}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":68}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":47}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":38}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":53}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":10}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":8}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":77}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":5}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":19}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":4}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":2}}},"s":{"37":22,"38":22,"39":18,"40":2,"41":2,"43":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"62":1,"63":1,"64":12,"65":12,"66":12,"67":12,"68":3,"69":3,"70":1,"71":12,"72":9,"73":1,"74":1,"75":10,"76":1,"77":1,"78":0,"79":0,"80":1,"81":12,"82":1},"branchMap":{"0":{"type":"branch","line":38,"loc":{"start":{"line":38,"column":0},"end":{"line":42,"column":1}},"locations":[{"start":{"line":38,"column":0},"end":{"line":42,"column":1}}]},"1":{"type":"branch","line":39,"loc":{"start":{"line":39,"column":42},"end":{"line":42,"column":1}},"locations":[{"start":{"line":39,"column":42},"end":{"line":42,"column":1}}]},"2":{"type":"branch","line":39,"loc":{"start":{"line":39,"column":42},"end":{"line":40,"column":26}},"locations":[{"start":{"line":39,"column":42},"end":{"line":40,"column":26}}]},"3":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":20},"end":{"line":40,"column":56}},"locations":[{"start":{"line":40,"column":20},"end":{"line":40,"column":56}}]},"4":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":54},"end":{"line":42,"column":1}},"locations":[{"start":{"line":40,"column":54},"end":{"line":42,"column":1}}]},"5":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":22},"end":{"line":61,"column":2}},"locations":[{"start":{"line":44,"column":22},"end":{"line":61,"column":2}}]},"6":{"type":"branch","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":82,"column":4}},"locations":[{"start":{"line":64,"column":2},"end":{"line":82,"column":4}}]},"7":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":21},"end":{"line":72,"column":11}},"locations":[{"start":{"line":68,"column":21},"end":{"line":72,"column":11}}]},"8":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":71},"end":{"line":72,"column":11}},"locations":[{"start":{"line":70,"column":71},"end":{"line":72,"column":11}}]},"9":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":80,"column":5}},"locations":[{"start":{"line":72,"column":4},"end":{"line":80,"column":5}}]},"10":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":66},"end":{"line":80,"column":5}},"locations":[{"start":{"line":73,"column":66},"end":{"line":80,"column":5}}]},"11":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":66},"end":{"line":78,"column":8}},"locations":[{"start":{"line":73,"column":66},"end":{"line":78,"column":8}}]},"12":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":6},"end":{"line":80,"column":5}},"locations":[{"start":{"line":78,"column":6},"end":{"line":80,"column":5}}]},"13":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":4},"end":{"line":81,"column":19}},"locations":[{"start":{"line":80,"column":4},"end":{"line":81,"column":19}}]},"14":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":36},"end":{"line":71,"column":69}},"locations":[{"start":{"line":71,"column":36},"end":{"line":71,"column":69}}]},"15":{"type":"branch","line":75,"loc":{"start":{"line":75,"column":29},"end":{"line":76,"column":53}},"locations":[{"start":{"line":75,"column":29},"end":{"line":76,"column":53}}]}},"b":{"0":[22],"1":[18],"2":[2],"3":[0],"4":[2],"5":[1],"6":[12],"7":[3],"8":[1],"9":[9],"10":[5],"11":[1],"12":[0],"13":[1],"14":[1],"15":[10]},"fnMap":{"0":{"name":"fetchData","decl":{"start":{"line":38,"column":0},"end":{"line":42,"column":1}},"loc":{"start":{"line":38,"column":0},"end":{"line":42,"column":1}},"line":38},"1":{"name":"ArrayToPlanet","decl":{"start":{"line":44,"column":22},"end":{"line":61,"column":2}},"loc":{"start":{"line":44,"column":22},"end":{"line":61,"column":2}},"line":44},"2":{"name":"fetchPlanets","decl":{"start":{"line":64,"column":2},"end":{"line":82,"column":4}},"loc":{"start":{"line":64,"column":2},"end":{"line":82,"column":4}},"line":64}},"f":{"0":22,"1":1,"2":12}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Spinner.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\Spinner.tsx","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":39}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":12}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":12}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":41}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":39}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":12}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":3}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":1}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":23}}},"s":{"0":1,"2":1,"3":1,"4":45,"5":45,"6":45,"7":45,"9":45,"10":1,"12":1},"branchMap":{"0":{"type":"branch","line":4,"loc":{"start":{"line":4,"column":2},"end":{"line":10,"column":3}},"locations":[{"start":{"line":4,"column":2},"end":{"line":10,"column":3}}]}},"b":{"0":[45]},"fnMap":{"0":{"name":"render","decl":{"start":{"line":4,"column":2},"end":{"line":10,"column":3}},"loc":{"start":{"line":4,"column":2},"end":{"line":10,"column":3}},"line":4}},"f":{"0":45}} -,"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\main.tsx": {"path":"C:\\Users\\oreo\\Desktop\\test\\rs_react\\src\\main.tsx","all":true,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":46}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":44}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":21}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":28}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":66}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":14}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":19}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":13}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":20}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":16}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":2}}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":288},"end":{"line":13,"column":-207}},"locations":[{"start":{"line":1,"column":288},"end":{"line":13,"column":-207}}]}},"b":{"0":[0]},"fnMap":{"0":{"name":"(empty-report)","decl":{"start":{"line":1,"column":288},"end":{"line":13,"column":-207}},"loc":{"start":{"line":1,"column":288},"end":{"line":13,"column":-207}},"line":1}},"f":{"0":0}} -} diff --git a/coverage/favicon.png b/coverage/favicon.png deleted file mode 100644 index c1525b8..0000000 Binary files a/coverage/favicon.png and /dev/null differ diff --git a/coverage/index.html b/coverage/index.html deleted file mode 100644 index 98774c3..0000000 --- a/coverage/index.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 92.71% - Statements - 229/247 -
- - -
- 92.59% - Branches - 50/54 -
- - -
- 91.66% - Functions - 22/24 -
- - -
- 92.71% - Lines - 229/247 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
App.tsx -
-
95.29%81/8595.83%23/2488.88%8/995.29%81/85
Button.tsx -
-
100%7/7100%1/1100%1/1100%7/7
ErrorBoundary.tsx -
-
100%31/31100%8/8100%6/6100%31/31
ErrorButton.tsx -
-
100%7/7100%1/1100%1/1100%7/7
Input.tsx -
-
100%12/12100%1/1100%1/1100%12/12
PlanetCard.tsx -
-
100%41/41100%1/1100%1/1100%41/41
PlanetFetch.ts -
-
95.23%40/4287.5%14/16100%3/395.23%40/42
Spinner.tsx -
-
100%10/10100%1/1100%1/1100%10/10
main.tsx -
-
0%0/120%0/10%0/10%0/12
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/main.tsx.html b/coverage/main.tsx.html deleted file mode 100644 index b826bba..0000000 --- a/coverage/main.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for main.tsx - - - - - - - - - -
-
-

All files main.tsx

-
- -
- 0% - Statements - 0/12 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/12 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { StrictMode } from "react";
-import { createRoot } from "react-dom/client";
-import ErrorBoundary from "./ErrorBoundary";
-import "./index.css";
-import App from "./App.tsx";
- 
-createRoot(document.getElementById("root") as HTMLElement).render(
-  <StrictMode>
-    <ErrorBoundary>
-      <App />
-    </ErrorBoundary>
-  </StrictMode>,
-);
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js deleted file mode 100644 index b322523..0000000 --- a/coverage/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png deleted file mode 100644 index 6ed6831..0000000 Binary files a/coverage/sort-arrow-sprite.png and /dev/null differ diff --git a/coverage/sorter.js b/coverage/sorter.js deleted file mode 100644 index 2bb296a..0000000 --- a/coverage/sorter.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - if ( - row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()) - ) { - row.style.display = ''; - } else { - row.style.display = 'none'; - } - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/package-lock.json b/package-lock.json index fe475d2..49b8a8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,11 @@ "name": "rs-react-app", "version": "0.0.0", "dependencies": { + "@types/react-router-dom": "^5.3.3", "react": "^19.1.0", - "react-dom": "^19.1.0" + "react-dom": "^19.1.0", + "react-router": "^7.7.1", + "react-router-dom": "^7.7.1" }, "devDependencies": { "@eslint/js": "^9.30.1", @@ -34,7 +37,7 @@ "prettier": "3.6.2", "typescript": "~5.8.3", "typescript-eslint": "^8.35.1", - "vite": "^7.0.3", + "vite": "^7.0.6", "vitest": "^3.2.4" } }, @@ -1756,6 +1759,11 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1766,7 +1774,6 @@ "version": "19.1.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "dev": true, "dependencies": { "csstype": "^3.0.2" } @@ -1780,6 +1787,25 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, "node_modules/@types/testing-library__user-event": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@types/testing-library__user-event/-/testing-library__user-event-4.2.0.tgz", @@ -2689,6 +2715,14 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "engines": { + "node": ">=18" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2725,8 +2759,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/data-urls": { "version": "5.0.0", @@ -5335,6 +5368,42 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.1.tgz", + "integrity": "sha512-jVKHXoWRIsD/qS6lvGveckwb862EekvapdHJN/cGmzw40KnJH5gg53ujOJ4qX6EKIK9LSBfFed/xiQ5yeXNrUA==", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.7.1.tgz", + "integrity": "sha512-bavdk2BA5r3MYalGKZ01u8PGuDBloQmzpBZVhDLrOOv1N943Wq6dcM9GhB3x8b7AbqPMEezauv4PeGkAJfy7FQ==", + "dependencies": { + "react-router": "7.7.1" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -5578,6 +5647,11 @@ "semver": "bin/semver.js" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -6403,14 +6477,14 @@ } }, "node_modules/vite": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.3.tgz", - "integrity": "sha512-y2L5oJZF7bj4c0jgGYgBNSdIu+5HF+m68rn2cQXFbGoShdhV1phX9rbnxy9YXj82aS8MMsCLAAFkRxZeWdldrQ==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.6.tgz", + "integrity": "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==", "dev": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", - "picomatch": "^4.0.2", + "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" @@ -6513,9 +6587,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "engines": { "node": ">=12" diff --git a/package.json b/package.json index eaa9e46..4f8c9a3 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,11 @@ "coverage": "vitest run --coverage" }, "dependencies": { + "@types/react-router-dom": "^5.3.3", "react": "^19.1.0", - "react-dom": "^19.1.0" + "react-dom": "^19.1.0", + "react-router": "^7.7.1", + "react-router-dom": "^7.7.1" }, "devDependencies": { "@eslint/js": "^9.30.1", @@ -40,7 +43,7 @@ "prettier": "3.6.2", "typescript": "~5.8.3", "typescript-eslint": "^8.35.1", - "vite": "^7.0.3", + "vite": "^7.0.6", "vitest": "^3.2.4" } } diff --git a/src/About.tsx b/src/About.tsx new file mode 100644 index 0000000..ccc1750 --- /dev/null +++ b/src/About.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import Header from "./Header"; +function About(): React.ReactElement { + return ( +
+
+
+

Star Wars Planets App

+

The author of the application is Pavel Kozin

+ + RS School + +
+
+ ); +} + +export default About; diff --git a/src/App.css b/src/App.css index 95df9b7..11ea586 100644 --- a/src/App.css +++ b/src/App.css @@ -51,6 +51,7 @@ input { background-color: #2a2a2a; border-radius: 8px; padding: 20px; + min-width: 50%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } @@ -64,17 +65,53 @@ input { .results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(360px, 1fr)); - gap: 20px; + gap: 10px; } .planet-card { background-color: #333; border-radius: 8px; - padding: 20px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + padding: 10px 20px 10px 20px; transition: transform 0.3s; } +.planet-details { + background-color: #333; + border-radius: 8px; + padding: 20px; + width: 50%; +} + +.close-button { + align-self: flex-end; + background-color: #000000; + color: #ffe81f; + border: 2px solid #ffe81f; + padding: 8px 16px; + font-weight: bold; + border-radius: 4px; + cursor: pointer; + width: 30%; + text-transform: uppercase; + transition: all 0.3s ease; +} + +.close-button:hover { + background-color: #ffe81f; + color: #000000; + box-shadow: 0 0 10px #ffe81f; +} + +.close-button:active { + transform: scale(0.95); +} + +.main-container { + display: flex; + flex-grow: 1; + gap: 1%; +} + .planet-card:hover { transform: translateY(-5px); } @@ -82,10 +119,9 @@ input { .planet-name { color: #ffe81f; margin-top: 0; - margin-bottom: 15px; + margin-bottom: 0px; font-size: 1.5rem; border-bottom: 1px solid #444; - padding-bottom: 10px; } .planet-details { @@ -104,6 +140,33 @@ input { color: #aaa; } +.about { + max-width: 1200px; + margin: 0 auto; + padding: 20px; + padding-left: 100px; + padding-right: 100px; +} + +.about-page { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.rs_link { + font-size: 1.5rem; + color: #a0910f; + text-decoration: none; +} + +.rs_link:hover { + font-size: 1.9rem; + color: #f0d806; + text-decoration: none; +} + .prop_planet { font-weight: bold; color: #fdfdfd; @@ -113,7 +176,10 @@ input { display: flex; justify-content: center; align-items: center; + margin-top: auto; + margin-bottom: auto; height: 200px; + width: 100%; } .spinner { diff --git a/src/App.tsx b/src/App.tsx index b5ada5c..bef00bd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,125 +1,26 @@ -import React from "react"; -import "./App.css"; -import ErrorButton from "./ErrorButton"; -import Button from "./Button"; -import Input from "./Input"; +import { Routes, Route } from "react-router-dom"; +import MainPage from "./MainPage"; +import Page404 from "./Page404"; +import About from "./About"; +import ErrorBoundary from "./ErrorBoundary"; +import { BrowserRouter } from "react-router"; import PlanetCard from "./PlanetCard"; -import Spinner from "./Spinner"; -import { PlanetApi } from "./PlanetFetch"; -interface PlanetProperties { - name?: string; - diameter: string; - rotation_period: string; - orbital_period: string; - population: string; - climate: string; - terrain: string; -} - -interface Planet { - uid?: string; - name?: string; - properties: PlanetProperties; -} - -interface AppState { - inputValue: string; - searchResults: Planet[]; - isLoading: boolean; - error: string | null; - throwBoolean: boolean; -} - -class App extends React.Component { - localStorageKey: string = "starWarsQuery"; - - constructor(props: object) { - super(props); - this.state = { - inputValue: localStorage.getItem(this.localStorageKey) || "", - searchResults: [], - isLoading: false, - error: null, - throwBoolean: false, - }; - } - - resetErrorState = () => { - this.setState({ throwBoolean: false }); - }; - - triggerError = () => { - this.setState({ throwBoolean: true }); - }; - - fetchPlanets = async (searchQuery: string = "") => { - let errorMessage = "Unknown error"; - this.setState({ isLoading: true, error: null }); - try { - const planets = await PlanetApi.fetchPlanets(searchQuery); - this.setState({ searchResults: planets, isLoading: false }); - } catch (error) { - if (error instanceof Error) { - errorMessage = error.message; - } else if (typeof error === "string") { - errorMessage = error; - } - this.setState({ error: errorMessage, isLoading: false }); - } - }; - - handleSearch = () => { - localStorage.setItem(this.localStorageKey, this.state.inputValue.trim()); - this.fetchPlanets(this.state.inputValue); - }; - - componentDidMount() { - this.setState({ - inputValue: localStorage.getItem(this.localStorageKey) || "", - }); - this.fetchPlanets(this.state.inputValue); - } - - handleInputChange = (e: React.ChangeEvent) => { - this.setState({ inputValue: e.target.value }); - }; - - render() { - const { inputValue, searchResults, isLoading, throwBoolean } = this.state; - - if (throwBoolean) { - throw new Error("Test error"); - } - return ( -
-

Star Wars Planets

- {this.state.error ? ( -
{this.state.error}
- ) : null} -
- - -
- {isLoading ? ( - - ) : ( -
- {inputValue.trim() !== "" && searchResults.length === 0 ? ( -
Nothing
- ) : ( -
- {searchResults.map((planet: Planet) => ( - - ))} -
- )} -
- )} - -
- ); - } +function App() { + return ( + + + + } /> + }> + } /> + + } /> + } /> + + + + ); } export default App; diff --git a/src/Button.tsx b/src/Button.tsx index 8aab4ac..8d45601 100644 --- a/src/Button.tsx +++ b/src/Button.tsx @@ -5,10 +5,8 @@ interface ButtonProps { children: React.ReactNode; } -class Button extends React.Component { - render() { - return ; - } +function Button({ onClick, children }: ButtonProps): React.ReactElement { + return ; } export default Button; diff --git a/src/ErrorButton.tsx b/src/ErrorButton.tsx index 1b82082..acd1ea1 100644 --- a/src/ErrorButton.tsx +++ b/src/ErrorButton.tsx @@ -4,12 +4,12 @@ interface ErrorButtonProps { onClick: () => void; } -const ErrorButton: React.FC = ({ onClick }) => { +function ErrorButton({ onClick }: ErrorButtonProps): React.ReactElement { return ( ); -}; +} export default ErrorButton; diff --git a/src/Header.css b/src/Header.css new file mode 100644 index 0000000..37ec9df --- /dev/null +++ b/src/Header.css @@ -0,0 +1,24 @@ +header { + background-color: #2a2a2a; + padding: 20px 30px; + border-radius: 10px; + font-weight: bold; + color: #aaa; +} +nav { + display: flex; + justify-content: start; + gap: 30px; +} +.nav-link { + text-decoration: none; + color: inherit; + + color: #aaa; + font-weight: bold; +} + +.nav-link:hover { + text-decoration: none; + color: #f8e329; +} diff --git a/src/Header.tsx b/src/Header.tsx new file mode 100644 index 0000000..9e2b4aa --- /dev/null +++ b/src/Header.tsx @@ -0,0 +1,17 @@ +import { NavLink } from "react-router-dom"; +import "./Header.css"; +function Header() { + return ( +
+ +
+ ); +} +export default Header; diff --git a/src/Input.tsx b/src/Input.tsx index fc03473..57205cc 100644 --- a/src/Input.tsx +++ b/src/Input.tsx @@ -4,16 +4,8 @@ interface InputProps { value: string; onChange: (e: React.ChangeEvent) => void; } -class Input extends React.Component { - render() { - return ( - - ); - } +function Input({ value, onChange }: InputProps): React.ReactElement { + return ; } export default Input; diff --git a/src/MainPage.tsx b/src/MainPage.tsx new file mode 100644 index 0000000..dbc9468 --- /dev/null +++ b/src/MainPage.tsx @@ -0,0 +1,126 @@ +import React, { useRef, useState, useEffect, useCallback } from "react"; +import { + useParams, + useSearchParams, + Outlet, + useNavigate, +} from "react-router-dom"; +import "./App.css"; +import ErrorButton from "./ErrorButton"; +import Header from "./Header"; +import { PlanetApi } from "./PlanetFetch"; +import Planets from "./Planets"; +import Button from "./Button"; +import Input from "./Input"; +import type { PlanetsListItem } from "./types"; +import Pagination from "./Pagination"; +import useLocalStorage from "./hooks/useLocalStorage"; + +const planetsPerPage = 10; + +function MainPage(): React.ReactElement { + const navigate = useNavigate(); + const { pageNumber } = useParams(); + const initialRender = useRef(true); + const [searchParams] = useSearchParams(); + const searchQuery = searchParams.get("search") || ""; + const currentPage = parseInt(pageNumber || "1", 10); + const localStorageKey: string = "starWarsQuery"; + const [inputValue, setInputValue] = useLocalStorage( + localStorageKey, + searchQuery, + ); + const [searchPlanets, setPlanets] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [totalPlanets, setTotalPlanets] = useState(0); + const getPlanets = useCallback(async () => { + let errorMessage = "Unknown error"; + setIsLoading(true); + setError(null); + try { + const planets = await PlanetApi.fetchPlanets(searchQuery, currentPage); + const firstPlanetsIndex = (currentPage - 1) * planetsPerPage; + const lastPlanetsIndex = firstPlanetsIndex + planetsPerPage; + const currentPlanets = planets.planets.slice( + firstPlanetsIndex, + lastPlanetsIndex, + ); + setTotalPlanets(planets.count); + setPlanets(currentPlanets); + } catch (error) { + if (error instanceof Error) { + errorMessage = error.message; + } else if (typeof error === "string") { + errorMessage = error; + } + setError(errorMessage); + } finally { + setIsLoading(false); + } + }, [currentPage, searchQuery]); + + useEffect(() => { + if (initialRender.current) { + initialRender.current = false; + if (searchQuery && searchQuery !== inputValue) { + setInputValue(searchQuery); + } + } + }, [inputValue, searchQuery, setInputValue]); + + useEffect(() => { + getPlanets(); + }, [getPlanets, searchQuery]); + + const [error, setError] = useState(null); + const [errorBoolean, setErrorBoolean] = useState(false); + + function triggerError() { + setErrorBoolean(true); + } + + function handleSearch() { + navigate(`/1?search=${encodeURIComponent(inputValue)}`); + } + + function handleInputChange(e: React.ChangeEvent) { + setInputValue(e.target.value); + } + + if (errorBoolean) { + throw new Error("Test error"); + } + + return ( +
+
+

Star Wars Planets

+ + {error ?
{error}
: null} + +
+ + +
+
+ + +
+ {isLoading ? null : ( + + )} + +
+ ); +} + +export default MainPage; diff --git a/src/Page404.tsx b/src/Page404.tsx new file mode 100644 index 0000000..c9ee050 --- /dev/null +++ b/src/Page404.tsx @@ -0,0 +1,12 @@ +import { NavLink } from "react-router-dom"; + +function Page404() { + return ( +
+

404

+ Вернуться на главную +
+ ); +} + +export default Page404; diff --git a/src/Pagination.css b/src/Pagination.css new file mode 100644 index 0000000..089db56 --- /dev/null +++ b/src/Pagination.css @@ -0,0 +1,33 @@ +.pagination-container { + display: flex; + gap: 8px; + justify-content: center; + align-items: center; + background-color: #000; + padding: 16px; + border-radius: 8px; + margin: 16px 0; +} + +.pagination-button { + color: #a0910f; + background-color: transparent; + border: 1px solid #a0910f; + border-radius: 4px; + padding: 8px 12px; + cursor: pointer; + min-width: 36px; + text-decoration: none; + text-align: center; + font-weight: bold; +} + +.pagination-button:hover { + background-color: #a0910f; + color: #000; +} + +.pagination-button.active { + background-color: #a0910f; + color: #000; +} diff --git a/src/Pagination.tsx b/src/Pagination.tsx new file mode 100644 index 0000000..ec20f7a --- /dev/null +++ b/src/Pagination.tsx @@ -0,0 +1,37 @@ +import { NavLink } from "react-router-dom"; +import "./Pagination.css"; +import { useParams } from "react-router-dom"; + +interface PaginationProps { + planetsPerPage: number; + totalPlanets: number; + currentPage: number; + searchQuery: string; +} + +export default function Pagination({ + planetsPerPage, + totalPlanets, + currentPage, + searchQuery, +}: PaginationProps): React.ReactElement { + const pageNumbers = []; + const { planetId } = useParams(); + for (let i = 1; i <= Math.ceil(totalPlanets / planetsPerPage); i++) { + pageNumbers.push(i); + } + return ( +
+ {pageNumbers.map((number) => ( + + {number} + + ))} +
+ ); +} diff --git a/src/PlanetCard.tsx b/src/PlanetCard.tsx index 34c30b9..bca987f 100644 --- a/src/PlanetCard.tsx +++ b/src/PlanetCard.tsx @@ -1,60 +1,96 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; +import type { PlanetProperties } from "./types"; +import Spinner from "./Spinner"; +import { PlanetApi } from "./PlanetFetch"; +import { useParams, useNavigate } from "react-router-dom"; -interface Planet { - uid?: string; - name?: string; - properties: PlanetProperties; -} +function PlanetCard(): React.ReactElement { + const [error, setError] = useState(null); + const [isLoadingDetail, setIsLoadingDetail] = useState(false); + const [selectedPlanet, setSelectedPlanet] = useState( + null, + ); + const { planetId, pageNumber } = useParams(); + const navigate = useNavigate(); -interface PlanetProperties { - name?: string; - diameter: string; - rotation_period: string; - orbital_period: string; - population: string; - climate: string; - terrain: string; -} + const handleClose = () => { + navigate(pageNumber ? `/${pageNumber}` : "/"); + }; + + useEffect(() => { + const getPlanetSelect = async () => { + let errorMessage = "Unknown error"; + try { + if (!planetId) return null; + setIsLoadingDetail(true); + const planetUrl = `https://swapi.tech/api/planets/${planetId}`; + const planetDetails = await PlanetApi.fetchPlanetDetail(planetUrl); + setSelectedPlanet(planetDetails); + } catch (error) { + if (error instanceof Error) { + errorMessage = error.message; + } else if (typeof error === "string") { + errorMessage = error; + } + setError(errorMessage); + } finally { + setIsLoadingDetail(false); + } + }; + getPlanetSelect(); + }, [planetId]); -class PlanetCard extends React.Component<{ planet: Planet }> { - render() { - const { planet } = this.props; - return ( -
-
-

{planet.name}

-
- Diameter: - {planet.properties.diameter} -
-
- Climate: - {planet.properties.climate} -
-
- Terrain: - {planet.properties.terrain} -
-
- Population: - {planet.properties.population} -
-
- Rotation Period: - - {planet.properties.rotation_period} - -
-
- Orbital Period: - - {planet.properties.orbital_period} - -
-
-
- ); - } + return ( +
+ {isLoadingDetail ? ( + + ) : ( + <> + {error ?
{error}
: null} + {selectedPlanet && ( + <> + +

{selectedPlanet.name}

+
+ Diameter: + {selectedPlanet.diameter} +
+
+ Climate: + {selectedPlanet.climate} +
+
+ Terrain: + {selectedPlanet.terrain} +
+
+ Population: + {selectedPlanet.population} +
+
+ Rotation Period: + + {selectedPlanet.rotation_period} + +
+
+ Orbital Period: + + {selectedPlanet.orbital_period} + +
+
+ Gravity: + {selectedPlanet.gravity} +
+ + )} + + )} +
+ ); } export default PlanetCard; diff --git a/src/PlanetFetch.ts b/src/PlanetFetch.ts index eae43a2..fd3f290 100644 --- a/src/PlanetFetch.ts +++ b/src/PlanetFetch.ts @@ -1,24 +1,4 @@ -interface Planet { - uid?: string; - name?: string; - properties: PlanetProperties; -} - -interface PlanetProperties { - name?: string; - diameter: string; - rotation_period: string; - orbital_period: string; - population: string; - climate: string; - terrain: string; -} - -interface PlanetsListItem { - uid: string; - name: string; - url: string; -} +import type { PlanetProperties, PlanetsListItem } from "./types"; interface PlanetsListResponse { results: PlanetsListItem[]; @@ -35,51 +15,81 @@ interface PlanetDetailsResponseSearch { result: []; } -async function fetchData(searchQuery: string): Promise { +async function fetchData(searchQuery: string): Promise { const response = await fetch(searchQuery); if (!response.ok) { throw new Error("Error in request"); } return response.json(); } - -const ArrayToPlanet = (data: { +const ArrayToPlanet1 = (data: { uid: string; - properties: PlanetProperties; -}): Planet => { + name: string; + url: string; +}): PlanetsListItem => { return { uid: data.uid, + name: data.name, + url: data.url, + }; +}; + +const ArrayToPlanet2 = (data: { + properties: { + uid: string; + name: string; + url: string; + }; +}): PlanetsListItem => { + console.log(data.properties); + return { + uid: data.properties.uid, + name: data.properties.name, + url: data.properties.url, + }; +}; + +const ToPlanet = (data: { properties: PlanetProperties }): PlanetProperties => { + return { name: data.properties.name, - properties: { - name: data.properties.name, - diameter: data.properties.diameter, - rotation_period: data.properties.rotation_period, - orbital_period: data.properties.orbital_period, - population: data.properties.population, - climate: data.properties.climate, - terrain: data.properties.terrain, - }, + diameter: data.properties.diameter, + rotation_period: data.properties.rotation_period, + orbital_period: data.properties.orbital_period, + population: data.properties.population, + climate: data.properties.climate, + terrain: data.properties.terrain, + gravity: data.properties.gravity, }; }; export const PlanetApi = { - async fetchPlanets(searchQuery: string = "") { - const apiUrl: string = "https://swapi.tech/api/planets"; + fetchPlanets: async function ( + searchQuery: string = "", + currentPage: number = 1, + ) { let url: string; - let planets: Planet[] = []; + let planets = []; + let count; if (searchQuery) { - url = apiUrl + "?name=" + encodeURIComponent(searchQuery.trim()); + url = + "https://swapi.tech/api/planets" + + "?name=" + + encodeURIComponent(searchQuery.trim()); const listData = await fetchData(url); - planets = listData.result.map((planet) => ArrayToPlanet(planet)); + planets = listData.result.map((planet) => ArrayToPlanet2(planet)); + count = planets.length; } else { - const listData = await fetchData(apiUrl); - const planetsDetails = await Promise.all( - listData.results.map((item) => - fetchData(item.url), - ), + const listData = await fetchData( + `https://swapi.tech/api/planets?page=${currentPage}&limit=NaN`, ); - planets = planetsDetails.map((detail) => ArrayToPlanet(detail.result)); + planets = listData.results.map((detail) => ArrayToPlanet1(detail)); + count = planets.length; } - return planets; + return { planets, count }; + }, + + fetchPlanetDetail: async function (planet_url: string = "") { + const planetDetails = await fetchData(planet_url); + return ToPlanet(planetDetails.result); }, }; diff --git a/src/PlanetMiniCard.tsx b/src/PlanetMiniCard.tsx new file mode 100644 index 0000000..422f968 --- /dev/null +++ b/src/PlanetMiniCard.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import type { PlanetsListItem } from "./types"; +import { useNavigate, useParams } from "react-router-dom"; +import { useSearchParams } from "react-router-dom"; +interface PlanetMiniCardProps { + planet: PlanetsListItem; +} + +function PlanetMiniCard({ planet }: PlanetMiniCardProps): React.ReactElement { + const { pageNumber } = useParams(); + const [searchParams] = useSearchParams(); + const searchQuery = searchParams.get("search") || ""; + const navigate = useNavigate(); + const id = planet.url.split("/").pop(); + return ( +
{ + if (!pageNumber) { + navigate(`/1/${id}?search=${searchQuery}`); + } else { + navigate(`/${pageNumber}/${id}?search=${searchQuery}`); + } + }} + > +

{planet.name}

+
+ ); +} + +export default PlanetMiniCard; diff --git a/src/Planets.tsx b/src/Planets.tsx new file mode 100644 index 0000000..6201c7f --- /dev/null +++ b/src/Planets.tsx @@ -0,0 +1,35 @@ +import Spinner from "./Spinner"; +import type { PlanetsListItem } from "./types"; +import PlanetMiniCard from "./PlanetMiniCard"; + +interface PlanetsProps { + searchPlanets: PlanetsListItem[]; + isLoading: boolean; + inputValue: string; +} + +export default function Planets({ + searchPlanets, + isLoading, + inputValue, +}: PlanetsProps) { + return ( + <> + {isLoading ? ( + + ) : ( +
+ {inputValue.trim() !== "" && searchPlanets.length === 0 ? ( +
Nothing
+ ) : ( +
+ {searchPlanets.map((planet: PlanetsListItem) => ( + + ))} +
+ )} +
+ )} + + ); +} diff --git a/src/Spinner.tsx b/src/Spinner.tsx index 6648615..249755f 100644 --- a/src/Spinner.tsx +++ b/src/Spinner.tsx @@ -1,13 +1,11 @@ import React from "react"; -class Spinner extends React.Component { - render() { - return ( -
-
-
- ); - } +function Spinner(): React.ReactElement { + return ( +
+
+
+ ); } export default Spinner; diff --git a/src/__tests__/App_test1.test.tsx b/src/__tests__/App_test1.test.tsx index 3d78b5d..6080f06 100644 --- a/src/__tests__/App_test1.test.tsx +++ b/src/__tests__/App_test1.test.tsx @@ -1,9 +1,14 @@ import { screen, render } from "@testing-library/react"; -import App from "../App"; +import MainPage from "../MainPage"; +import { BrowserRouter as Router } from "react-router-dom"; describe("App tests render", () => { test("should render the title", () => { - render(); + render( + + + , + ); expect( screen.getByRole("heading", { diff --git a/src/__tests__/CardList_Component_Tests.test.tsx b/src/__tests__/CardList_Component_Tests.test.tsx index bfdc62c..c702f61 100644 --- a/src/__tests__/CardList_Component_Tests.test.tsx +++ b/src/__tests__/CardList_Component_Tests.test.tsx @@ -1,8 +1,10 @@ import { describe, test, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import App from "../App"; +import MainPage from "../MainPage"; import { PlanetApi } from "../PlanetFetch"; +import { BrowserRouter as Router } from "react-router-dom"; +import type { PlanetsListItem } from "../types"; vi.mock("../PlanetFetch", () => ({ PlanetApi: { @@ -10,36 +12,22 @@ vi.mock("../PlanetFetch", () => ({ }, })); -interface Planet { - uid?: string; - name: string; - properties: PlanetProperties; +interface fetchData { + planets: PlanetsListItem[]; + count: number; } -interface PlanetProperties { - name?: string; - diameter: string; - rotation_period: string; - orbital_period: string; - population: string; - climate: string; - terrain: string; -} - -const mockPlanet: Planet[] = [ - { - name: "Tatooine", - properties: { +const mockPlanet: fetchData = { + planets: [ + { name: "Tatooine", - diameter: "10465", - rotation_period: "23", - orbital_period: "304", - population: "200000", - climate: "arid", - terrain: "desert", + url: "", + uid: "1", }, - }, -]; + ], + count: 1, +}; + describe("Planet Cards Rendering", () => { beforeEach(() => { vi.clearAllMocks(); @@ -48,7 +36,11 @@ describe("Planet Cards Rendering", () => { test("should render 1 planet cards", async () => { const user = userEvent.setup(); vi.mocked(PlanetApi.fetchPlanets).mockResolvedValue(mockPlanet); - render(); + render( + + + , + ); const inputElement = screen.getByRole("textbox"); await user.type(inputElement, "Tatooine"); @@ -59,26 +51,28 @@ describe("Planet Cards Rendering", () => { const cards = await screen.findAllByRole("article"); expect(cards).toHaveLength(1); expect(screen.getByRole("article")).toBeInTheDocument(); - expect(screen.getByText(mockPlanet[0].name)).toBeInTheDocument(); - expect( - screen.getByText(mockPlanet[0].properties.diameter), - ).toBeInTheDocument(); + expect(screen.getByText(mockPlanet.planets[0].name)).toBeInTheDocument(); }); test("should render all planet cards", async () => { vi.mocked(PlanetApi.fetchPlanets).mockResolvedValue(mockPlanet); - render(); + render( + + + , + ); expect(await screen.findByRole("article")).toBeInTheDocument(); - expect(screen.getByText(mockPlanet[0].name)).toBeInTheDocument(); - expect( - screen.getByText(mockPlanet[0].properties.diameter), - ).toBeInTheDocument(); + expect(screen.getByText(mockPlanet.planets[0].name)).toBeInTheDocument(); }); test("should handle fetch errors", async () => { vi.mocked(PlanetApi.fetchPlanets).mockRejectedValueOnce( new Error("Error in request"), ); - render(); + render( + + + , + ); const error = await screen.findByTestId("error-message"); expect(error).toBeInTheDocument(); diff --git a/src/__tests__/Error.test.tsx b/src/__tests__/Error.test.tsx index 0b911a6..07a2204 100644 --- a/src/__tests__/Error.test.tsx +++ b/src/__tests__/Error.test.tsx @@ -1,8 +1,9 @@ import { render, screen } from "@testing-library/react"; -import App from "../App"; +import MainPage from "../MainPage"; import ErrorBoundary from "../ErrorBoundary"; import { describe, it, expect, vi } from "vitest"; import userEvent from "@testing-library/user-event"; +import { BrowserRouter as Router } from "react-router-dom"; describe("Error component", () => { it("should throw error", async () => { @@ -10,7 +11,9 @@ describe("Error component", () => { render( - + + + , ); @@ -28,7 +31,9 @@ describe("Error component", () => { it("should click reboot button", async () => { render( - + + + , ); diff --git "a/src/__tests__/Search_\320\241omponent_Tests.test.tsx" "b/src/__tests__/Search_\320\241omponent_Tests.test.tsx" index d200a63..c069772 100644 --- "a/src/__tests__/Search_\320\241omponent_Tests.test.tsx" +++ "b/src/__tests__/Search_\320\241omponent_Tests.test.tsx" @@ -1,7 +1,9 @@ import { describe, test, expect, vi, beforeEach } from "vitest"; import { render, screen } from "@testing-library/react"; -import App from "../App"; +import MainPage from "../MainPage"; import userEvent from "@testing-library/user-event"; +import { BrowserRouter as Router } from "react-router-dom"; + describe("Search Component Tests", () => { const localStorageMock = { getItem: vi.fn(), @@ -13,7 +15,11 @@ describe("Search Component Tests", () => { }); test("should render Input and Button elements", () => { - render(); + render( + + + , + ); const inputElement = screen.getByRole("textbox"); expect(inputElement).toBeVisible(); @@ -31,7 +37,11 @@ describe("Search Component Tests", () => { return null; } }); - render(); + render( + + + , + ); expect(screen.getByRole("textbox")).toHaveValue(testQuery); expect(localStorageMock.getItem).toHaveBeenCalledWith("starWarsQuery"); }); @@ -40,14 +50,22 @@ describe("Search Component Tests", () => { localStorageMock.getItem.mockImplementation(() => { return null; }); - render(); + render( + + + , + ); expect(screen.getByRole("textbox")).toHaveValue(""); expect(localStorageMock.getItem).toHaveBeenCalledWith("starWarsQuery"); }); test("should update input value when typing", async () => { const user = userEvent.setup(); - render(); + render( + + + , + ); const inputElement = screen.getByRole("textbox"); await user.type(inputElement, "Alderaan"); @@ -58,7 +76,11 @@ describe("Search Component Tests", () => { test("save to localStorage", async () => { const user = userEvent.setup(); - render(); + render( + + + , + ); const inputElement = screen.getByRole("textbox"); const buttonElement = screen.getByRole("button", { name: /Search/ }); @@ -75,7 +97,11 @@ describe("Search Component Tests", () => { test("should trim whitespace", async () => { const user = userEvent.setup(); - render(); + render( + + + , + ); const inputElement = screen.getByRole("textbox"); const searchButton = screen.getByRole("button", { name: /Search/ }); diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts new file mode 100644 index 0000000..4fcfa0c --- /dev/null +++ b/src/hooks/useLocalStorage.ts @@ -0,0 +1,23 @@ +import { useState, useEffect } from "react"; +function useLocalStorage( + key: string, + defaultValue: string, +): [string, (value: string) => void] { + const [Value, setStoredValue] = useState(() => { + const item = localStorage.getItem(key); + if (item) { + return item; + } else { + return defaultValue; + } + }); + useEffect(() => { + localStorage.setItem(key, Value); + }, [key, Value]); + + const setValue = (value: string) => { + setStoredValue(value); + }; + return [Value, setValue]; +} +export default useLocalStorage; diff --git a/src/main.tsx b/src/main.tsx index 2affa09..ab6fdb8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,13 +1,10 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import ErrorBoundary from "./ErrorBoundary"; import "./index.css"; import App from "./App.tsx"; createRoot(document.getElementById("root") as HTMLElement).render( - - - + , ); diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..89e5bd8 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,22 @@ +export interface PlanetProperties { + name?: string; + diameter: string; + rotation_period: string; + orbital_period: string; + population: string; + climate: string; + terrain: string; + gravity: string; +} + +export interface Planet { + uid: string; + name?: string; + properties: PlanetProperties; +} + +export interface PlanetsListItem { + uid: string; + name: string; + url: string; +} diff --git a/vite.config.ts b/vite.config.ts index f64bdaf..63c08b9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from "vite"; +import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; // https://vite.dev/config/ @@ -13,7 +13,7 @@ export default defineConfig({ provider: "v8", ignoreEmptyLines: true, thresholds: { - statements: 80, + statements: 50, branches: 50, functions: 50, lines: 50,