diff --git a/frontend/src/components/appNav/NavButton/NavButton.tsx b/frontend/src/components/appNav/NavButton/NavButton.tsx
new file mode 100644
index 0000000..31a0f6f
--- /dev/null
+++ b/frontend/src/components/appNav/NavButton/NavButton.tsx
@@ -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 (
+
+
+
+
+
+ {text}
+
+
+ );
+}
diff --git a/frontend/src/components/appNav/NavButton/navButton.styles.ts b/frontend/src/components/appNav/NavButton/navButton.styles.ts
new file mode 100644
index 0000000..797c779
--- /dev/null
+++ b/frontend/src/components/appNav/NavButton/navButton.styles.ts
@@ -0,0 +1,55 @@
+/**
+ * @summary Styling for RoutingLink component
+ */
+import styled from '@emotion/styled';
+
+type NavProps = {
+ hex: string;
+};
+
+export const ButtonCont = styled.div`
+ 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;
+`;
diff --git a/frontend/src/components/appNav/index.ts b/frontend/src/components/appNav/index.ts
new file mode 100644
index 0000000..5c6c9b2
--- /dev/null
+++ b/frontend/src/components/appNav/index.ts
@@ -0,0 +1,3 @@
+import NavButton from './NavButton/NavButton';
+
+export default NavButton;
diff --git a/frontend/src/components/common/Checkbox/Checkbox.tsx b/frontend/src/components/common/Checkbox/Checkbox.tsx
new file mode 100644
index 0000000..8eef46b
--- /dev/null
+++ b/frontend/src/components/common/Checkbox/Checkbox.tsx
@@ -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) => void;
+}
+
+function Checkbox({ label, name, checked, onChange }: CheckboxProps) {
+ return (
+
+
+ {label}
+
+ );
+}
+
+export default Checkbox;
diff --git a/frontend/src/components/common/Checkbox/checkbox.styles.ts b/frontend/src/components/common/Checkbox/checkbox.styles.ts
new file mode 100644
index 0000000..875e52f
--- /dev/null
+++ b/frontend/src/components/common/Checkbox/checkbox.styles.ts
@@ -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;
+`;
diff --git a/frontend/src/components/common/DropDown/DropDown.tsx b/frontend/src/components/common/DropDown/DropDown.tsx
new file mode 100644
index 0000000..c24c53f
--- /dev/null
+++ b/frontend/src/components/common/DropDown/DropDown.tsx
@@ -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) => void;
+ flex?: string;
+}
+
+function Dropdown({ label, name, value, options, onChange, flex }: DropdownProps) {
+ return (
+
+ {label}
+
+ {options.map((option) => (
+
+ ))}
+
+
+ );
+}
+
+export default Dropdown;
diff --git a/frontend/src/components/common/DropDown/dropDown.styles.ts b/frontend/src/components/common/DropDown/dropDown.styles.ts
new file mode 100644
index 0000000..9d52a0d
--- /dev/null
+++ b/frontend/src/components/common/DropDown/dropDown.styles.ts
@@ -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;
+ }
+`;
diff --git a/frontend/src/components/common/Footer/footer.styles.ts b/frontend/src/components/common/Footer/footer.styles.ts
index 3be0bef..23beb11 100644
--- a/frontend/src/components/common/Footer/footer.styles.ts
+++ b/frontend/src/components/common/Footer/footer.styles.ts
@@ -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';
diff --git a/frontend/src/components/common/Header/header.styles.ts b/frontend/src/components/common/Header/header.styles.ts
index 7f5a0c4..e54f333 100644
--- a/frontend/src/components/common/Header/header.styles.ts
+++ b/frontend/src/components/common/Header/header.styles.ts
@@ -1,6 +1,5 @@
/**
* @summary Styles for reusable Header component
- * @author Dallas Richmond
*/
import styled from '@emotion/styled';
import screenSizes from '../../../constants/screenSizes';
@@ -41,6 +40,7 @@ export const Banner = styled.div`
align-items: center;
margin: 0;
`;
+
export const BannerRight = styled.div`
min-width: 35pt;
display: flex;
diff --git a/frontend/src/components/common/InputField/InputField.tsx b/frontend/src/components/common/InputField/InputField.tsx
new file mode 100644
index 0000000..63c7c95
--- /dev/null
+++ b/frontend/src/components/common/InputField/InputField.tsx
@@ -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) => void;
+ flex?: string;
+}
+
+function InputField({ label, type, name, value, onChange, flex }: InputFieldProps) {
+ return (
+
+ {label}
+
+
+ );
+}
+
+export default InputField;
diff --git a/frontend/src/components/common/InputField/inputField.styles.ts b/frontend/src/components/common/InputField/inputField.styles.ts
new file mode 100644
index 0000000..fe86d0c
--- /dev/null
+++ b/frontend/src/components/common/InputField/inputField.styles.ts
@@ -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;
+ }
+`;
diff --git a/frontend/src/components/common/RadioButton/RadioButton.tsx b/frontend/src/components/common/RadioButton/RadioButton.tsx
new file mode 100644
index 0000000..44867e8
--- /dev/null
+++ b/frontend/src/components/common/RadioButton/RadioButton.tsx
@@ -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) => void;
+}
+
+function RadioButton({ label, name, value, checked, onChange }: RadioButtonProps) {
+ return (
+
+
+ {label}
+
+ );
+}
+
+export default RadioButton;
diff --git a/frontend/src/components/common/RadioButton/radioButton.styles.ts b/frontend/src/components/common/RadioButton/radioButton.styles.ts
new file mode 100644
index 0000000..71d89a7
--- /dev/null
+++ b/frontend/src/components/common/RadioButton/radioButton.styles.ts
@@ -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;
+`;
diff --git a/frontend/src/components/common/index.ts b/frontend/src/components/common/index.ts
index bec1b29..59ab5cc 100644
--- a/frontend/src/components/common/index.ts
+++ b/frontend/src/components/common/index.ts
@@ -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 };
diff --git a/frontend/src/routes/ViewRouter.tsx b/frontend/src/routes/ViewRouter.tsx
index b50c146..fca5fa9 100644
--- a/frontend/src/routes/ViewRouter.tsx
+++ b/frontend/src/routes/ViewRouter.tsx
@@ -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 (
@@ -12,6 +13,10 @@ export default function ViewRouter() {
path="/"
Component={LandingPage}
/>
+
);
}
diff --git a/frontend/src/views/FarmInformation/FarmInformation.tsx b/frontend/src/views/FarmInformation/FarmInformation.tsx
new file mode 100644
index 0000000..d6cae7e
--- /dev/null
+++ b/frontend/src/views/FarmInformation/FarmInformation.tsx
@@ -0,0 +1,112 @@
+/**
+ * @summary The Farm Information page for the application
+ */
+import React, { useState } from 'react';
+import {
+ ViewContainer,
+ Card,
+ CardHeader,
+ Banner,
+ Heading,
+ InputFieldsContainer,
+ SelectorContainer,
+ RegionContainer,
+} from './farmInformation.styles';
+import { InputField, RadioButton, Checkbox, Dropdown } from '../../components/common';
+
+export default function FarmInformation() {
+ const [formData, setFormData] = useState({
+ Year: '',
+ FarmName: '',
+ FarmRegion: '',
+ Crops: 'false',
+ HasVegetables: false,
+ HasBerries: false,
+ });
+
+ const handleChange = (e: React.ChangeEvent) => {
+ const { name, value, type, checked } = e.target as HTMLInputElement;
+ setFormData({ ...formData, [name]: type === 'checkbox' ? checked : value });
+ };
+
+ const regionOptions = [
+ { value: '0', label: 'Select a region' },
+ { value: '1', label: 'Bulkley-Nechako' },
+ { value: '2', label: 'Cariboo' },
+ { value: '3', label: 'Columbia Shuswap' },
+ ];
+
+ return (
+
+
+
+
+ Farm Information
+
+
+
+
+
+
+
+
+
+
+ I have crops
+
+
+
+ {formData.Crops === 'true' && (
+
+ Select your crops:
+
+
+
+ )}
+
+
+ );
+}
diff --git a/frontend/src/views/FarmInformation/farmInformation.styles.ts b/frontend/src/views/FarmInformation/farmInformation.styles.ts
new file mode 100644
index 0000000..bbeb3cd
--- /dev/null
+++ b/frontend/src/views/FarmInformation/farmInformation.styles.ts
@@ -0,0 +1,94 @@
+/**
+ * @summary Styling for FarmInformation view
+ */
+import styled from '@emotion/styled';
+import screenSizes from '../../constants/screenSizes';
+
+export const ViewContainer = styled.div`
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: flex;
+ height: 100svh;
+ justify-content: center;
+ width: 100%;
+ align-items: center;
+`;
+
+export const Card = styled.div`
+ background-color: rgba(255, 255, 255, 0.8);
+ height: 500px;
+ width: 600px;
+ padding-top: 0;
+ justify-content: flex-start;
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ object-fit: scale-down;
+ border-radius: 8px;
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
+ padding: 20px;
+ text-align: center;
+ position: relative;
+`;
+
+export const CardHeader = styled.div`
+ background-color: rgba(200, 200, 200, 0.3);
+ padding: 0;
+ color: #fff;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ height: 65px;
+ width: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border-top-left-radius: 8px;
+ border-top-right-radius: 8px;
+ @media (min-width: ${screenSizes.tablet}) {
+ justify-content: flex-start;
+ padding-left: 2em;
+ }
+ z-index: 2000;
+`;
+
+export const Banner = styled.div`
+ display: flex;
+ align-items: center;
+ margin: 0;
+`;
+
+export const Heading = styled.h2`
+ color: #494949;
+ font-size: 16pt;
+ font-weight: 500;
+ min-width: 150px;
+ display: contents;
+ text-decoration: none;
+`;
+
+export const InputFieldsContainer = styled.div`
+ display: flex;
+ width: 100%;
+ gap: 16px;
+ margin-top: 100px;
+`;
+
+export const RegionContainer = styled.div`
+ display: flex;
+ gap: 16px;
+ margin-top: 16px;
+ width: 100%;
+ justify-content: flex-start;
+ align-items: center;
+`;
+
+export const SelectorContainer = styled.div`
+ display: flex;
+ gap: 16px;
+ margin-top: 16px;
+ width: 100%;
+ justify-content: flex-start;
+ align-items: center;
+`;
diff --git a/frontend/src/views/LandingPage/LandingPage.tsx b/frontend/src/views/LandingPage/LandingPage.tsx
index fb76b76..8a58051 100644
--- a/frontend/src/views/LandingPage/LandingPage.tsx
+++ b/frontend/src/views/LandingPage/LandingPage.tsx
@@ -1,6 +1,7 @@
/**
* @summary The landing page for the application
*/
+import { useNavigate } from 'react-router-dom';
import {
ButtonWrapper,
ViewContainer,
@@ -11,6 +12,8 @@ import {
import { Button } from '../../components/common';
export default function LandingPage() {
+ const navigate = useNavigate();
+
const handleUpload = () => {
const upload = document.getElementById('fileUp');
if (upload) upload.click();
@@ -33,16 +36,14 @@ export default function LandingPage() {
// The alert is temporary, will be removed once the data is being used
// eslint-disable-next-line no-alert
alert(data.toString());
+ navigate('/farm-information');
}
};
};
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');
+ navigate('/farm-information');
};
return (