Skip to content
Snippets Groups Projects
Commit 2d2c05e4 authored by gseagren2's avatar gseagren2
Browse files

Version 0.0.1 done

First version is done.
parent 2ebbef94
Branches
No related tags found
No related merge requests found
Showing
with 379 additions and 193 deletions
# React Redux Starter Code
A minimal app to be used as starter code for labs and homework in the SOFT 260
course at UNL. The starter code demonstrates basic usage of the React Hooks
API, the Redux Toolkit (RTK), React Router, Jest, and the React Testing Library
(RTL) in the context of a React Redux progressive web app (PWA).
# Quick Start
Recursively clone this repository and `cd` into the root folder:
```bash
$ git clone --recursive git@git.unl.edu:soft-core/soft-260/react-redux-starter-code.git
$ cd react-redux-starter-code
```
(If you forget `--recursive` when cloning, you can `cd` into your clone and run
`git submodule update --init --recursive` instead.)
Install dependencies:
```bash
$ npm install
```
(You may see a few warnings because `create-react-app` transitively depends on
some deprecated packages.)
Optionally run the linter and the test suite:
```
$ npm run lint
$ npm run test
```
And then serve the application locally:
```
$ npm start
```
When you are done, press control-c to stop the server.
# Folders and Files
The folders and files in the starter code are briefly described below. React
Redux applications use a model-view-controller (MVC) architecture (see
<https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller>), so in
these descriptions the terms "model", "view", and "controller" refer to those
roles from MVC.
## Submodules
* The Git submodule `stylelint-config` contains the stylelint configuration
for the coding style used in the `minimal-app` project.
* The Git submodule `eslint-config` contains the ESLint configuration for the
coding style used in the `minimal-app` project. Per `create-react-app`
convention, in a development build of the main app, a separate, weaker
coding style also warns at runtime about likely bugs.
## General Configuration
* The file `minimal-app/.gitignore` prevents non-source-code files from being
accidentally committed to the repository.
* The file `minimal-app/package.json` describes the project and its
dependencies. It can be edited to customize the inputs and processes used
in various software lifecyle tasks like linting, testing, or deploying.
* The file `minimal-app/package-lock.json` records the exact set of
dependencies used to satisfy the requirements in `minimal-app/package.json`.
It should not be hand-edited; use commands like `npm install` or `npm
uninstall` from the `minimal-app` directory to make changes.
* The folder `minimal-app/node_modules` contains the dependencies installed by
`npm`.
## Application Infrastructure
* The file `minimal-app/public/manifest.json` provides data needed to run the
web application as a PWA. (See
<https://developer.mozilla.org/en-US/docs/Web/Manifest> for more
information.)
* The file `minimal-app/public/logo.svg` is the image used for the app's icon.
(A maskable icon is recommended; see <https://web.dev/maskable-icon/> for
more information and <https://maskable.app/> to test an image.)
* The file `minimal-app/public/index.html` contains the skeleton document in
which the app's HTML is embedded.
* The file `minimal-app/src/index.js` specifies other wrappers around the
application proper than cannot be given in `index.html`, usually because
they involve React components, not pure HTML. In this case, the wrappers:
* Enable extra checks at development time using React strict mode. (See
<https://reactjs.org/docs/strict-mode.html> for more information.)
* Make the Redux store from `minimal-app/src/app/store.js` available to
the app's React components.
* Enable routing with React Router. (See
<https://reacttraining.com/react-router/web> for more information.)
* Apply the letterboxed portrait layout from `index.css`, which is
described next.
* The file `minimal-app/src/index.css` contains the CSS associated with
`index.html`. In this case the CSS forces a letterboxed portrait layout and
specifies a sans-serif font.
## Model and Controller Code
* The file `minimal-app/src/app/store.js` combines the models provided by the
app's features to create a model for the whole app.
* The file `minimal-app/src/features/counter/counterSlice.js` implements a
Redux slice, the model and associated controllers for a particular feature,
which in this case is a simple counter. (See
<https://redux-toolkit.js.org/> for more information.)
## View Code
* The file `minimal-app/src/app.js` implements the React component
representing the entire app. In this case only the universal route, `/*`,
is implemented, but the returned fragment is intentionally written so that
it is easy to add additional routes.
* The file `minimal-app/src/features/counter/counter.js` implements a React
component that counts the number of times a user has tapped a button. This
component uses the slice from `counterSlice.js`.
* The file `minimal-app/src/features/counter/counter.module.css` provides
styles for the React component in `counter.js`.
## Test Infrastructure
* The file `minimal-app/src/setupTests.js` provides setup code that applies to
every test case. In this case that code imports RTL's custom matchers from
testing React components.
* The file `minimal-app/src/testing/mockRedux.js` provides the ability to mock
the part of Redux used by React components under the React Hooks API so that
those view components can be tested independently of model and controller
code.
## Test Code
* The file `minimal-app/app.test.js` demonstrates a snapshot regression test
of the app component with mocked selectors. (See
<https://jestjs.io/docs/en/snapshot-testing> for more information.)
* The file `minimal-app/src/__snapshots__/app.test.js.snap` contains the
oracles for the snapshot tests in `app.test.js`. When the tests are run in
watch mode (using the command `npm test`), these oracles can be updated
interactively if a snapshot test fails due to changed requirements.
* The file `minimal-app/src/features/counter/counter.test.js` demonstrates
non-snapshot tests of the view code in the counter component.
* The file `minimal-app/src/features/counter/counterSlice.test.js`
demonstrates tests of model and controller code.
# Adaptation Checklist
When adapting this code for a new project, make sure to do at least the
following:
* Change the project name, version number, and description in
`minimal-app/package.json`.
* Change the short name, name, description, colors, and other settings in
`minimal-app/public/manifest.json`.
* Change the title, description, and theme color in
`minimal-app/public/index.html`.
* Rename the folder from `minimal-app` to something descriptive and change the
corresponding entries in the outer `package.json`.
* Rerun `npm install` in the outer folder to update `package-lock.json` based
on the above changes.
File moved
{
"name": "@unlsoft/minimal-app",
"version": "1.0.0",
"name": "@unlsoft/algorithm-explorer",
"version": "0.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@unlsoft/minimal-app",
"version": "1.0.0",
"name": "@unlsoft/algorithm-explorer",
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
"@reduxjs/toolkit": "^1.8.3",
{
"name": "@unlsoft/minimal-app",
"version": "1.0.0",
"description": "A minimal app to be used as starter code for labs and homework.",
"name": "@unlsoft/algorithm-explorer",
"version": "0.0.1",
"description": "An designed to help learn the difference in algorithms",
"private": true,
"license": "UNLICENSED",
"scripts": {
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Algorithm Explorer</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
algorithm-explorer/public/logo.png

793 KiB

File moved
{
"short_name": "Minimal App",
"name": "Minimal React Redux App",
"description": "A minimal app to be used as starter code for labs and homework.",
"short_name": "Algorithm Explorer",
"name": "Algorithm Explorer App",
"description": "An app to help with the understanding of algorithms.",
"icons": [
{
"src": "logo.svg",
......
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import AlgorithmSelection from './components/AlgorithmSelection';
import BFS from './components/BFS';
import DFS from './components/DFS';
import Dijkstra from './components/Dijkstra';
import GreedyAlgorithm from './components/GreedyAlgorithm';
import DAC from './components/DAC';
const App = () =>
<Router>
<Routes>
{/* Default route: AlgorithmSelection */}
<Route path="/algorithm-selection" element={<AlgorithmSelection />} />
{/* Routes for individual algorithms */}
<Route path="/bfs" element={<BFS />} />
<Route path="/dfs" element={<DFS />} />
<Route path="/dijkstra" element={<Dijkstra />} />
<Route path="/greedy-algorithm" element={<GreedyAlgorithm />} />
<Route path="/dac" element={<DAC />} />
</Routes>
</Router>
;
export default App;
.algorithm-selection {
text-align: center;
margin-top: 50px;
color: rgb(218 218 218);
}
.algorithm-list {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 20px;
margin-top: 20px;
}
.algorithm-link {
text-decoration: none;
}
.algorithm-card {
width: 200px;
height: 100px;
background-color: rgb(240 240 240);
display: flex;
justify-content: center;
align-items: center;
border: 2px solid rgb(218 218 218);
border-radius: 8px;
font-size: 18px;
font-weight: bold;
color: rgb(51 51 51);
transition: 0.3s ease-in-out;
text-align: center;
box-shadow: 0 4px 6px rgba(0 0 0 10%);
}
.algorithm-card:hover {
background-color: rgb(224 224 224);
transform: scale(1.05);
cursor: pointer;
}
.algorithm-card a {
text-decoration: none;
color: inherit;
}
import React from 'react';
import { Link } from 'react-router-dom';
import './AlgorithmSelection.css';
const AlgorithmSelection = () =>
<div className="algorithm-selection">
<h1>Select an Algorithm to Explore</h1>
<div className="algorithm-list">
<Link to="/bfs" className="algorithm-link">
<div className="algorithm-card">Breadth-First Search (BFS)</div>
</Link>
<Link to="/dfs" className="algorithm-link">
<div className="algorithm-card">Depth-First Search (DFS)</div>
</Link>
<Link to="/dijkstra" className="algorithm-link">
<div className="algorithm-card">Dijkstra's Algorithm</div>
</Link>
<Link to="/greedy-algorithm" className="algorithm-link">
<div className="algorithm-card">Greedy Algorithm</div>
</Link>
<Link to="/dac" className="algorithm-link">
<div className="algorithm-card">Divide and Conquer</div>
</Link>
</div>
</div>
;
export default AlgorithmSelection;
import React from 'react';
const BFS = () =>
<div>
<h1>Breadth-First Search (BFS)</h1>
<p>This is where you can visualize the BFS algorithm.</p>
{/* Add your graph visualizer or algorithm logic here */}
</div>
;
export default BFS;
import React from 'react';
const DAC = () =>
<div>
<h1>Divide and Conquer Algorithm</h1>
<p>This is where you can visualize Divide and Conquer algorithm.</p>
{/* Add your graph visualizer or algorithm logic here */}
</div>
;
export default DAC;
import React from 'react';
const DFS = () =>
<div>
<h1>Depth-First Search (DFS)</h1>
<p>This is where you can visualize the DFS algorithm.</p>
{/* Add your graph visualizer or algorithm logic here */}
</div>
;
export default DFS;
import React from 'react';
const Dijkstra = () =>
<div>
<h1>Dijkstra's Algorithm</h1>
<p>This is where you can visualize Dijkstra's algorithm.</p>
{/* Add your graph visualizer or algorithm logic here */}
</div>
;
export default Dijkstra;
import React from 'react';
const GreedyAlgorithm = () =>
<div>
<h1>Greedy Algorithm</h1>
<p>This is where you can visualize Greedy algorithm.</p>
{/* Add your graph visualizer or algorithm logic here */}
</div>
;
export default GreedyAlgorithm;
:root {
/* Colors */
--letterbox-color: rgba(0 0 0 / 100%);
--app-background-color: rgba(239 239 239 / 100%);
--font-color: rgba(255 255 255 / 100%);
--highlight-color: rgba(115 168 254 / 100%);
--button-background-color: rgb(0 98 255);
--button-hover-color: rgb(0 86 230);
/* Sizes */
--minimum-app-size: 300px;
}
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgb(125 125 125);
}
.landing-page {
display: flex;
align-items: center; /* Center logo and text vertically */
justify-content: space-between; /* Push logo and text apart */
width: 90%;
max-width: 1200px;
height: auto;
background-color: transparent; /* Remove any background */
}
.image-container {
flex-shrink: 0; /* Prevent shrinking of the logo */
max-width: 40%; /* Limit the width of the logo */
text-align: left;
}
.image-container img {
max-width: 100%; /* Ensure the image fits within the container */
height: auto;
display: block;
border: none; /* Remove any borders from the image */
}
.content {
flex-grow: 1; /* Allow the text container to grow */
margin-left: 20px; /* Add spacing between the logo and text */
text-align: left;
}
.content h1 {
font-size: 48px;
margin-bottom: 20px;
color: var(--highlight-color); /* Highlight color for the title */
}
.start-button {
padding: 15px 30px;
font-size: 20px;
background-color: var(--button-background-color); /* Button background color */
color: var(--font-color); /* Button font color */
border: none;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
transition: background-color 0.3s ease;
}
.start-button:hover {
background-color: var(--button-hover-color); /* Hover effect for button */
}
import React from 'react';
import { useNavigate } from 'react-router-dom';
import './LandingPage.css';
const LandingPage = () => {
const navigate = useNavigate();
const handleStart = () => {
navigate('/algorithm-selection');
};
return (
<div className="landing-page">
<div className="image-container">
<img src="logo.png" alt="Algorithm Explorer Logo" />
</div>
<div className="content">
<h1>Welcome to Algorithm Explorer</h1>
<button onClick={handleStart} className="start-button">Start</button>
</div>
</div>
);
};
export default LandingPage;
:root {
/* Colors */
--letterbox-color: rgba(0 0 0 / 100%);
--app-background-color: rgba(239 239 239 / 100%);
--font-color: rgba(255 255 255 / 100%);
--highlight-color: rgba(115 168 254 / 100%);
--button-background-color: rgb(0 98 255);
--button-hover-color: rgb(0 86 230);
/* Sizes */
--minimum-app-size: 300px;
}
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgb(125 125 125);
}
.landing-page {
display: flex;
align-items: center; /* Center logo and text vertically */
justify-content: space-between; /* Push logo and text apart */
width: 90%;
max-width: 1200px;
height: auto;
background-color: transparent; /* Remove any background */
}
.image-container {
flex-shrink: 0; /* Prevent shrinking of the logo */
max-width: 40%; /* Limit the width of the logo */
text-align: left;
}
.image-container img {
max-width: 100%; /* Ensure the image fits within the container */
height: auto;
display: block;
border: none; /* Remove any borders from the image */
}
.content {
flex-grow: 1; /* Allow the text container to grow */
margin-left: 20px; /* Add spacing between the logo and text */
text-align: left;
}
.content h1 {
font-size: 48px;
margin-bottom: 20px;
color: var(--highlight-color); /* Highlight color for the title */
}
.start-button {
padding: 15px 30px;
font-size: 20px;
background-color: var(--button-background-color);
color: var(--font-color);
border: none;
border-radius: 5px;
cursor: pointer;
text-decoration: none;
transition: background-color 0.3s ease;
}
.start-button:hover {
background-color: var(--button-hover-color);
}
import React from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import store from './store';
import './index.css';
import AlgorithmSelection from './components/AlgorithmSelection.jsx';
import BFS from './components/BFS.jsx';
import DFS from './components/DFS.jsx';
import Dijkstra from './components/Dijkstra.jsx';
import GreedyAlgorithm from './components/GreedyAlgorithm';
import DAC from './components/DAC';
import LandingPage from './components/LandingPage.jsx';
createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Provider store={store}>
<Router>
<Routes>
{/* Algorithm Selection is the default ("/") route */}
<Route path="/" element={<LandingPage />} />
<Route path="/algorithm-selection" element={<AlgorithmSelection />} />
<Route path="/bfs" element={<BFS />} />
<Route path="/dfs" element={<DFS />} />
<Route path="/dijkstra" element={<Dijkstra />} />
<Route path="/greedy-algorithm" element={<GreedyAlgorithm />} />
<Route path="/dac" element={<DAC />} />
</Routes>
</Router>
</Provider>
</React.StrictMode>,
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment