mirror of
https://github.com/Mastermindzh/react-starter-kit.git
synced 2025-01-20 18:41:41 +01:00
Moved examples into example directory
Moved routes to separate file Used route constants
This commit is contained in:
parent
de1484e9a1
commit
8496f5cfbe
@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.4.1] - 2022-06-26
|
||||||
|
|
||||||
|
- Moved examples into example directory
|
||||||
|
- Moved routes to separate file
|
||||||
|
- Used route constants
|
||||||
|
|
||||||
## [0.4.0] - 2022-07-25
|
## [0.4.0] - 2022-07-25
|
||||||
|
|
||||||
- Added the possibility to override partial configs during deployments
|
- Added the possibility to override partial configs during deployments
|
||||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-starter-kit",
|
"name": "react-starter-kit",
|
||||||
"version": "0.4.0",
|
"version": "0.4.1",
|
||||||
"description": "A modern, create-react-app-based, starter kit for React projects",
|
"description": "A modern, create-react-app-based, starter kit for React projects",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
|
19
src/App.tsx
19
src/App.tsx
@ -1,26 +1,13 @@
|
|||||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import { AboutContainer } from "./features/about/About";
|
|
||||||
import { CounterContainer } from "./features/counter/Counter";
|
|
||||||
import { HomeContainer } from "./features/home/Home";
|
|
||||||
import { Navbar } from "./infrastructure/navbar/Navbar";
|
import { Navbar } from "./infrastructure/navbar/Navbar";
|
||||||
|
import { AppRoutes } from "./Routes";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Routes>
|
<AppRoutes />
|
||||||
<Route path="/" element={<HomeContainer />} />
|
|
||||||
<Route path="/about" element={<AboutContainer />} />
|
|
||||||
<Route path="/counter" element={<CounterContainer />} />
|
|
||||||
{/* <Route index element={<Home />} /> */}
|
|
||||||
{/* <Route path="teams" element={<Teams />}>
|
|
||||||
<Route path=":teamId" element={<Team />} />
|
|
||||||
<Route path="new" element={<NewTeamForm />} />
|
|
||||||
<Route index element={<LeagueStandings />} />
|
|
||||||
</Route> */}
|
|
||||||
{/* </Route> */}
|
|
||||||
</Routes>
|
|
||||||
</div>
|
</div>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
);
|
);
|
||||||
|
30
src/Routes.tsx
Normal file
30
src/Routes.tsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { FunctionComponent } from "react";
|
||||||
|
import { Route, Routes } from "react-router-dom";
|
||||||
|
import { AboutContainer } from "./features/about/About";
|
||||||
|
import { CounterContainer } from "./features/examples/counter/Counter";
|
||||||
|
import { HomeContainer } from "./features/home/Home";
|
||||||
|
type Props = {};
|
||||||
|
|
||||||
|
export const ROUTE_KEYS = {
|
||||||
|
home: "",
|
||||||
|
about: "about",
|
||||||
|
counter: "counter",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AppRoutes: FunctionComponent<Props> = () => {
|
||||||
|
const { home, about, counter } = ROUTE_KEYS;
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path={home} element={<HomeContainer />} />
|
||||||
|
<Route path={about} element={<AboutContainer />} />
|
||||||
|
<Route path={counter} element={<CounterContainer />} />
|
||||||
|
{/* <Route index element={<Home />} /> */}
|
||||||
|
{/* <Route path="teams" element={<Teams />}>
|
||||||
|
<Route path=":teamId" element={<Team />} />
|
||||||
|
<Route path="new" element={<NewTeamForm />} />
|
||||||
|
<Route index element={<LeagueStandings />} />
|
||||||
|
</Route> */}
|
||||||
|
{/* </Route> */}
|
||||||
|
</Routes>
|
||||||
|
);
|
||||||
|
};
|
@ -1,5 +1,5 @@
|
|||||||
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit";
|
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit";
|
||||||
import counterReducer from "../features/counter/state/counterSlice";
|
import counterReducer from "../features/examples/counter/state/counterSlice";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
|
@ -2,7 +2,14 @@ import { FunctionComponent, ReactNode } from "react";
|
|||||||
import { I18nextProvider, useTranslation } from "react-i18next";
|
import { I18nextProvider, useTranslation } from "react-i18next";
|
||||||
import i18n from "./i18n";
|
import i18n from "./i18n";
|
||||||
|
|
||||||
type Props = { children?: ReactNode; keysOnly?: boolean };
|
type Props = {
|
||||||
|
children?: ReactNode;
|
||||||
|
/**
|
||||||
|
* Whether to show the translation keys instead of translated text
|
||||||
|
* Can be useful to test languages that don't have full translations
|
||||||
|
*/
|
||||||
|
keysOnly?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const ProvidedComponent: FunctionComponent<Props> = ({ children, keysOnly }) => {
|
const ProvidedComponent: FunctionComponent<Props> = ({ children, keysOnly }) => {
|
||||||
const [_translate, i18nSettings] = useTranslation();
|
const [_translate, i18nSettings] = useTranslation();
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
// A mock function to mimic making an async request for data
|
|
||||||
export function fetchCount(amount = 1) {
|
|
||||||
return new Promise<{ data: number }>((resolve) => setTimeout(() => resolve({ data: amount }), 500));
|
|
||||||
}
|
|
@ -18,7 +18,7 @@
|
|||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@ -60,7 +60,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.asyncButton:after {
|
.asyncButton:after {
|
||||||
content: '';
|
content: "";
|
||||||
background-color: rgba(112, 76, 182, 0.15);
|
background-color: rgba(112, 76, 182, 0.15);
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useAppDispatch, useAppSelector } from "../../app/hooks";
|
import { useAppDispatch, useAppSelector } from "../../../app/hooks";
|
||||||
import styles from "./Counter.module.css";
|
import styles from "./Counter.module.css";
|
||||||
import { incrementAsync } from "./state/actions/incrementAsync";
|
import { incrementAsync } from "./state/actions/incrementAsync";
|
||||||
import {
|
import {
|
6
src/features/examples/counter/services/counterAPI.ts
Normal file
6
src/features/examples/counter/services/counterAPI.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// A mock function to mimic making an async request for data
|
||||||
|
export function fetchCount(amount = 1) {
|
||||||
|
return new Promise<{ data: number }>((resolve) =>
|
||||||
|
setTimeout(() => resolve({ data: amount }), 500),
|
||||||
|
);
|
||||||
|
}
|
@ -1,8 +1,4 @@
|
|||||||
import counterReducer, {
|
import counterReducer, { increment, decrement, incrementByAmount } from "./counterSlice";
|
||||||
increment,
|
|
||||||
decrement,
|
|
||||||
incrementByAmount,
|
|
||||||
} from "./counterSlice";
|
|
||||||
import { CounterState } from "../models/CounterState";
|
import { CounterState } from "../models/CounterState";
|
||||||
|
|
||||||
describe("counter reducer", () => {
|
describe("counter reducer", () => {
|
@ -1,5 +1,5 @@
|
|||||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
import { AppThunk, RootState } from "../../../app/store";
|
import { AppThunk, RootState } from "../../../../app/store";
|
||||||
import { CounterState } from "../models/CounterState";
|
import { CounterState } from "../models/CounterState";
|
||||||
import { incrementAsync } from "./actions/incrementAsync";
|
import { incrementAsync } from "./actions/incrementAsync";
|
||||||
|
|
@ -8,19 +8,39 @@ export const HomeContainer: FunctionComponent<Props> = () => {
|
|||||||
<p>This is the react base app :)</p>
|
<p>This is the react base app :)</p>
|
||||||
<span>
|
<span>
|
||||||
<span>Learn </span>
|
<span>Learn </span>
|
||||||
<a className="App-link" href="https://reactjs.org/" target="_blank" rel="noopener noreferrer">
|
<a
|
||||||
|
className="App-link"
|
||||||
|
href="https://reactjs.org/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
React
|
React
|
||||||
</a>
|
</a>
|
||||||
<span>, </span>
|
<span>, </span>
|
||||||
<a className="App-link" href="https://redux.js.org/" target="_blank" rel="noopener noreferrer">
|
<a
|
||||||
|
className="App-link"
|
||||||
|
href="https://redux.js.org/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
Redux
|
Redux
|
||||||
</a>
|
</a>
|
||||||
<span>, </span>
|
<span>, </span>
|
||||||
<a className="App-link" href="https://redux-toolkit.js.org/" target="_blank" rel="noopener noreferrer">
|
<a
|
||||||
|
className="App-link"
|
||||||
|
href="https://redux-toolkit.js.org/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
Redux Toolkit
|
Redux Toolkit
|
||||||
</a>
|
</a>
|
||||||
,<span> and </span>
|
,<span> and </span>
|
||||||
<a className="App-link" href="https://react-redux.js.org/" target="_blank" rel="noopener noreferrer">
|
<a
|
||||||
|
className="App-link"
|
||||||
|
href="https://react-redux.js.org/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
React Redux
|
React Redux
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import deepmerge from "deepmerge";
|
import deepmerge from "deepmerge";
|
||||||
|
import { RunTimeConfig } from "./RunTimeConfig";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets and merges both the regular config and the override config from the window
|
* gets and merges both the regular config and the override config from the window
|
||||||
@ -12,4 +13,4 @@ export const mergeConfigs = () => {
|
|||||||
|
|
||||||
mergeConfigs();
|
mergeConfigs();
|
||||||
|
|
||||||
export const Config = window.mergedConfig;
|
export const Config: RunTimeConfig = window.mergedConfig;
|
||||||
|
@ -2,12 +2,14 @@ import { DateTime } from "luxon";
|
|||||||
import { FunctionComponent } from "react";
|
import { FunctionComponent } from "react";
|
||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { ROUTE_KEYS } from "../../Routes";
|
||||||
import { Config } from "../config";
|
import { Config } from "../config";
|
||||||
import "./Navbar.css";
|
import "./Navbar.css";
|
||||||
type Props = {};
|
type Props = {};
|
||||||
|
|
||||||
export const Navbar: FunctionComponent<Props> = () => {
|
export const Navbar: FunctionComponent<Props> = () => {
|
||||||
const [translate, i18n] = useTranslation();
|
const [translate, i18n] = useTranslation();
|
||||||
|
const { home, about, counter } = ROUTE_KEYS;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>{translate("navBar.intro")}</h1>
|
<h1>{translate("navBar.intro")}</h1>
|
||||||
@ -20,13 +22,13 @@ export const Navbar: FunctionComponent<Props> = () => {
|
|||||||
{/* This translation uses a formatter in the translation files */}
|
{/* This translation uses a formatter in the translation files */}
|
||||||
<p>{translate("navBar.currentDate", { date: DateTime.now().toJSDate() })}</p>
|
<p>{translate("navBar.currentDate", { date: DateTime.now().toJSDate() })}</p>
|
||||||
<nav data-testid="nav">
|
<nav data-testid="nav">
|
||||||
<Link to="/" data-testid="nav.home">
|
<Link to={home} data-testid="nav.home">
|
||||||
{translate("nav.home")}
|
{translate("nav.home")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to="/about" data-testid="nav.about">
|
<Link to={about} data-testid="nav.about">
|
||||||
{translate("nav.about")}
|
{translate("nav.about")}
|
||||||
</Link>
|
</Link>
|
||||||
<Link to="/counter" data-testid="nav.counter">
|
<Link to={counter} data-testid="nav.counter">
|
||||||
{translate("nav.counter")}
|
{translate("nav.counter")}
|
||||||
</Link>
|
</Link>
|
||||||
<button onClick={() => i18n.changeLanguage("en")}>en</button>
|
<button onClick={() => i18n.changeLanguage("en")}>en</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user