Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [NMP-81] Farm Information Page #91

Merged
merged 13 commits into from
Dec 10, 2024
36 changes: 36 additions & 0 deletions frontend/src/components/appNav/NavButton/NavButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @summary A reusable nav button component used for routing to different pages
* @param path - is the path the Link will route to
* @param text - is the text displayed on the button
* @param hex - HexValue for the Nav Button background
* @param icon - Image to place in Nav Container
* @type {(path: string, text: string, icon: string, hex: string)}
*/
import { Link } from 'react-router-dom';
import { ButtonCont, ImageCont, TextCont, Image } from './navButton.styles';

export type RoutingLinkProps = {
path: string;
text: string;
icon?: string;
hex: string;
};

export default function NavButton({ path, text, icon, hex }: RoutingLinkProps) {
return (
<Link
to={path}
style={{ textDecoration: 'none' }}
>
<ButtonCont hex={hex}>
<ImageCont>
<Image
src={icon}
alt={text}
/>
</ImageCont>
<TextCont>{text}</TextCont>
</ButtonCont>
</Link>
);
}
55 changes: 55 additions & 0 deletions frontend/src/components/appNav/NavButton/navButton.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* @summary Styling for RoutingLink component
*/
import styled from '@emotion/styled';

type NavProps = {
hex: string;
};

export const ButtonCont = styled.div<NavProps>`
height: 75pt;
width: 220pt;
border-radius: 8pt;
align-items: center;
justify-content: flex-start;
background-color: ${({ hex }) => hex || '#000'};
padding: 5pt;
display: flex;
&:hover {
transform: scale(0.95);
}
`;

export const ImageCont = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 50pt;
height: 45pt;
border-radius: 8pt;
margin: 0 0 0 10pt;
padding: 0;
`;

export const TextCont = styled.div`
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
font-size: 16pt;
text-wrap: auto;
width: 100%;
height: 70pt;
color: black;
margin: 0;
padding: 0 0 0 1em;
`;
export const Image = styled.img`
height: 100%;
display: flex;
margin: 0;
padding: 0;
justify-content: center;
align-items: center;
`;
3 changes: 3 additions & 0 deletions frontend/src/components/appNav/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import NavButton from './NavButton/NavButton';

export default NavButton;
28 changes: 28 additions & 0 deletions frontend/src/components/common/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @summary Reusable Checkbox Component
*/
import React from 'react';
import { CheckboxWrapper, StyledLabel } from './checkbox.styles';

interface CheckboxProps {
label: string;
name: string;
checked: boolean;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

function Checkbox({ label, name, checked, onChange }: CheckboxProps) {
return (
<CheckboxWrapper>
<input
type="checkbox"
name={name}
checked={checked}
onChange={onChange}
/>
<StyledLabel htmlFor={name}>{label}</StyledLabel>
</CheckboxWrapper>
);
}

export default Checkbox;
14 changes: 14 additions & 0 deletions frontend/src/components/common/Checkbox/checkbox.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @summary Styles for reusable Checkbox component
*/
import styled from '@emotion/styled';

export const CheckboxWrapper = styled.div`
display: flex;
align-items: center;
`;

export const StyledLabel = styled.label`
margin-left: 8px;
font-size: 14px;
`;
38 changes: 38 additions & 0 deletions frontend/src/components/common/DropDown/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @summary A reusable Dropdown component
*/
import React from 'react';
import { DropdownWrapper, StyledLabel, StyledSelect } from './dropDown.styles';

interface DropdownProps {
label: string;
name: string;
value: string;
options: { value: string; label: string }[];
onChange: (e: React.ChangeEvent<HTMLSelectElement>) => void;
flex?: string;
}

function Dropdown({ label, name, value, options, onChange, flex }: DropdownProps) {
return (
<DropdownWrapper flex={flex}>
<StyledLabel htmlFor={name}>{label}</StyledLabel>
<StyledSelect
name={name}
value={value}
onChange={onChange}
>
{options.map((option) => (
<option
key={option.value}
value={option.value}
>
{option.label}
</option>
))}
</StyledSelect>
</DropdownWrapper>
);
}

export default Dropdown;
28 changes: 28 additions & 0 deletions frontend/src/components/common/DropDown/dropDown.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @summary Styling for Dropdown component
*/
import styled from '@emotion/styled';

export const DropdownWrapper = styled.div<{ flex?: string }>`
display: flex;
flex-direction: column;
margin-bottom: 16px;
flex: ${({ flex }) => flex || '1'};
`;

export const StyledLabel = styled.label`
margin-bottom: 8px;
font-size: 14px;
text-align: left;
`;

export const StyledSelect = styled.select`
padding: 8px;
font-size: 16px;
border: 1px solid #c8c8c8;
border-radius: 4px;
&:focus {
border-color: #c8c8c8;
outline: none;
}
`;
3 changes: 1 addition & 2 deletions frontend/src/components/common/Footer/footer.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* @summary Styles for reusable Header component
* @author Dallas Richmond
* @summary Styles for reusable Footer component
*/
import styled from '@emotion/styled';
import screenSizes from '../../../constants/screenSizes';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/Header/header.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* @summary Styles for reusable Header component
* @author Dallas Richmond
*/
import styled from '@emotion/styled';
import screenSizes from '../../../constants/screenSizes';
Expand Down Expand Up @@ -41,6 +40,7 @@ export const Banner = styled.div`
align-items: center;
margin: 0;
`;

export const BannerRight = styled.div`
min-width: 35pt;
display: flex;
Expand Down
30 changes: 30 additions & 0 deletions frontend/src/components/common/InputField/InputField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @summary Reusable Input Field Component
*/
import React from 'react';
import { InputWrapper, StyledLabel, StyledInput } from './inputField.styles';

interface InputFieldProps {
label: string;
type: string;
name: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
flex?: string;
}

function InputField({ label, type, name, value, onChange, flex }: InputFieldProps) {
return (
<InputWrapper flex={flex}>
<StyledLabel htmlFor={name}>{label}</StyledLabel>
<StyledInput
type={type}
name={name}
value={value}
onChange={onChange}
/>
</InputWrapper>
);
}

export default InputField;
28 changes: 28 additions & 0 deletions frontend/src/components/common/InputField/inputField.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @summary Styling for InputField component
*/
import styled from '@emotion/styled';

export const InputWrapper = styled.div<{ flex?: string }>`
display: flex;
flex-direction: column;
margin-bottom: 16px;
flex: ${({ flex }) => flex || '1'};
`;

export const StyledLabel = styled.label`
margin-bottom: 8px;
font-size: 14px;
text-align: left;
`;

export const StyledInput = styled.input`
padding: 8px;
font-size: 16px;
border: 1px solid #c8c8c8;
border-radius: 4px;
&:focus {
border-color: #c8c8c8;
outline: none;
}
`;
28 changes: 28 additions & 0 deletions frontend/src/components/common/RadioButton/RadioButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// frontend/src/components/common/RadioButton/RadioButton.tsx
import React from 'react';
import { RadioButtonWrapper, StyledLabel } from './radioButton.styles';

interface RadioButtonProps {
label: string;
name: string;
value: string;
checked: boolean;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}

function RadioButton({ label, name, value, checked, onChange }: RadioButtonProps) {
return (
<RadioButtonWrapper>
<input
type="radio"
name={name}
value={value}
checked={checked}
onChange={onChange}
/>
<StyledLabel htmlFor={name}>{label}</StyledLabel>
</RadioButtonWrapper>
);
}

export default RadioButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* @summary Styling for RadioButton component
*/
import styled from '@emotion/styled';

export const RadioButtonWrapper = styled.div`
display: flex;
align-items: center;
`;

export const StyledLabel = styled.label`
margin-left: 8px;
font-size: 14px;
`;
6 changes: 5 additions & 1 deletion frontend/src/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Header from './Header/Header';
import { Button } from './Button/Button';
import Footer from './Footer/Footer';
import InputField from './InputField/InputField';
import RadioButton from './RadioButton/RadioButton';
import Checkbox from './Checkbox/Checkbox';
import Dropdown from './DropDown/DropDown';

export { Header, Button, Footer };
export { Header, Button, Footer, InputField, RadioButton, Checkbox, Dropdown };
5 changes: 5 additions & 0 deletions frontend/src/routes/ViewRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { Routes, Route } from 'react-router-dom';

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

export default function ViewRouter() {
return (
Expand All @@ -12,6 +13,10 @@ export default function ViewRouter() {
path="/"
Component={LandingPage}
/>
<Route
path="/farm-information"
Component={FarmInformation}
/>
</Routes>
);
}
Loading
Loading