diff --git a/package-lock.json b/package-lock.json index ab878bc4..26f5e8f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@eslint/js": "^9.17.0", "@svgr/webpack": "^6.2.1", + "@types/react-dom": "^19.1.3", "daisyui": "^5.0.28", "eslint-config-react-app": "^7.0.1", "eslint-define-config": "^2.1.0", @@ -4218,6 +4219,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "19.1.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.3.tgz", + "integrity": "sha512-rJXC08OG0h3W6wDMFxQrZF00Kq6qQvw0djHRdzl3U5DnIERz0MRce3WVc7IS6JYBwtaP/DwYtRRjVlvivNveKg==", + "devOptional": true, + "peerDependencies": { + "@types/react": "^19.0.0" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", diff --git a/package.json b/package.json index f5f99f49..5b0894a7 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@eslint/js": "^9.17.0", "@svgr/webpack": "^6.2.1", + "@types/react-dom": "^19.1.3", "daisyui": "^5.0.28", "eslint-config-react-app": "^7.0.1", "eslint-define-config": "^2.1.0", diff --git a/src/declarations.d.ts b/src/declarations.d.ts new file mode 100644 index 00000000..45ce3dae --- /dev/null +++ b/src/declarations.d.ts @@ -0,0 +1,43 @@ +// Declarations file for fixing certain type errors + +declare module "*.webp" { + const value: string; + export default value; +} + +declare type PagesState = { + pages: string[]; + activePage: string; +} + +// FOr about section idk what this is tbh +declare interface AboutItem { + title: string; + description: string; +} + +// This the result returned from 'packageOpportunityCard' in opportunity_routes.py in backend +declare interface OpportunityCardData { + "id": string, + "title": string, + "professor": string, + "season": stringr, + "location": string, + "year": string, +} + +// This the result returned from 'packageIndividualOpportunity' in opportunity_routes.py in backend +declare interface OpportunityData { + "id": string; + "name": string; + "description": string; + "recommended_experience": string; + "author": string; + "authorProfile": string; + "department": string; + "pay": string; + "credits"?: string; + "semester": string + "application_due": string; + "recommended_class_years": string; +} diff --git a/src/opportunities/components/AboutSection.js b/src/opportunities/components/AboutSection.tsx similarity index 81% rename from src/opportunities/components/AboutSection.js rename to src/opportunities/components/AboutSection.tsx index cdd3914f..6257f63b 100644 --- a/src/opportunities/components/AboutSection.js +++ b/src/opportunities/components/AboutSection.tsx @@ -1,7 +1,11 @@ import React from "react"; import AboutSectionElement from "./AboutSectionElement"; -const AboutSection = ({ aboutSection }) => { +interface AboutSectionProps { + aboutSection: AboutItem[]; +} + +const AboutSection = ({ aboutSection }: AboutSectionProps) => { let i = 0; return ( diff --git a/src/opportunities/components/AboutSectionElement.js b/src/opportunities/components/AboutSectionElement.tsx similarity index 70% rename from src/opportunities/components/AboutSectionElement.js rename to src/opportunities/components/AboutSectionElement.tsx index c8374365..31900ab4 100644 --- a/src/opportunities/components/AboutSectionElement.js +++ b/src/opportunities/components/AboutSectionElement.tsx @@ -1,6 +1,6 @@ import React from "react"; -const AboutSectionElement = ({ title, description }) => { +const AboutSectionElement = ({ title, description }: { title: string, description: string }) => { return (
{title}
diff --git a/src/opportunities/components/HorizontalIconButton.tsx b/src/opportunities/components/HorizontalIconButton.tsx index 001655fe..9de9c6c1 100644 --- a/src/opportunities/components/HorizontalIconButton.tsx +++ b/src/opportunities/components/HorizontalIconButton.tsx @@ -1,7 +1,13 @@ import React from "react"; -import PropTypes from "prop-types"; -const HorizontalIconButton = ({ children, onClick, icon, special }) => { +interface HorizontalIconButtonProps { + children?: React.ReactNode; + onClick: (arg?: React.ReactNode) => void; + icon: React.ReactNode; + special: boolean; +} + +const HorizontalIconButton = ({ children, onClick, icon, special }: HorizontalIconButtonProps) => { return (
{ ); }; -HorizontalIconButton.propTypes = { - children: PropTypes.node, - onClick: PropTypes.func.isRequired, - icon: PropTypes.node, - special: PropTypes.bool, -} - export default HorizontalIconButton; diff --git a/src/opportunities/components/JobDescription.js b/src/opportunities/components/JobDescription.tsx similarity index 74% rename from src/opportunities/components/JobDescription.js rename to src/opportunities/components/JobDescription.tsx index e905bd0f..7b582fe9 100644 --- a/src/opportunities/components/JobDescription.js +++ b/src/opportunities/components/JobDescription.tsx @@ -1,6 +1,6 @@ import React from "react"; -const JobDescription = ({ title, description }) => { +const JobDescription = ({ title, description }: { title?: string, description: string }) => { return (
{title || "Role Description"}
diff --git a/src/opportunities/components/JobDetails.js b/src/opportunities/components/JobDetails.tsx similarity index 80% rename from src/opportunities/components/JobDetails.js rename to src/opportunities/components/JobDetails.tsx index 47d9e9db..c8f9028f 100644 --- a/src/opportunities/components/JobDetails.js +++ b/src/opportunities/components/JobDetails.tsx @@ -3,6 +3,16 @@ import AboutSection from "./AboutSection"; import JobHeader from "./JobHeader"; import JobDescription from "./JobDescription"; +interface JobDetailsProps { + name: string; + author: string; + department: string; + description: string; + authorProfile: string; + aboutSection: AboutItem[]; + recommended_experience: string; +} + const JobDetails = ({ name, author, @@ -11,7 +21,7 @@ const JobDetails = ({ authorProfile, aboutSection, recommended_experience, -}) => { +}: JobDetailsProps) => { return (
{ +interface JobHeaderProps { + title: string; + img: string; + author: string; + department: string; +} + +const JobHeader = ({ title, img, author, department }: JobHeaderProps) => { return (

{title}

diff --git a/src/opportunities/components/JobInteractionButton.js b/src/opportunities/components/JobInteractionButton.tsx similarity index 71% rename from src/opportunities/components/JobInteractionButton.js rename to src/opportunities/components/JobInteractionButton.tsx index 58f5704f..5e66d9e7 100644 --- a/src/opportunities/components/JobInteractionButton.js +++ b/src/opportunities/components/JobInteractionButton.tsx @@ -1,6 +1,13 @@ import React from "react"; -const JobInteractionButton = ({ className, special, onClick, children }) => { +interface JobInteractionButtonProps { + className: string; + special: string; + onClick: () => void + children: React.ReactNode +} + +const JobInteractionButton = ({ className, special, onClick, children }: JobInteractionButtonProps) => { return (
diff --git a/src/shared/components/Profile/EditInformation.js b/src/shared/components/Profile/EditInformation.tsx similarity index 75% rename from src/shared/components/Profile/EditInformation.js rename to src/shared/components/Profile/EditInformation.tsx index 1df9d17c..34e8ca96 100644 --- a/src/shared/components/Profile/EditInformation.js +++ b/src/shared/components/Profile/EditInformation.tsx @@ -1,11 +1,31 @@ import React from "react"; -import { useState } from "react"; import { useForm } from "react-hook-form"; -import { useEffect } from "react"; import Input from "../../../staff/components/Input"; -const EditInformation = ({className, id, name, department, researchCenter, description, email, role, image }) => { - const submitHandler = (data) => { +interface EditInformationProps { + className?: string; + id: string; + name: string; + department: string; + researchCenter: string; + description: string; + email: string; + role: string; + image: string; +} + +interface FormType { + id: string, + name: string, + email: string, + role: string, + description: string; + department: string; + researchCenter: string; +} + +const EditInformation = ({className, id, name, department, researchCenter, description, email, role, image }: EditInformationProps) => { + const submitHandler = (data: FormType) => { console.log(data); }; @@ -25,7 +45,7 @@ const EditInformation = ({className, id, name, department, researchCenter, descr }, }); - var forms = ( + const forms = (
{ submitHandler(data); diff --git a/src/shared/components/Profile/OpportunityActionCard.js b/src/shared/components/Profile/OpportunityActionCard.tsx similarity index 84% rename from src/shared/components/Profile/OpportunityActionCard.js rename to src/shared/components/Profile/OpportunityActionCard.tsx index 9bbcbb3a..a98d6941 100644 --- a/src/shared/components/Profile/OpportunityActionCard.js +++ b/src/shared/components/Profile/OpportunityActionCard.tsx @@ -1,6 +1,16 @@ import React from "react"; import { Link } from "react-router-dom"; +interface OpportunityActionCardProps { + editPath: string; + title: string; + body: React.ReactNode; + id: string; + activeStatus: string; + changeActiveStatus: (id: string, activeStatus: string) => void; + deleteOpp: (id: string) => void; +} + const OpportunityActionCard = ({ editPath, title, @@ -9,7 +19,7 @@ const OpportunityActionCard = ({ activeStatus, changeActiveStatus, deleteOpp, -}) => { +}: OpportunityActionCardProps) => { if (title.length > 100) { title = title.slice(0, 150) + " ..."; } diff --git a/src/shared/components/SEO.tsx b/src/shared/components/SEO.tsx index f1b45f6e..83efbd9c 100644 --- a/src/shared/components/SEO.tsx +++ b/src/shared/components/SEO.tsx @@ -1,9 +1,12 @@ import React from 'react'; import { Helmet } from 'react-helmet-async'; -import PropTypes from 'prop-types'; +interface SEOProps { + title: string; + description: string; +} -export default function SEO({ title, description }) { +export default function SEO({ title, description }: SEOProps) { return ( { /* Standard metadata tags */} @@ -24,9 +27,4 @@ export default function SEO({ title, description }) { ) -} - -SEO.propTypes = { - title: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/shared/components/UIElements/Avatar.tsx b/src/shared/components/UIElements/Avatar.tsx index a9939a90..606c23ac 100644 --- a/src/shared/components/UIElements/Avatar.tsx +++ b/src/shared/components/UIElements/Avatar.tsx @@ -1,6 +1,6 @@ import React from "react"; -const Avatar: React.FC<{ img: string, name: string, className?: string }> = ({ img, name, className = "" }) => { +const Avatar: React.FC<{ img: string, name: string, role: string, className?: string }> = ({ img, name, role, className = "" }) => { return (
{name} diff --git a/src/shared/components/UIElements/Backdrop.js b/src/shared/components/UIElements/Backdrop.tsx similarity index 62% rename from src/shared/components/UIElements/Backdrop.js rename to src/shared/components/UIElements/Backdrop.tsx index e462cef9..de4ba4af 100644 --- a/src/shared/components/UIElements/Backdrop.js +++ b/src/shared/components/UIElements/Backdrop.tsx @@ -1,10 +1,10 @@ import React from "react"; import ReactDOM from "react-dom"; -const Backdrop = ({ onClick }) => { +const Backdrop = ({ onClick }: { onClick: () => void }) => { return ReactDOM.createPortal(
, - document.getElementById("backdrop-hook") + document.getElementById("backdrop-hook")! ); }; diff --git a/src/shared/components/UIElements/Breadcrumb.tsx b/src/shared/components/UIElements/Breadcrumb.tsx index 6981b854..493c804b 100644 --- a/src/shared/components/UIElements/Breadcrumb.tsx +++ b/src/shared/components/UIElements/Breadcrumb.tsx @@ -1,12 +1,20 @@ import React from "react"; import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; -const Breadcrumb = ({ tree }) => { +interface BreadcrumbProps { + tree: {link: string, title: string}[]; +} + +interface Shape { + link: string; + title: string; +} + +const Breadcrumb = ({ tree }: BreadcrumbProps) => { return (
    - {tree.map((item) => { + {tree.map((item: Shape) => { return (
  • {item.title} @@ -17,13 +25,5 @@ const Breadcrumb = ({ tree }) => {
); }; -Breadcrumb.propTypes = { - tree: PropTypes.arrayOf( - PropTypes.shape({ - link: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - }) - ).isRequired, -}; export default Breadcrumb; diff --git a/src/shared/components/UIElements/GroupedComponents.js b/src/shared/components/UIElements/GroupedComponents.js deleted file mode 100644 index ba8af41f..00000000 --- a/src/shared/components/UIElements/GroupedComponents.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from "react"; - -const GroupedComponents = ({ children, gap }) => { - return
{children}
; -}; - -export default GroupedComponents; diff --git a/src/shared/components/UIElements/GroupedComponents.tsx b/src/shared/components/UIElements/GroupedComponents.tsx new file mode 100644 index 00000000..4e13d76e --- /dev/null +++ b/src/shared/components/UIElements/GroupedComponents.tsx @@ -0,0 +1,12 @@ +import React from "react"; + +interface GroupedComponentsProps { + children?: React.ReactNode[]; + gap: number; +} + +const GroupedComponents = ({ children, gap }: GroupedComponentsProps) => { + return
{children}
; +}; + +export default GroupedComponents; diff --git a/src/shared/components/UIElements/LargeTextCard.tsx b/src/shared/components/UIElements/LargeTextCard.tsx index 693d41f3..ca9e9d0d 100644 --- a/src/shared/components/UIElements/LargeTextCard.tsx +++ b/src/shared/components/UIElements/LargeTextCard.tsx @@ -1,8 +1,15 @@ import React from "react"; import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; -const LargeTextCard = ({ to, title, due, pay, credits }) => { +interface LargeTextCardProps { + to: string; + title: string; + due: string; + pay?: string; + credits?: string; +} + +const LargeTextCard = ({ to, title, due, pay, credits }: LargeTextCardProps) => { return (
@@ -22,12 +29,4 @@ const LargeTextCard = ({ to, title, due, pay, credits }) => { ); }; -LargeTextCard.propTypes = { - to: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - due: PropTypes.string.isRequired, - pay: PropTypes.string, - credits: PropTypes.string, -}; - export default LargeTextCard; diff --git a/src/shared/hooks/page-navigation-hook.ts b/src/shared/hooks/page-navigation-hook.ts index d910c4b7..cfc58b7b 100644 --- a/src/shared/hooks/page-navigation-hook.ts +++ b/src/shared/hooks/page-navigation-hook.ts @@ -1,10 +1,5 @@ import { useState } from "react"; -interface PagesState { - pages: string[]; - activePage: string; -} - type SwitchPage = (view: string) => void; const usePageNavigation = (views: string[], activeView: string): [PagesState, SwitchPage] => { diff --git a/src/shared/pages/EditProfile.js b/src/shared/pages/EditProfile.tsx similarity index 68% rename from src/shared/pages/EditProfile.js rename to src/shared/pages/EditProfile.tsx index f4a6b102..b45f1d1b 100644 --- a/src/shared/pages/EditProfile.js +++ b/src/shared/pages/EditProfile.tsx @@ -1,6 +1,17 @@ import React from "react"; -import ProfileAvatar from "../components/UIElements/ProfileAvatar.tsx"; -import EditInformation from "../components/Profile/EditInformation"; +import ProfileAvatar from "../components/Profile/ProfileAvatar.tsx"; +import EditInformation from "../components/Profile/EditInformation.tsx"; + +interface EditProfileProps { + id: string; + name: string; + department: string; + researchCenter: string; + description: string; + email: string; + role: string; + image: string; +} const EditProfile = ({ id, @@ -11,7 +22,7 @@ const EditProfile = ({ email, role, image, -}) => { +}: EditProfileProps) => { return (
diff --git a/src/staff/components/DepartmentStaff.tsx b/src/staff/components/DepartmentStaff.tsx index 7c258d30..dc939619 100644 --- a/src/staff/components/DepartmentStaff.tsx +++ b/src/staff/components/DepartmentStaff.tsx @@ -1,9 +1,12 @@ import React from "react"; -import PropTypes from "prop-types"; import AvatarCard from "../../shared/components/UIElements/AvatarCard.tsx"; import { Link } from "react-router-dom"; -const DepartmentStaff = ({ staff }) => { +interface DepartmentStaffProps { + staff: {id: string, name: string, image: string}[]; +} + +const DepartmentStaff = ({ staff }: DepartmentStaffProps) => { return (
{staff.map((staff_member) => { @@ -21,14 +24,4 @@ const DepartmentStaff = ({ staff }) => { ); }; -DepartmentStaff.propTypes = { - staff: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - image: PropTypes.string.isRequired, - }) - ).isRequired, -}; - export default DepartmentStaff; diff --git a/src/staff/components/Input.js b/src/staff/components/Input.tsx similarity index 59% rename from src/staff/components/Input.js rename to src/staff/components/Input.tsx index 1fd702a6..6e33215e 100644 --- a/src/staff/components/Input.js +++ b/src/staff/components/Input.tsx @@ -1,6 +1,51 @@ import React from "react"; +import { FieldErrors, UseFormRegisterReturn, FieldValues} from "react-hook-form"; -const Input = ({ +interface InputProps { + type?: string; + errorMessage: string; + errors: FieldErrors; + name: keyof TFieldValues & string; + formHook: UseFormRegisterReturn; + label: string; + options?: string[]; + placeHolder?: string; +} + +/* +const errors: FieldErrors<{ + id: string; + title: string; + application_due: string; + type: string; + hourlyPay: number; + credits: never[]; + description: string; + recommended_experience: string; + location: string; + years: string[]; +}> + +const errors: FieldErrors<{ + years: never[]; + credits: never[]; + hourlyPay: number; + majors: never[]; +}> + +const errors: FieldErrors<{ + id: string; + name: string; + email: string; + role: string; + description: string; + department: string; + researchCenter: string; +}> + +*/ + +const Input = ({ type, errorMessage, errors, @@ -9,7 +54,7 @@ const Input = ({ label, options, placeHolder, -}) => { +}: InputProps) => { // if (!formHook) { // return

FormHook Not Given

; // } @@ -28,8 +73,8 @@ const Input = ({ ); diff --git a/src/staff/components/LargeImageCard.js b/src/staff/components/LargeImageCard.tsx similarity index 66% rename from src/staff/components/LargeImageCard.js rename to src/staff/components/LargeImageCard.tsx index 77a5fbdd..7d790818 100644 --- a/src/staff/components/LargeImageCard.js +++ b/src/staff/components/LargeImageCard.tsx @@ -1,8 +1,13 @@ import React from "react"; import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; -const LargeImageCard = ({ to, image, title }) => { +interface LargeImageCardProps { + to: string; + image: string; + title: string; +} + +const LargeImageCard = ({ to, image, title }: LargeImageCardProps) => { return (
@@ -17,10 +22,4 @@ const LargeImageCard = ({ to, image, title }) => { ); }; -LargeImageCard.propTypes = { - to: PropTypes.string.isRequired, - image: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, -}; - export default LargeImageCard; diff --git a/src/style/general.css b/src/style/general.css index 1ca835be..38aa235b 100644 --- a/src/style/general.css +++ b/src/style/general.css @@ -80,9 +80,6 @@ .jobs-categories { @apply text-base flex gap-4 justify-items-center font-semibold; } -.postsfield-header { - @apply border-t border-b grid grid-cols-9; -} .searchbar { @apply flex p-2 px-3 border rounded-3xl align-items-center; }