Skip to content

Commit

Permalink
feat: [NMP-64 & NMP-65] File upload page (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
dallascrichmond authored Nov 21, 2024
1 parent 021cab9 commit dbc41a1
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 9 deletions.
6 changes: 6 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"dependencies": {
"@bcgov/bc-sans": "^2.1.0",
"@bcgov/design-tokens": "^3.1.1",
"@emotion/styled": "^11.13.0",
"axios": "^1.7.7",
"react": "^18.3.1",
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import StyledApp from './App.styles';
import { Header } from './components/common';
import ViewRouter from './routes/ViewRouter';

/**
* @summary The root component of the application.
Expand All @@ -8,6 +9,7 @@ function App() {
return (
<StyledApp>
<Header />
<ViewRouter />
</StyledApp>
);
}
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/components/common/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* eslint-disable max-len */
/**
* @summary This is a universal button component for use in our application.
* @param handleClick - optional stub function to designate what occurs if button is clicked.
* @param variant - dictates button coloring.
* @param size - dictates button size for general design or mobile reponsiveness.
* @param disabled - prop/value to enable disabled functionality.
* @param text - the text that will display within the button.
* @type {( handleClick: () => void, variant: ButtonVariants, size: ButtonSizes, disabled: boolean, text: string )}
*/

import StyledButton from './button.styles';

export type ButtonVariants = 'default' | 'primary' | 'secondary' | 'tertiary';
export type ButtonSizes = 'sm' | 'md' | 'lg';

export type ButtonProps = {
handleClick?: () => void;
variant: ButtonVariants;
size: ButtonSizes;
disabled: boolean;
text: string;
};

export function Button({ handleClick, variant, size = 'md', disabled = false, text }: ButtonProps) {
return (
<StyledButton
onClick={handleClick}
variant={variant}
size={size}
disabled={disabled}
value=""
>
{text}
</StyledButton>
);
}

Button.defaultProps = {
handleClick: () => {}, // Provide a default empty function
};
52 changes: 52 additions & 0 deletions frontend/src/components/common/Button/button.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* eslint-disable no-nested-ternary */
/**
* @summary This is the styling page for the common button component.
*/
import styled from '@emotion/styled';
import typography from '../../../typography';

type ButtonProps = {
variant: string;
size: string;
disabled: boolean;
};

const StyledButton = styled.button<ButtonProps>`
${typography.toString()}
width: ${(props) => (props.size === 'sm' ? '125px' : props.size === 'md' ? '200px' : '300px')};
height: ${(props) => (props.size === 'sm' ? '35px' : props.size === 'md' ? '70px' : '100px')};
border: none;
border-radius: 8px;
padding: ${(props) => (props.size === 'sm' ? '6pt 2pt' : '12px 32px')};
text-align: center;
text-decoration: none;
font-size: ${(props) => (props.size === 'sm' ? '14px' : '18px')};
font-weight: 500;
letter-spacing: 1px;
cursor: pointer;
background-color: ${(props) =>
props.variant === 'primary'
? '#003366'
: props.variant === 'secondary'
? '#DC3545'
: '#000000'};
background-color: ${(props) =>
props.variant === 'primary'
? '#003366'
: props.variant === 'secondary'
? '#DC3545'
: props.variant === 'tertiary'
? '#198754'
: '#000000'};
color: #ffffff;
&:hover {
transform: scale(0.98);
}
&:disabled {
transform: scale(1);
background-color: #a0a0a0;
cursor: not-allowed;
}
`;

export default StyledButton;
8 changes: 4 additions & 4 deletions frontend/src/components/common/Header/header.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* @author Dallas Richmond
*/
import styled from '@emotion/styled';
import screenSizes from '../../../constants/screenSizes';
import typography from '../../../typography';
import mq from '../../../constants/screensizes';

export const HeaderWrapper = styled.header`
background-color: #036;
Expand All @@ -19,7 +19,7 @@ export const HeaderWrapper = styled.header`
position: fixed;
width: 100%;
left: 0;
@media (min-width: ${mq.tablet}) {
@media (min-width: ${screenSizes.tablet}) {
justify-content: flex-start;
padding: 2em;
}
Expand All @@ -46,7 +46,7 @@ export const BannerRight = styled.div`
display: flex;
padding: 0 0.5em;
margin: 0;
@media (min-width: ${mq.tablet}) {
@media (min-width: ${screenSizes.tablet}) {
margin: 0 0 0 auto;
}
`;
Expand All @@ -63,7 +63,7 @@ export const Image = styled.img`
position: relative;
height: 100%;
padding-right: 10px;
@media (max-width: ${mq.tablet}) {
@media (max-width: ${screenSizes.tablet}) {
width: 100px;
padding-right: 5px;
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Header from './Header/Header';
import { Button } from './Button/Button';

// eslint-disable-next-line import/prefer-default-export
export { Header };
export { Header, Button };
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const screensizes = {
const screenSizes = {
mobile: '480px',
tablet: '768px',
desktop: '1025px',
};

export default screensizes;
export default screenSizes;
5 changes: 4 additions & 1 deletion frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App.tsx';

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
);
17 changes: 17 additions & 0 deletions frontend/src/routes/ViewRouter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @summary Router to different views
*/
import { Routes, Route } from 'react-router-dom';

import LandingPage from '../views/LandingPage/LandingPage';

export default function ViewRouter() {
return (
<Routes>
<Route
path="/"
Component={LandingPage}
/>
</Routes>
);
}
95 changes: 95 additions & 0 deletions frontend/src/views/LandingPage/LandingPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @summary The landing page for the application
*/
import {
Wrapper,
ButtonWrapper,
ViewContainer,
StyledDivider,
StyledContent,
} from './landingPage.styles';
import { Button } from '../../components/common';

export default function LandingPage() {
const handleUpload = () => {
const upload = document.getElementById('fileUp');
if (upload) upload.click();
};

const isValidFile = (file: File): boolean =>
file.type === 'application/json' || file.name.endsWith('.nmp');

const saveFile = (e: any) => {
const file = e.target.files[0];

if (!isValidFile(file)) {
return;
}

const fr = new FileReader();
fr.readAsText(file);

fr.onload = () => {
const data = fr.result;
if (data) {
console.log(data.toString());
// The alert is temporary, will be removed once the data is being used
// eslint-disable-next-line no-alert
alert(data.toString());
}
};
};

const newCalcHandler = () => {
localStorage.clear();
console.log('New Calculation');
// The alert is temporary, will be removed once the data is being used
// eslint-disable-next-line no-alert
alert('New Calculation');
};
return (
<ViewContainer>
<Wrapper>
<ButtonWrapper>
<Button
text="New Calculation"
size="lg"
handleClick={newCalcHandler}
aria-label="New Calculation"
variant="primary"
disabled={false}
/>
</ButtonWrapper>
<StyledDivider>or</StyledDivider>
<ButtonWrapper>
<Button
size="lg"
text="Load Existing File"
handleClick={handleUpload}
aria-label="Upload File"
variant="primary"
disabled={false}
/>
<input
id="fileUp"
type="file"
accept=".nmp, application/json"
onChange={saveFile}
aria-label="Upload File"
hidden
/>
</ButtonWrapper>
<StyledContent>
<p>
All information contained within the Nutrient Management Calculator is provided solely
&quot;as is&quot; at the user&apos;s own risk. Although every effort has been made to
ensure that the information contained in the Nutrient Management Calculator is accurate,
the Government of British Columbia assumes no legal liability or responsibility for the
completeness, accuracy, or usefulness of the information provided or any product
resulting from the use of the Nutrient Management Calculator.
</p>
</StyledContent>
</Wrapper>
</ViewContainer>
);
}
Loading

0 comments on commit dbc41a1

Please sign in to comment.