Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ import "App.css";
import React from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router";
import { TitleWrapper } from "components";
import { Home, JobBoard, Overview, Networking, CoverLetter } from "pages";
import {
Home,
JobBoard,
Overview,
Networking,
CoverLetter,
JobDescriptions,
} from "pages";
import DashBoardLayout from "layouts/DashboardLayout";

const routes = [
Expand All @@ -26,6 +33,11 @@ const routes = [
element: <Networking />,
title: "Networking | Job Tracker",
},
{
path: "/job-descriptions",
element: <JobDescriptions />,
title: "Job Descriptions | Job Tracker",
},
];

function App() {
Expand Down
20 changes: 4 additions & 16 deletions client/src/components/CoverLetterForm/Module/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { Add, Close, HighlightOff } from "@mui/icons-material";
import { useState, useEffect } from "react";
import { TextField, CircularProgress } from "@mui/material";
import { useSnackbar } from "hooks";
import { useHandleCopy } from "hooks";
import BootstrapDialog from "./BootstrapDialog";
import axios from "axios";
import { ErrorMessage } from "components";
Expand All @@ -21,7 +21,7 @@ const Module = ({
setCurrentData,
currentData,
}) => {
const { showSnackbar } = useSnackbar();
const handleCopy = useHandleCopy();
const [open, setOpen] = useState(false);

const serverURL = process.env.REACT_APP_SERVER_URL;
Expand All @@ -35,7 +35,7 @@ const Module = ({
setCompanyNotFound(data);
setJobNameNotFound(data);
};

//TODO: This needs to be consolidated somehow since we using it twice
const getScrapedData = (url) => {
setLoading(true);

Expand Down Expand Up @@ -97,18 +97,6 @@ const Module = ({
setOpen(false);
};

const handleCopy = () => {
navigator.clipboard
.writeText(coverLetter)
.then(() => {
showSnackbar({ message: "Copied to clipboard!", type: "success" });
})
.catch((error) => {
showSnackbar("Failed to copy. Please try again.", "error");
console.error(error);
});
};

const clearInput = (value) => {
setCurrentData((prev) => ({
...prev,
Expand Down Expand Up @@ -297,7 +285,7 @@ const Module = ({
))}
</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleCopy}>
<Button autoFocus onClick={() => handleCopy(coverLetter)}>
Copy
</Button>
<Button autoFocus onClick={clearForm}>
Expand Down
1 change: 1 addition & 0 deletions client/src/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as useSnackbar } from "./useSnackbar/index";
export { default as useAuth } from "./useAuth/index";
export { default as useHandleCopy } from "./useHandleCopy/index";
24 changes: 24 additions & 0 deletions client/src/hooks/useHandleCopy/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useSnackbar } from "hooks";

const useHandleCopy = () => {
const { showSnackbar } = useSnackbar();

const handleCopy = (dataToCopy) => {
navigator.clipboard
.writeText(dataToCopy)
.then(() => {
showSnackbar({ message: "Copied to clipboard!", type: "success" });
})
.catch((error) => {
showSnackbar({
message: "Failed to copy. Please try again.",
type: "error",
});
console.error(error);
});
};

return handleCopy;
};

export default useHandleCopy;
6 changes: 6 additions & 0 deletions client/src/layouts/DashboardLayout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
BarChart,
ConnectWithoutContact,
Description,
Article,
} from "@mui/icons-material";
import SidebarFooterAccount from "./AccountSidebar/SidebarFooterAccount";
import { useAuth } from "hooks";
Expand Down Expand Up @@ -41,6 +42,11 @@ const NAVIGATION = [
title: "Networking",
icon: <ConnectWithoutContact />,
},
{
segment: "job-descriptions",
title: "Job Descriptions",
icon: <Article />,
},
];

const Layout = () => {
Expand Down
124 changes: 124 additions & 0 deletions client/src/pages/JobDescriptions/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import "./styles.css";
import Button from "@mui/material/Button";
import { ContentCopy } from "@mui/icons-material";
import { useHandleCopy } from "hooks";

const JobDescriptions = () => {
const handleCopy = useHandleCopy();
const socials = [
{
name: "LinkedIn",
url: "https://www.linkedin.com/in/som-ramnani-b1990b14b",
},
{
name: "Personal Website",
url: "http://somramnani.com",
},
{
name: "GitHub",
url: "https://github.com/somramnani",
},
];

const jobDescriptions = [
{
companyName: "Formation",
role: "Software Engineer Fellow",
date: "May 2022",
description: `
* Selected for a highly competitive Fellowship for personalized coaching from top-tier software engineers\n
* Studied front-end engineering fundamentals in small groups led by senior engineers from top companies, comparing and contrasting concepts in modern web-based applications\n
* Completed intensive training to master computer science fundamentals through coding exercises with React/HTML/CSS through independent study, pair programming, and small mentor-led groups`,
},

{
companyName: "Trendsetter Media & Marketing",
role: "Junior Software Engineer",
date: "May - November 2021",
description: `
* Selected for a highly competitive Fellowship for personalized coaching from top-tier software engineers

* Studied front-end engineering fundamentals in small groups led by senior engineers from top companies, comparing and contrasting concepts in modern web-based applications

* Completed intensive training to master computer science fundamentals through coding exercises with React/HTML/CSS through independent study, pair programming, and small mentor-led groups
`,
},
];

return (
<div className="job-container">
<h2 className="job-title">Job Descriptions</h2>

<div id="job-descriptions">
<h2>Socials</h2>
{socials.map((social, index) => {
return (
<div key={index}>
<strong>{social.name}</strong> : {social.url}
<Button onClick={() => handleCopy(social.url)} variant="text">
<ContentCopy />
</Button>
</div>
);
})}
</div>

<div>
<h2>Job Descriptions</h2>
{jobDescriptions.map((job, index) => (
<div
key={index}
style={{ marginBottom: "20px" }}
className="job-item"
>
{/* Loop through the job properties dynamically */}
{Object.entries(job).map(([key, value]) => {
if (key === "description") return null;
return (
<div
key={key}
style={{
display: "block", // Make sure each key-value pair appears on a new line
marginBottom: "10px", // Add space between each pair
}}
>
<strong style={{ marginRight: "5px" }}>
{key.replace(/([A-Z])/g, " $1").toUpperCase()}:
</strong>
<span>{value}</span>
<Button
onClick={() => handleCopy(value)}
variant="text"
style={{ marginLeft: "5px" }}
>
<ContentCopy />
</Button>
</div>
);
})}
<div className="job-detail">
<strong>Description:</strong>
<pre
style={{
whiteSpace: "pre-wrap", // Allows wrapping and preserves line breaks
margin: "0", // Remove extra margin or indentation
padding: "0", // Ensure no extra padding is added
}}
>
{job.description}
</pre>
<Button
onClick={() => handleCopy(job.description)}
variant="outlined"
>
<ContentCopy />
</Button>
</div>
</div>
))}
</div>
</div>
);
};

export default JobDescriptions;
12 changes: 12 additions & 0 deletions client/src/pages/JobDescriptions/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.job-container {
padding-left: 0.5em;
}

.job-title {
font-size: 1.75rem;
color: #333;
padding-bottom: 0.5rem;
padding-left: 0.5em;
border-bottom: 1px solid #ccc;
margin-bottom: 1rem;
}
1 change: 1 addition & 0 deletions client/src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { default as JobBoard } from "./JobBoard/index";
export { default as Overview } from "./Overview/index";
export { default as Networking } from "./Networking/index";
export { default as CoverLetter } from "./CoverLetter/index";
export { default as JobDescriptions } from "./JobDescriptions/index";