Skip to content

Commit

Permalink
feat(@set-app): react-redux
Browse files Browse the repository at this point in the history
* chore(@set-app/react-redux): initial Version

Include all the code and dependencies for running example of react-redux

* ci(@set-app): add new react-redux

New example: react-redux on release-please config to be track

* fix(@set-app/react): bump and change dependencies

bump [email protected] and change @vitejs/plugin-react to
@vitejs/[email protected]

* build(@set-app/cli): bump and remove ^ on dependencies

* build(@set-app/docs): remove ^ from typescript dependency

* build(@set-app): fix version [email protected]

* feat(@set-app/cli): add react-redux as new type of project

* style(@set-app/react-redux): order commands for node execution

* fix(@set-app/cli): fix broken dependency @vitejs/plugin-react-swc: 3.0.0

* refactor(@set-app/cli): remove comments and fix comparission

* ci(@set-app/react-redux): add new link to netlify for React-Redux

* docs(@set-app/docs): add init structure for support tools usage

include docs, basic-info, 4 advance-info, adding images and most wording in english

* docs(@set-app/docs): add true links and final site testing

---------

Co-authored-by: Francisco Leonel Moreno Eraso <[email protected]>
  • Loading branch information
Frankeo and Francisco Leonel Moreno Eraso committed Feb 20, 2023
1 parent f310de4 commit f6a6242
Show file tree
Hide file tree
Showing 83 changed files with 2,257 additions and 1,313 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,16 @@ jobs:
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_REACT }}

- name: Deploy Examples React-Redux to Netlify
uses: nwtgck/[email protected]
if: ${{ steps.release.outputs['examples/react-redux--release_created'] }}
with:
publish-dir: './examples/react-redux/src/dist'
production-branch: main
github-token: ${{ secrets.GTIHUB_SET_APP }}
deploy-message: "Deploy from GitHub Actions"
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_REDUX }}
7 changes: 6 additions & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
{"examples/react":"2.0.0","packages/cli":"2.0.0","packages/docs":"0.0.2"}
{
"examples/react": "2.0.0",
"packages/cli": "2.0.0",
"packages/docs": "0.0.2",
"examples/react-redux": "1.0.0"
}
31 changes: 31 additions & 0 deletions examples/react-redux/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:react/recommended",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"prettier"
],
"rules": {
"react/prop-types": 0,
"react/react-in-jsx-scope": 0,
"@typescript-eslint/no-empty-function": 0
},
"plugins": ["react", "import", "jsx-a11y", "@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"ecmaVersion": 2022,
"sourceType": "module",
"ecmaFeatures": { "jsx": true }
},
"env": { "es6": true, "browser": true, "node": true },
"settings": {
"react": { "version": "detect" },
"import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] },
"import/resolver": { "typescript": { "alwaysTryTypes": true } }
}
}
6 changes: 6 additions & 0 deletions examples/react-redux/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
dist/
.env
.DS_Store
coverage/
.vscode/
1 change: 1 addition & 0 deletions examples/react-redux/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
48 changes: 48 additions & 0 deletions examples/react-redux/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@set-app/react-redux",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"check-format": "prettier --check \"src/**/*.{ts,tsx}\"",
"typecheck": "tsc --noEmit",
"lint": "eslint \"src/**/*.{ts,tsx}\" --quiet",
"test": "vitest --run",
"test:watch": "vitest",
"coverage": "vitest run --coverage"
},
"devDependencies": {
"@testing-library/react": "13.4.0",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
"@typescript-eslint/eslint-plugin": "5.40.1",
"@typescript-eslint/parser": "5.40.1",
"@vitejs/plugin-react-swc": "3.0.0",
"@vitest/coverage-c8": "0.28.4",
"eslint": "8.24.0",
"eslint-config-prettier": "8.5.0",
"eslint-import-resolver-typescript": "3.5.3",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsx-a11y": "6.6.1",
"eslint-plugin-react": "7.31.8",
"eslint-plugin-react-hooks": "4.6.0",
"happy-dom": "7.6.0",
"prettier": "2.7.1",
"typescript": "4.8.4",
"vite": "3.1.4",
"vitest": "0.27.2",
"vitest-fetch-mock": "0.2.1"
},
"dependencies": {
"@reduxjs/toolkit": "1.8.6",
"@tanstack/react-query": "4.10.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-redux": "8.0.4",
"react-router-dom": "6.4.1"
}
}
31 changes: 31 additions & 0 deletions examples/react-redux/src/APIResponsesTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export type Animal = "dog" | "cat" | "bird" | "reptile" | "rabbit";

export interface Pet {
id: number;
name: string;
animal: Animal;
description: string;
breed: string;
images: string[];
city: string;
state: string;
}

export interface PetAPIResponse {
numberOfResults: number;
startIndex: number;
endIndex: number;
hasNext: boolean;
pets: Pet[];
}

export interface BreedListAPIResponse {
animal: Animal;
breeds: string[];
}

