mirror of
https://github.com/aleleba/test-list-app.git
synced 2025-07-04 15:48:24 -06:00
Initial commit
This commit is contained in:
9
src/frontend/actions/index.ts
Normal file
9
src/frontend/actions/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import test, { TTest } from './testAction';
|
||||
|
||||
export type TAction = TTest
|
||||
|
||||
const actions = {
|
||||
test
|
||||
}
|
||||
|
||||
export default actions
|
25
src/frontend/actions/testAction.ts
Normal file
25
src/frontend/actions/testAction.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export enum ActionTypesTest {
|
||||
ChangeHello = 'CHANGE_HELLO'
|
||||
}
|
||||
|
||||
export interface IChangeHello {
|
||||
type: ActionTypesTest.ChangeHello
|
||||
payload: IChangeHelloPayload
|
||||
}
|
||||
|
||||
export interface IChangeHelloPayload {
|
||||
hello: any | undefined
|
||||
}
|
||||
|
||||
export type TTest = IChangeHello
|
||||
|
||||
const changeHello = (payload: string) => ({
|
||||
type: ActionTypesTest.ChangeHello,
|
||||
payload
|
||||
})
|
||||
|
||||
const actions = {
|
||||
changeHello
|
||||
}
|
||||
|
||||
export default actions
|
20
src/frontend/components/App.tsx
Normal file
20
src/frontend/components/App.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PrincipalRoutes from './PrincipalRoutes';
|
||||
import { config } from '../../../config';
|
||||
|
||||
const App = () => {
|
||||
if(config.ENV === 'development') {
|
||||
useEffect(() => {
|
||||
const ws = new WebSocket(`wss://${config.HOST}/ws`);
|
||||
ws.onmessage = (event) => {
|
||||
if (event.data === 'reload') {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
}
|
||||
|
||||
return <PrincipalRoutes />;
|
||||
};
|
||||
|
||||
export default App;
|
38
src/frontend/components/InitialComponent.scss
Normal file
38
src/frontend/components/InitialComponent.scss
Normal file
@ -0,0 +1,38 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
36
src/frontend/components/InitialComponent.tsx
Normal file
36
src/frontend/components/InitialComponent.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import './InitialComponent.scss';
|
||||
import { connect } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const InitialComponent = ({ hello }: { hello: string }) => {
|
||||
|
||||
return(
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
|
||||
<p>This is the text from the store of redux: <strong>{hello}</strong></p>
|
||||
<p>
|
||||
Edit <code>src/frontend/InitialComponent.jsx</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
<Link className="App-link" to="/other-component">Other Component</Link>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
hello: state.testReducer.hello
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(InitialComponent);
|
18
src/frontend/components/OtherComponent.tsx
Normal file
18
src/frontend/components/OtherComponent.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
// import logo from '../logo.svg';
|
||||
import './InitialComponent.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const OtherComponent = () => (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/frontend/OtherComponent.jsx</code> and save to reload.
|
||||
</p>
|
||||
<Link className="App-link" to="/">Initial Component</Link>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default OtherComponent;
|
11
src/frontend/components/PrincipalRoutes.tsx
Normal file
11
src/frontend/components/PrincipalRoutes.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
//Router
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
//Routes
|
||||
import routes from '../../routes';
|
||||
|
||||
const PrincipalRoutes = () => {
|
||||
let element = useRoutes(routes);
|
||||
return element;
|
||||
};
|
||||
|
||||
export default PrincipalRoutes;
|
16
src/frontend/components/__tests__/App.test.cy.tsx
Normal file
16
src/frontend/components/__tests__/App.test.cy.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import { ProviderMock } from '@mocks';
|
||||
import App from '@components/App';
|
||||
|
||||
describe('Testing Card Component', () => {
|
||||
beforeEach(() => {
|
||||
cy.mount(
|
||||
<ProviderMock>
|
||||
<App />
|
||||
</ProviderMock>
|
||||
);
|
||||
});
|
||||
it('Show Text', () => {
|
||||
cy.get('p').contains('Edit src/frontend/InitialComponent.jsx and save to reload.');
|
||||
});
|
||||
});
|
23
src/frontend/components/__tests__/App.test.tsx
Normal file
23
src/frontend/components/__tests__/App.test.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ProviderMock } from '@mocks';
|
||||
import App from '@components/App';
|
||||
|
||||
describe('<App/> Component', () => {
|
||||
beforeEach(() => {
|
||||
fetchMock.resetMocks();
|
||||
});
|
||||
|
||||
it('Should render root <App /> Component', async () => {
|
||||
fetchMock.mockResponseOnce(JSON.stringify({
|
||||
//First Data Fetch
|
||||
data: 'data'
|
||||
}));
|
||||
|
||||
render(
|
||||
<ProviderMock>
|
||||
<App />
|
||||
</ProviderMock>
|
||||
)
|
||||
})
|
||||
})
|
24
src/frontend/converter/tsxToString.tsx
Normal file
24
src/frontend/converter/tsxToString.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
//Redux
|
||||
import { Provider } from 'react-redux';
|
||||
import setStore from '../setStore';
|
||||
import initialState from '../reducers/initialState';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { StaticRouter } from 'react-router-dom/server';
|
||||
import App from '../components/App';
|
||||
|
||||
const url = process.argv[2];
|
||||
|
||||
const store = setStore({ initialState });
|
||||
|
||||
const render = () => {
|
||||
return renderToString(
|
||||
<Provider store={store}>
|
||||
<StaticRouter location={`${url}`} >
|
||||
<App />
|
||||
</StaticRouter>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
console.log(render());
|
5
src/frontend/getPreloadedState/getPreloadedState.ts
Normal file
5
src/frontend/getPreloadedState/getPreloadedState.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import setStore from '../setStore';
|
||||
import initialState from '../reducers/initialState';
|
||||
const store = setStore({ initialState });
|
||||
const preloadedState = store.getState();
|
||||
console.log(preloadedState);
|
81
src/frontend/index.tsx
Normal file
81
src/frontend/index.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import { hydrateRoot, createRoot } from 'react-dom/client';
|
||||
// Router
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
// Redux
|
||||
import { Provider } from 'react-redux';
|
||||
import { IInitialState } from './reducers/index';
|
||||
import setStore from './setStore';
|
||||
import { config } from '../../config';
|
||||
|
||||
import './styles/global.scss';
|
||||
import App from './components/App';
|
||||
import serviceWorkerRegistration from '../../serviceWorkerRegistration';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__PRELOADED_STATE__?: IInitialState;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface NodeModule {
|
||||
hot?: IHot;
|
||||
}
|
||||
}
|
||||
|
||||
interface IHot {
|
||||
accept: unknown
|
||||
}
|
||||
|
||||
const { ENV, PREFIX_URL } = config;
|
||||
|
||||
const preloadedState = window.__PRELOADED_STATE__;
|
||||
const store = setStore({ initialState: preloadedState });
|
||||
|
||||
delete window.__PRELOADED_STATE__;
|
||||
|
||||
const container = document.getElementById('app')!;
|
||||
|
||||
if(ENV === 'development') {
|
||||
const root = createRoot(container);
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<Router basename={PREFIX_URL}>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// add "const root" to be able to rerender.
|
||||
ENV === 'production' && hydrateRoot(container,
|
||||
<Provider store={store}>
|
||||
<Router basename={PREFIX_URL}>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>,
|
||||
// Add this comment to update later app and remove warning
|
||||
/* {
|
||||
onRecoverableError: (error) => {
|
||||
console.error("recoverable", error);
|
||||
}
|
||||
}, */
|
||||
);
|
||||
|
||||
// Use root.render to update later the app
|
||||
/* root.render(
|
||||
<Provider store={store}>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>
|
||||
); */
|
||||
|
||||
if((ENV) && (ENV === 'production')){
|
||||
serviceWorkerRegistration();
|
||||
}
|
||||
|
||||
/*if(module.hot){
|
||||
module.hot.accept();
|
||||
}*/
|
14
src/frontend/reducers/index.ts
Normal file
14
src/frontend/reducers/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import testReducer from './testReducer';
|
||||
import { IChangeHelloPayload } from '../actions/testAction';
|
||||
|
||||
export interface IInitialState {
|
||||
testReducer?: IChangeHelloPayload | undefined
|
||||
}
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
// Here comes the reducers
|
||||
testReducer
|
||||
});
|
||||
|
||||
export default rootReducer;
|
3
src/frontend/reducers/initialState.ts
Normal file
3
src/frontend/reducers/initialState.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { IInitialState } from './';
|
||||
const initialState: IInitialState = {};
|
||||
export default initialState;
|
20
src/frontend/reducers/testReducer.ts
Normal file
20
src/frontend/reducers/testReducer.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { TAction } from '../actions';
|
||||
|
||||
const initialState = {
|
||||
hello: 'world'
|
||||
};
|
||||
|
||||
const testReducer = (state = initialState, action: TAction) => {
|
||||
switch (action.type){
|
||||
case 'CHANGE_HELLO': {
|
||||
const newHello = action.payload.hello;
|
||||
return {
|
||||
hello: newHello
|
||||
};
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default testReducer;
|
27
src/frontend/setStore.ts
Normal file
27
src/frontend/setStore.ts
Normal file
@ -0,0 +1,27 @@
|
||||
// Redux
|
||||
import { legacy_createStore as createStore} from 'redux'; //, applyMiddleware
|
||||
// import { Provider } from 'react-redux';
|
||||
import { composeWithDevTools as composeWithDevToolsWeb } from '@redux-devtools/extension';
|
||||
import { config } from '../../config';
|
||||
import reducer, { IInitialState } from './reducers';
|
||||
|
||||
|
||||
const { ENV } = config;
|
||||
|
||||
const composeEnhancers = composeWithDevToolsWeb({
|
||||
// Specify here name, actionsBlacklist, actionsCreators and other options
|
||||
});
|
||||
|
||||
const setStore = ({ initialState }: { initialState: IInitialState | undefined }) => {
|
||||
const store = ENV === 'development' ? createStore(
|
||||
reducer,
|
||||
initialState,
|
||||
composeEnhancers(),
|
||||
) : createStore(
|
||||
reducer,
|
||||
initialState,
|
||||
);
|
||||
return store;
|
||||
};
|
||||
|
||||
export default setStore;
|
5
src/frontend/styles/global.scss
Normal file
5
src/frontend/styles/global.scss
Normal file
@ -0,0 +1,5 @@
|
||||
$base-color: #282c34;
|
||||
|
||||
body {
|
||||
background-color: $base-color;
|
||||
}
|
Reference in New Issue
Block a user