export interface searchParams {
location: string;
breed: string;
animal: Animal;
}
48 changes: 48 additions & 0 deletions examples/react-redux/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createRoot } from "react-dom/client";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { lazy, Suspense } from "react";
import { Provider } from "react-redux";
import store from "./store";

const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: Infinity,
cacheTime: Infinity,
},
},
});

const Details = lazy(() => import("./Details"));
const SearchParams = lazy(() => import("./SearchParams"));

const App = () => {
return (
<div>
<BrowserRouter>
<Provider store={store}>
<QueryClientProvider client={queryClient}>
<Suspense
fallback={
<div className="loading-pane">
<h2 className="loader">🌀</h2>
</div>
}
>
<header>
<Link to="/">Adopt Me!</Link>
</header>
<Routes>
<Route path="/details/:id" element={<Details />} />
<Route path="/" element={<SearchParams />} />
</Routes>
</Suspense>
</QueryClientProvider>
</Provider>
</BrowserRouter>
</div>
);
};

createRoot(document.getElementById("root") as HTMLElement).render(<App />);
49 changes: 49 additions & 0 deletions examples/react-redux/src/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Component, MouseEvent } from "react";

interface IProps {
images: string[];
}

class Carousel extends Component<IProps> {
state = {
active: 0,
};

static defaultProps = {
images: ["https://pets-images.dev-apis.com/pets/none.jpg"],
};

handleIndexClick = (event: MouseEvent<HTMLElement>) => {
if (!(event.target instanceof HTMLElement)) return;
if (!event.target.dataset.index) return;
this.setState({
active: +event.target.dataset.index,
});
};

render() {
const { active } = this.state;
const { images } = this.props;
return (
<div className="carousel">
<img data-testid="hero" src={images[active]} alt="animal" />
<div className="carousel-smaller">
{images.map((photo, index) => (
// eslint-disable-next-line
<img
data-testid={`thumbnail${index}`}
key={photo}
src={photo}
className={index === active ? "active" : ""}
alt="animal thumbnail"
onClick={this.handleIndexClick}
data-index={index}
/>
))}
</div>
</div>
);
}
}

export default Carousel;
66 changes: 66 additions & 0 deletions examples/react-redux/src/Details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useNavigate, useParams } from "react-router-dom";
import { useState, lazy } from "react";
import ErrorBoundary from "./ErrorBoundary";
import { useGetPetQuery } from "./petApiService";
import { adopt } from "./adoptedPetSlice";
import { useDispatch } from "react-redux";
import Carousel from "./Carousel";

const Modal = lazy(() => import("./Modal"));

const Details = () => {
const { id } = useParams();
if (!id) throw new Error("No ID!");
const [showModal, setShowModal] = useState(false);
const navigate = useNavigate();
const { isLoading, data: pet } = useGetPetQuery(id);
const dispatch = useDispatch();

if (isLoading) {
return (
<div className="loading-pane">
<h2 className="loader">🌀</h2>
</div>
);
}

if (!pet) throw new Error("No PET!");

return (
<div className="details">
<Carousel images={pet.images} />
<div>
<h1>{pet.name}</h1>
<h2>{`${pet.animal}${pet.breed}${pet.city}, ${pet.state}`}</h2>
<button onClick={() => setShowModal(true)}>Adopt {pet.name}</button>
<p>{pet.description}</p>
{showModal ? (
<Modal>
<div>
<h1>Would you like to adopt {pet.name}?</h1>
<div className="buttons">
<button
onClick={() => {
dispatch(adopt(pet));
navigate("/");
}}
>
Yes
</button>
<button onClick={() => setShowModal(false)}>No</button>
</div>
</div>
</Modal>
) : null}
</div>
</div>
);
};

export default function DetailsErrorBoundary() {
return (
<ErrorBoundary>
<Details />
</ErrorBoundary>
);
}
27 changes: 27 additions & 0 deletions examples/react-redux/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// mostly code from reactjs.org/docs/error-boundaries.html
import { Component, ErrorInfo, ReactElement } from "react";
import { Link } from "react-router-dom";

class ErrorBoundary extends Component<{ children: ReactElement }> {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error, info: ErrorInfo) {
console.error("ErrorBoundary caught an error", error, info);
}
render() {
if (this.state.hasError) {
return (
<h2>
There was an error with this listing. <Link to="/">Click here</Link>{" "}
to back to the home page.
</h2>
);
}

return this.props.children;
}
}

export default ErrorBoundary;
22 changes: 22 additions & 0 deletions examples/react-redux/src/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useEffect, useRef, ReactElement } from "react";
import { createPortal } from "react-dom";

const Modal = ({ children }: { children: ReactElement }) => {
const elRef = useRef<HTMLDivElement | null>(null);
if (!elRef.current) {
elRef.current = document.createElement("div");
}

useEffect(() => {
const modalRoot = document.getElementById("modal");
if (!modalRoot || !elRef.current) return;
modalRoot.appendChild(elRef.current);
return () => {
elRef.current && modalRoot.removeChild(elRef.current);
};
}, []);

return createPortal(<div>{children}</div>, elRef.current);
};

export default Modal;
Loading

0 comments on commit f6a6242

Please sign in to comment.