├── client ├── public │ ├── _redirects │ ├── CTA.png │ ├── hero.png │ ├── avatar.png │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── logos │ │ ├── 3M.png │ │ ├── AIG.png │ │ ├── AMD.png │ │ ├── Box.png │ │ ├── Dow.png │ │ ├── HCA.png │ │ ├── HP.png │ │ ├── IBM.png │ │ ├── TD.png │ │ ├── TJX.png │ │ ├── X.png │ │ ├── Adobe.png │ │ ├── Apple.png │ │ ├── Arrow.png │ │ ├── Asana.png │ │ ├── Bolt.png │ │ ├── Brex.png │ │ ├── Canva.png │ │ ├── Cigna.png │ │ ├── Cisco.png │ │ ├── Delta.png │ │ ├── Ebay.png │ │ ├── Etsy.png │ │ ├── FedEx.png │ │ ├── Figma.png │ │ ├── Glean.png │ │ ├── Hulu.png │ │ ├── Intel.png │ │ ├── Kayak.png │ │ ├── Lyft.png │ │ ├── Mako.png │ │ ├── Merck.png │ │ ├── Meta.png │ │ ├── NASA.png │ │ ├── Nike.png │ │ ├── Nucor.png │ │ ├── Nuro.png │ │ ├── Okta.png │ │ ├── Pepsi.png │ │ ├── Plaid.png │ │ ├── Quora.png │ │ ├── Ramp.png │ │ ├── Slack.png │ │ ├── Snap.png │ │ ├── Sysco.png │ │ ├── TIAA.png │ │ ├── Tesla.png │ │ ├── Uber.png │ │ ├── Visa.png │ │ ├── Waymo.png │ │ ├── Wish.png │ │ ├── Yelp.png │ │ ├── Yext.png │ │ ├── Zoom.png │ │ ├── AbbVie.png │ │ ├── Addepar.png │ │ ├── Affirm.png │ │ ├── Airbnb.png │ │ ├── Airtable.png │ │ ├── Allstate.png │ │ ├── Amazon.png │ │ ├── Anduril.png │ │ ├── Autodesk.png │ │ ├── Barclays.png │ │ ├── Best_Buy.png │ │ ├── Boeing.png │ │ ├── CarMax.png │ │ ├── Citadel.png │ │ ├── Cohere.png │ │ ├── Coinbase.png │ │ ├── Cruise.png │ │ ├── Datadog.png │ │ ├── Deepmind.png │ │ ├── Discord.png │ │ ├── Disney.png │ │ ├── Docusign.png │ │ ├── DoorDash.png │ │ ├── Dropbox.png │ │ ├── Duolingo.png │ │ ├── Elastic.png │ │ ├── Expedia.png │ │ ├── Fidelity.png │ │ ├── Flexport.png │ │ ├── Fox_News.png │ │ ├── GitHub.png │ │ ├── Google.png │ │ ├── GrubHub.png │ │ ├── HubSpot.png │ │ ├── Humana.png │ │ ├── Indeed.png │ │ ├── Intuit.png │ │ ├── Kelloggs.png │ │ ├── Lennar.png │ │ ├── Linkedin.png │ │ ├── Macy's.png │ │ ├── MetLife.png │ │ ├── Micron.png │ │ ├── MongoDB.png │ │ ├── Netflix.png │ │ ├── Nextdoor.png │ │ ├── Notion.png │ │ ├── Nutanix.png │ │ ├── Nvidia.png │ │ ├── OpenAI.png │ │ ├── Optiver.png │ │ ├── Oracle.png │ │ ├── Palantir.png │ │ ├── PayPal.png │ │ ├── Peloton.png │ │ ├── Pintrest.png │ │ ├── Publix.png │ │ ├── Qualcomm.png │ │ ├── Raytheon.png │ │ ├── Red_Hat.png │ │ ├── Reddit.png │ │ ├── Redfin.png │ │ ├── Retool.png │ │ ├── Rippling.png │ │ ├── Roblox.png │ │ ├── Samsara.png │ │ ├── Samsung.png │ │ ├── Scale_AI.png │ │ ├── Shopify.png │ │ ├── SpaceX.png │ │ ├── Spectrum.png │ │ ├── Splunk.png │ │ ├── Spotify.png │ │ ├── Square.png │ │ ├── StoneX.png │ │ ├── Tableau.png │ │ ├── Tanium.png │ │ ├── TikTok.png │ │ ├── Twilio.png │ │ ├── Twitch.png │ │ ├── US_Foods.png │ │ ├── VMware.png │ │ ├── Verily.png │ │ ├── Walmart.png │ │ ├── Wayfair.png │ │ ├── Workday.png │ │ ├── Zillow.png │ │ ├── Albertsons.png │ │ ├── Anthropic.png │ │ ├── Atlassian.png │ │ ├── Blackrock.png │ │ ├── Bloomberg.png │ │ ├── ByteDance.png │ │ ├── Cloudflare.png │ │ ├── Coca_Cola.png │ │ ├── D.E._Shaw.png │ │ ├── Databricks.png │ │ ├── Five_Rings.png │ │ ├── Honeywell.png │ │ ├── Instacart.png │ │ ├── John_Deere.png │ │ ├── MasterCard.png │ │ ├── McDonalds.png │ │ ├── Microsoft.png │ │ ├── Nationwide.png │ │ ├── Neuralink.png │ │ ├── Occidental.png │ │ ├── PBF_Energy.png │ │ ├── Postmates.png │ │ ├── Prudential.png │ │ ├── Qualtrics.png │ │ ├── Riot_Games.png │ │ ├── Robinhood.png │ │ ├── Salesforce.png │ │ ├── ServiceNow.png │ │ ├── Snowflake.png │ │ ├── Starbucks.png │ │ ├── State_Farm.png │ │ ├── TD_Synnex.png │ │ ├── Travelers.png │ │ ├── Two_Sigma.png │ │ ├── Akuna_Capital.png │ │ ├── Blue_Origin.png │ │ ├── Capital_One.png │ │ ├── Caterpillar.png │ │ ├── Dollar_Tree.png │ │ ├── Epic_Systems.png │ │ ├── Flow_Traders.png │ │ ├── Freddie_Mac.png │ │ ├── General_Mills.png │ │ ├── Goldman_Sachs.png │ │ ├── Hugging_Face.png │ │ ├── IMC_Trading.png │ │ ├── J.P._Morgan.png │ │ ├── Jane_Street.png │ │ ├── Jump_Trading.png │ │ ├── New_York_Life.png │ │ ├── Progressive.png │ │ ├── Radix_Trading.png │ │ ├── Tyson_Foods.png │ │ ├── Union_Pacific.png │ │ ├── UserTesting.png │ │ ├── Warner_Bros.png │ │ ├── Wells_Fargo.png │ │ ├── Charles_Schwab.png │ │ ├── ConocoPhillips.png │ │ ├── Dollar_General.png │ │ ├── Energy_Transfer.png │ │ ├── General_Motors.png │ │ ├── Liberty_Mutual.png │ │ ├── Lockheed_Martin.png │ │ ├── Morgan_Stanley.png │ │ ├── Tower_Research.png │ │ ├── United_Airlines.png │ │ ├── Virtu_Financial.png │ │ ├── Abbot_Laboratories.png │ │ ├── American_Airlines.png │ │ ├── American_Express.png │ │ ├── Berkshire_Hathaway.png │ │ ├── General_Dynamics.png │ │ ├── General_Electric.png │ │ ├── Johnson_&_Johnson.png │ │ ├── Northrop_Grumman.png │ │ ├── Performance_Food.png │ │ ├── Proctor_&_Gamble.png │ │ ├── Wolverine_Trading.png │ │ ├── Bristol_Myers_Squibb.png │ │ ├── Hudson_River_Trading.png │ │ ├── Northwestern_Mutual.png │ │ ├── Renaissance_Technologies.png │ │ ├── Thermo_Fisher_Scientific.png │ │ └── Yelp │ ├── pipelines.png │ ├── preview.png │ ├── manifest.json │ └── index.html ├── .prettierignore ├── src │ ├── static │ │ └── ratings │ │ │ ├── demon.png │ │ │ ├── frown.png │ │ │ ├── neutral.png │ │ │ ├── smiley.png │ │ │ └── BigSmiley.png │ ├── util │ │ ├── linkedinUtils.js │ │ ├── mongoUtils.js │ │ ├── generalUtils.js │ │ ├── apiRoutes.js │ │ ├── companyUtils.js │ │ ├── tokenUtils.js │ │ └── fetchUtils.js │ ├── components │ │ ├── ConditionalLink.js │ │ ├── Footer.js │ │ ├── ProfilePicture.js │ │ ├── landing │ │ │ ├── Hero.js │ │ │ ├── CTAButton.js │ │ │ ├── Marquee.js │ │ │ ├── CTA.js │ │ │ ├── About.js │ │ │ └── People.js │ │ ├── Error404.js │ │ ├── CompanyCard.js │ │ ├── TitleQuerySearchInput.js │ │ ├── DatePicker.js │ │ ├── QuerySearchInput.js │ │ ├── ExperienceQuerySearchInput.js │ │ └── PipelineDisplay.js │ ├── hooks │ │ ├── useAuthContext.js │ │ ├── useAdminContext.js │ │ ├── useEarlyAccess.js │ │ ├── usePatchJson.js │ │ └── useValidateExperience.js │ ├── pages │ │ ├── Loading.js │ │ ├── Home.js │ │ ├── (admin) │ │ │ ├── Admin.js │ │ │ └── AdminDashboard.js │ │ ├── Code.js │ │ └── Newsletter.js │ ├── index.css │ ├── index.js │ ├── context │ │ ├── EarlyAccessContext.js │ │ ├── AdminContext.js │ │ └── AuthContext.js │ ├── data │ │ └── index.js │ ├── App.css │ └── App.js ├── .env.example ├── .prettierrc ├── tailwind.config.js ├── .eslintrc.json └── package.json ├── preview.png ├── .vscode └── settings.json ├── server ├── routes │ ├── earlyAccess.js │ ├── mongodbId.js │ ├── admin.js │ ├── imageModeration.js │ ├── pfps.js │ ├── school.js │ ├── auth.js │ ├── token.js │ ├── profiles.js │ ├── offers.js │ ├── emails.js │ └── companies.js ├── models │ ├── emailModel.js │ ├── offerModel.js │ ├── experienceModel.js │ ├── schoolModel.js │ ├── companyModel.js │ ├── userModel.js │ ├── profileModel.js │ └── adminModel.js ├── .env.example ├── controllers │ ├── mongodbIdController.js │ ├── earlyAccessController.js │ ├── adminController.js │ ├── imageModerationController.js │ ├── pfpController.js │ └── schoolController.js ├── utils │ ├── apiRoutes.js │ └── generalUtils.js ├── package.json ├── middleware │ ├── token.js │ ├── admin.js │ ├── user.js │ └── profile.js ├── app.test.js ├── emails │ └── welcome.js └── index.js ├── .gitignore ├── LICENSE ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md /client/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /client/.prettierignore: -------------------------------------------------------------------------------- 1 | src/components/PipelineCard.js -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/preview.png -------------------------------------------------------------------------------- /client/public/CTA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/CTA.png -------------------------------------------------------------------------------- /client/public/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/hero.png -------------------------------------------------------------------------------- /client/public/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/avatar.png -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logo512.png -------------------------------------------------------------------------------- /client/public/logos/3M.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/3M.png -------------------------------------------------------------------------------- /client/public/logos/AIG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/AIG.png -------------------------------------------------------------------------------- /client/public/logos/AMD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/AMD.png -------------------------------------------------------------------------------- /client/public/logos/Box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Box.png -------------------------------------------------------------------------------- /client/public/logos/Dow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Dow.png -------------------------------------------------------------------------------- /client/public/logos/HCA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/HCA.png -------------------------------------------------------------------------------- /client/public/logos/HP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/HP.png -------------------------------------------------------------------------------- /client/public/logos/IBM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/IBM.png -------------------------------------------------------------------------------- /client/public/logos/TD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/TD.png -------------------------------------------------------------------------------- /client/public/logos/TJX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/TJX.png -------------------------------------------------------------------------------- /client/public/logos/X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/X.png -------------------------------------------------------------------------------- /client/public/pipelines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/pipelines.png -------------------------------------------------------------------------------- /client/public/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/preview.png -------------------------------------------------------------------------------- /client/public/logos/Adobe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Adobe.png -------------------------------------------------------------------------------- /client/public/logos/Apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Apple.png -------------------------------------------------------------------------------- /client/public/logos/Arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Arrow.png -------------------------------------------------------------------------------- /client/public/logos/Asana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Asana.png -------------------------------------------------------------------------------- /client/public/logos/Bolt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Bolt.png -------------------------------------------------------------------------------- /client/public/logos/Brex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Brex.png -------------------------------------------------------------------------------- /client/public/logos/Canva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Canva.png -------------------------------------------------------------------------------- /client/public/logos/Cigna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Cigna.png -------------------------------------------------------------------------------- /client/public/logos/Cisco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Cisco.png -------------------------------------------------------------------------------- /client/public/logos/Delta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Delta.png -------------------------------------------------------------------------------- /client/public/logos/Ebay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Ebay.png -------------------------------------------------------------------------------- /client/public/logos/Etsy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Etsy.png -------------------------------------------------------------------------------- /client/public/logos/FedEx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/FedEx.png -------------------------------------------------------------------------------- /client/public/logos/Figma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Figma.png -------------------------------------------------------------------------------- /client/public/logos/Glean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Glean.png -------------------------------------------------------------------------------- /client/public/logos/Hulu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Hulu.png -------------------------------------------------------------------------------- /client/public/logos/Intel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Intel.png -------------------------------------------------------------------------------- /client/public/logos/Kayak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Kayak.png -------------------------------------------------------------------------------- /client/public/logos/Lyft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Lyft.png -------------------------------------------------------------------------------- /client/public/logos/Mako.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Mako.png -------------------------------------------------------------------------------- /client/public/logos/Merck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Merck.png -------------------------------------------------------------------------------- /client/public/logos/Meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Meta.png -------------------------------------------------------------------------------- /client/public/logos/NASA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/NASA.png -------------------------------------------------------------------------------- /client/public/logos/Nike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nike.png -------------------------------------------------------------------------------- /client/public/logos/Nucor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nucor.png -------------------------------------------------------------------------------- /client/public/logos/Nuro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nuro.png -------------------------------------------------------------------------------- /client/public/logos/Okta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Okta.png -------------------------------------------------------------------------------- /client/public/logos/Pepsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Pepsi.png -------------------------------------------------------------------------------- /client/public/logos/Plaid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Plaid.png -------------------------------------------------------------------------------- /client/public/logos/Quora.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Quora.png -------------------------------------------------------------------------------- /client/public/logos/Ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Ramp.png -------------------------------------------------------------------------------- /client/public/logos/Slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Slack.png -------------------------------------------------------------------------------- /client/public/logos/Snap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Snap.png -------------------------------------------------------------------------------- /client/public/logos/Sysco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Sysco.png -------------------------------------------------------------------------------- /client/public/logos/TIAA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/TIAA.png -------------------------------------------------------------------------------- /client/public/logos/Tesla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Tesla.png -------------------------------------------------------------------------------- /client/public/logos/Uber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Uber.png -------------------------------------------------------------------------------- /client/public/logos/Visa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Visa.png -------------------------------------------------------------------------------- /client/public/logos/Waymo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Waymo.png -------------------------------------------------------------------------------- /client/public/logos/Wish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Wish.png -------------------------------------------------------------------------------- /client/public/logos/Yelp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Yelp.png -------------------------------------------------------------------------------- /client/public/logos/Yext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Yext.png -------------------------------------------------------------------------------- /client/public/logos/Zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Zoom.png -------------------------------------------------------------------------------- /client/public/logos/AbbVie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/AbbVie.png -------------------------------------------------------------------------------- /client/public/logos/Addepar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Addepar.png -------------------------------------------------------------------------------- /client/public/logos/Affirm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Affirm.png -------------------------------------------------------------------------------- /client/public/logos/Airbnb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Airbnb.png -------------------------------------------------------------------------------- /client/public/logos/Airtable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Airtable.png -------------------------------------------------------------------------------- /client/public/logos/Allstate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Allstate.png -------------------------------------------------------------------------------- /client/public/logos/Amazon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Amazon.png -------------------------------------------------------------------------------- /client/public/logos/Anduril.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Anduril.png -------------------------------------------------------------------------------- /client/public/logos/Autodesk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Autodesk.png -------------------------------------------------------------------------------- /client/public/logos/Barclays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Barclays.png -------------------------------------------------------------------------------- /client/public/logos/Best_Buy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Best_Buy.png -------------------------------------------------------------------------------- /client/public/logos/Boeing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Boeing.png -------------------------------------------------------------------------------- /client/public/logos/CarMax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/CarMax.png -------------------------------------------------------------------------------- /client/public/logos/Citadel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Citadel.png -------------------------------------------------------------------------------- /client/public/logos/Cohere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Cohere.png -------------------------------------------------------------------------------- /client/public/logos/Coinbase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Coinbase.png -------------------------------------------------------------------------------- /client/public/logos/Cruise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Cruise.png -------------------------------------------------------------------------------- /client/public/logos/Datadog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Datadog.png -------------------------------------------------------------------------------- /client/public/logos/Deepmind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Deepmind.png -------------------------------------------------------------------------------- /client/public/logos/Discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Discord.png -------------------------------------------------------------------------------- /client/public/logos/Disney.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Disney.png -------------------------------------------------------------------------------- /client/public/logos/Docusign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Docusign.png -------------------------------------------------------------------------------- /client/public/logos/DoorDash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/DoorDash.png -------------------------------------------------------------------------------- /client/public/logos/Dropbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Dropbox.png -------------------------------------------------------------------------------- /client/public/logos/Duolingo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Duolingo.png -------------------------------------------------------------------------------- /client/public/logos/Elastic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Elastic.png -------------------------------------------------------------------------------- /client/public/logos/Expedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Expedia.png -------------------------------------------------------------------------------- /client/public/logos/Fidelity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Fidelity.png -------------------------------------------------------------------------------- /client/public/logos/Flexport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Flexport.png -------------------------------------------------------------------------------- /client/public/logos/Fox_News.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Fox_News.png -------------------------------------------------------------------------------- /client/public/logos/GitHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/GitHub.png -------------------------------------------------------------------------------- /client/public/logos/Google.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Google.png -------------------------------------------------------------------------------- /client/public/logos/GrubHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/GrubHub.png -------------------------------------------------------------------------------- /client/public/logos/HubSpot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/HubSpot.png -------------------------------------------------------------------------------- /client/public/logos/Humana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Humana.png -------------------------------------------------------------------------------- /client/public/logos/Indeed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Indeed.png -------------------------------------------------------------------------------- /client/public/logos/Intuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Intuit.png -------------------------------------------------------------------------------- /client/public/logos/Kelloggs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Kelloggs.png -------------------------------------------------------------------------------- /client/public/logos/Lennar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Lennar.png -------------------------------------------------------------------------------- /client/public/logos/Linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Linkedin.png -------------------------------------------------------------------------------- /client/public/logos/Macy's.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Macy's.png -------------------------------------------------------------------------------- /client/public/logos/MetLife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/MetLife.png -------------------------------------------------------------------------------- /client/public/logos/Micron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Micron.png -------------------------------------------------------------------------------- /client/public/logos/MongoDB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/MongoDB.png -------------------------------------------------------------------------------- /client/public/logos/Netflix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Netflix.png -------------------------------------------------------------------------------- /client/public/logos/Nextdoor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nextdoor.png -------------------------------------------------------------------------------- /client/public/logos/Notion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Notion.png -------------------------------------------------------------------------------- /client/public/logos/Nutanix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nutanix.png -------------------------------------------------------------------------------- /client/public/logos/Nvidia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nvidia.png -------------------------------------------------------------------------------- /client/public/logos/OpenAI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/OpenAI.png -------------------------------------------------------------------------------- /client/public/logos/Optiver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Optiver.png -------------------------------------------------------------------------------- /client/public/logos/Oracle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Oracle.png -------------------------------------------------------------------------------- /client/public/logos/Palantir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Palantir.png -------------------------------------------------------------------------------- /client/public/logos/PayPal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/PayPal.png -------------------------------------------------------------------------------- /client/public/logos/Peloton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Peloton.png -------------------------------------------------------------------------------- /client/public/logos/Pintrest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Pintrest.png -------------------------------------------------------------------------------- /client/public/logos/Publix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Publix.png -------------------------------------------------------------------------------- /client/public/logos/Qualcomm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Qualcomm.png -------------------------------------------------------------------------------- /client/public/logos/Raytheon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Raytheon.png -------------------------------------------------------------------------------- /client/public/logos/Red_Hat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Red_Hat.png -------------------------------------------------------------------------------- /client/public/logos/Reddit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Reddit.png -------------------------------------------------------------------------------- /client/public/logos/Redfin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Redfin.png -------------------------------------------------------------------------------- /client/public/logos/Retool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Retool.png -------------------------------------------------------------------------------- /client/public/logos/Rippling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Rippling.png -------------------------------------------------------------------------------- /client/public/logos/Roblox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Roblox.png -------------------------------------------------------------------------------- /client/public/logos/Samsara.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Samsara.png -------------------------------------------------------------------------------- /client/public/logos/Samsung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Samsung.png -------------------------------------------------------------------------------- /client/public/logos/Scale_AI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Scale_AI.png -------------------------------------------------------------------------------- /client/public/logos/Shopify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Shopify.png -------------------------------------------------------------------------------- /client/public/logos/SpaceX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/SpaceX.png -------------------------------------------------------------------------------- /client/public/logos/Spectrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Spectrum.png -------------------------------------------------------------------------------- /client/public/logos/Splunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Splunk.png -------------------------------------------------------------------------------- /client/public/logos/Spotify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Spotify.png -------------------------------------------------------------------------------- /client/public/logos/Square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Square.png -------------------------------------------------------------------------------- /client/public/logos/StoneX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/StoneX.png -------------------------------------------------------------------------------- /client/public/logos/Tableau.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Tableau.png -------------------------------------------------------------------------------- /client/public/logos/Tanium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Tanium.png -------------------------------------------------------------------------------- /client/public/logos/TikTok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/TikTok.png -------------------------------------------------------------------------------- /client/public/logos/Twilio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Twilio.png -------------------------------------------------------------------------------- /client/public/logos/Twitch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Twitch.png -------------------------------------------------------------------------------- /client/public/logos/US_Foods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/US_Foods.png -------------------------------------------------------------------------------- /client/public/logos/VMware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/VMware.png -------------------------------------------------------------------------------- /client/public/logos/Verily.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Verily.png -------------------------------------------------------------------------------- /client/public/logos/Walmart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Walmart.png -------------------------------------------------------------------------------- /client/public/logos/Wayfair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Wayfair.png -------------------------------------------------------------------------------- /client/public/logos/Workday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Workday.png -------------------------------------------------------------------------------- /client/public/logos/Zillow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Zillow.png -------------------------------------------------------------------------------- /client/public/logos/Albertsons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Albertsons.png -------------------------------------------------------------------------------- /client/public/logos/Anthropic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Anthropic.png -------------------------------------------------------------------------------- /client/public/logos/Atlassian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Atlassian.png -------------------------------------------------------------------------------- /client/public/logos/Blackrock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Blackrock.png -------------------------------------------------------------------------------- /client/public/logos/Bloomberg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Bloomberg.png -------------------------------------------------------------------------------- /client/public/logos/ByteDance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/ByteDance.png -------------------------------------------------------------------------------- /client/public/logos/Cloudflare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Cloudflare.png -------------------------------------------------------------------------------- /client/public/logos/Coca_Cola.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Coca_Cola.png -------------------------------------------------------------------------------- /client/public/logos/D.E._Shaw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/D.E._Shaw.png -------------------------------------------------------------------------------- /client/public/logos/Databricks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Databricks.png -------------------------------------------------------------------------------- /client/public/logos/Five_Rings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Five_Rings.png -------------------------------------------------------------------------------- /client/public/logos/Honeywell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Honeywell.png -------------------------------------------------------------------------------- /client/public/logos/Instacart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Instacart.png -------------------------------------------------------------------------------- /client/public/logos/John_Deere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/John_Deere.png -------------------------------------------------------------------------------- /client/public/logos/MasterCard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/MasterCard.png -------------------------------------------------------------------------------- /client/public/logos/McDonalds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/McDonalds.png -------------------------------------------------------------------------------- /client/public/logos/Microsoft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Microsoft.png -------------------------------------------------------------------------------- /client/public/logos/Nationwide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Nationwide.png -------------------------------------------------------------------------------- /client/public/logos/Neuralink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Neuralink.png -------------------------------------------------------------------------------- /client/public/logos/Occidental.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Occidental.png -------------------------------------------------------------------------------- /client/public/logos/PBF_Energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/PBF_Energy.png -------------------------------------------------------------------------------- /client/public/logos/Postmates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Postmates.png -------------------------------------------------------------------------------- /client/public/logos/Prudential.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Prudential.png -------------------------------------------------------------------------------- /client/public/logos/Qualtrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Qualtrics.png -------------------------------------------------------------------------------- /client/public/logos/Riot_Games.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Riot_Games.png -------------------------------------------------------------------------------- /client/public/logos/Robinhood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Robinhood.png -------------------------------------------------------------------------------- /client/public/logos/Salesforce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Salesforce.png -------------------------------------------------------------------------------- /client/public/logos/ServiceNow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/ServiceNow.png -------------------------------------------------------------------------------- /client/public/logos/Snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Snowflake.png -------------------------------------------------------------------------------- /client/public/logos/Starbucks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Starbucks.png -------------------------------------------------------------------------------- /client/public/logos/State_Farm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/State_Farm.png -------------------------------------------------------------------------------- /client/public/logos/TD_Synnex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/TD_Synnex.png -------------------------------------------------------------------------------- /client/public/logos/Travelers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Travelers.png -------------------------------------------------------------------------------- /client/public/logos/Two_Sigma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Two_Sigma.png -------------------------------------------------------------------------------- /client/public/logos/Akuna_Capital.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Akuna_Capital.png -------------------------------------------------------------------------------- /client/public/logos/Blue_Origin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Blue_Origin.png -------------------------------------------------------------------------------- /client/public/logos/Capital_One.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Capital_One.png -------------------------------------------------------------------------------- /client/public/logos/Caterpillar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Caterpillar.png -------------------------------------------------------------------------------- /client/public/logos/Dollar_Tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Dollar_Tree.png -------------------------------------------------------------------------------- /client/public/logos/Epic_Systems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Epic_Systems.png -------------------------------------------------------------------------------- /client/public/logos/Flow_Traders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Flow_Traders.png -------------------------------------------------------------------------------- /client/public/logos/Freddie_Mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Freddie_Mac.png -------------------------------------------------------------------------------- /client/public/logos/General_Mills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/General_Mills.png -------------------------------------------------------------------------------- /client/public/logos/Goldman_Sachs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Goldman_Sachs.png -------------------------------------------------------------------------------- /client/public/logos/Hugging_Face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Hugging_Face.png -------------------------------------------------------------------------------- /client/public/logos/IMC_Trading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/IMC_Trading.png -------------------------------------------------------------------------------- /client/public/logos/J.P._Morgan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/J.P._Morgan.png -------------------------------------------------------------------------------- /client/public/logos/Jane_Street.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Jane_Street.png -------------------------------------------------------------------------------- /client/public/logos/Jump_Trading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Jump_Trading.png -------------------------------------------------------------------------------- /client/public/logos/New_York_Life.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/New_York_Life.png -------------------------------------------------------------------------------- /client/public/logos/Progressive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Progressive.png -------------------------------------------------------------------------------- /client/public/logos/Radix_Trading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Radix_Trading.png -------------------------------------------------------------------------------- /client/public/logos/Tyson_Foods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Tyson_Foods.png -------------------------------------------------------------------------------- /client/public/logos/Union_Pacific.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Union_Pacific.png -------------------------------------------------------------------------------- /client/public/logos/UserTesting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/UserTesting.png -------------------------------------------------------------------------------- /client/public/logos/Warner_Bros.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Warner_Bros.png -------------------------------------------------------------------------------- /client/public/logos/Wells_Fargo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Wells_Fargo.png -------------------------------------------------------------------------------- /client/src/static/ratings/demon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/src/static/ratings/demon.png -------------------------------------------------------------------------------- /client/src/static/ratings/frown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/src/static/ratings/frown.png -------------------------------------------------------------------------------- /client/src/static/ratings/neutral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/src/static/ratings/neutral.png -------------------------------------------------------------------------------- /client/src/static/ratings/smiley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/src/static/ratings/smiley.png -------------------------------------------------------------------------------- /client/public/logos/Charles_Schwab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Charles_Schwab.png -------------------------------------------------------------------------------- /client/public/logos/ConocoPhillips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/ConocoPhillips.png -------------------------------------------------------------------------------- /client/public/logos/Dollar_General.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Dollar_General.png -------------------------------------------------------------------------------- /client/public/logos/Energy_Transfer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Energy_Transfer.png -------------------------------------------------------------------------------- /client/public/logos/General_Motors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/General_Motors.png -------------------------------------------------------------------------------- /client/public/logos/Liberty_Mutual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Liberty_Mutual.png -------------------------------------------------------------------------------- /client/public/logos/Lockheed_Martin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Lockheed_Martin.png -------------------------------------------------------------------------------- /client/public/logos/Morgan_Stanley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Morgan_Stanley.png -------------------------------------------------------------------------------- /client/public/logos/Tower_Research.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Tower_Research.png -------------------------------------------------------------------------------- /client/public/logos/United_Airlines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/United_Airlines.png -------------------------------------------------------------------------------- /client/public/logos/Virtu_Financial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Virtu_Financial.png -------------------------------------------------------------------------------- /client/src/static/ratings/BigSmiley.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/src/static/ratings/BigSmiley.png -------------------------------------------------------------------------------- /client/.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_NODE_ENV= 2 | 3 | REACT_APP_API_URL= 4 | 5 | REACT_APP_LINKEDIN_CLIENT_ID= 6 | REACT_APP_LINKEDIN_SCOPE= 7 | -------------------------------------------------------------------------------- /client/public/logos/Abbot_Laboratories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Abbot_Laboratories.png -------------------------------------------------------------------------------- /client/public/logos/American_Airlines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/American_Airlines.png -------------------------------------------------------------------------------- /client/public/logos/American_Express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/American_Express.png -------------------------------------------------------------------------------- /client/public/logos/Berkshire_Hathaway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Berkshire_Hathaway.png -------------------------------------------------------------------------------- /client/public/logos/General_Dynamics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/General_Dynamics.png -------------------------------------------------------------------------------- /client/public/logos/General_Electric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/General_Electric.png -------------------------------------------------------------------------------- /client/public/logos/Johnson_&_Johnson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Johnson_&_Johnson.png -------------------------------------------------------------------------------- /client/public/logos/Northrop_Grumman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Northrop_Grumman.png -------------------------------------------------------------------------------- /client/public/logos/Performance_Food.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Performance_Food.png -------------------------------------------------------------------------------- /client/public/logos/Proctor_&_Gamble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Proctor_&_Gamble.png -------------------------------------------------------------------------------- /client/public/logos/Wolverine_Trading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Wolverine_Trading.png -------------------------------------------------------------------------------- /client/public/logos/Bristol_Myers_Squibb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Bristol_Myers_Squibb.png -------------------------------------------------------------------------------- /client/public/logos/Hudson_River_Trading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Hudson_River_Trading.png -------------------------------------------------------------------------------- /client/public/logos/Northwestern_Mutual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Northwestern_Mutual.png -------------------------------------------------------------------------------- /client/public/logos/Renaissance_Technologies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Renaissance_Technologies.png -------------------------------------------------------------------------------- /client/public/logos/Thermo_Fisher_Scientific.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pipelines-lol/pipelines/HEAD/client/public/logos/Thermo_Fisher_Scientific.png -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier.insertPragma": false, 3 | "prettier.bracketSameLine": false, 4 | "editor.codeActionsOnSave": ["source.fixAll.eslint"], 5 | "editor.formatOnSave": true 6 | } 7 | -------------------------------------------------------------------------------- /client/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": false, 5 | "singleQuote": true, 6 | "plugins": [ 7 | "prettier-plugin-tailwindcss" 8 | ] 9 | } -------------------------------------------------------------------------------- /client/src/util/linkedinUtils.js: -------------------------------------------------------------------------------- 1 | export const CLIENT_ID = process.env.REACT_APP_LINKEDIN_CLIENT_ID 2 | export const REDIRECT_URI = process.env.REACT_APP_LINKEDIN_REDIRECT_URI 3 | export const SCOPE = process.env.REACT_APP_LINKEDIN_SCOPE 4 | -------------------------------------------------------------------------------- /server/routes/earlyAccess.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { checkCode } = require("../controllers/earlyAccessController"); 3 | 4 | const router = express.Router(); 5 | 6 | // check code 7 | router.post("/check", checkCode); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /server/models/emailModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const Schema = mongoose.Schema; 4 | 5 | const emailSchema = new Schema( 6 | { 7 | email: String, 8 | }, 9 | { timestamps: true } 10 | ); 11 | 12 | module.exports = mongoose.model("Email", emailSchema); 13 | -------------------------------------------------------------------------------- /server/routes/mongodbId.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const { 3 | checkMongodbId 4 | } = require('../controllers/mongodbIdController') 5 | 6 | const router = express.Router() 7 | 8 | // GET a check of a single id 9 | router.get('/:id', checkMongodbId) 10 | 11 | module.exports = router; -------------------------------------------------------------------------------- /client/src/components/ConditionalLink.js: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom' 2 | 3 | export const ConditionalLink = ({ children, condition, ...props }) => { 4 | return !!condition && props.to ? ( 5 | {children} 6 | ) : ( 7 | <>{children} 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /server/.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV= 2 | PORT= 3 | DB_CONNECT= 4 | JWT_SECRET= 5 | 6 | API_URL= 7 | 8 | BUCKET_NAME= 9 | BUCKET_REGION= 10 | AWS_ACCESS_KEY_ID= 11 | AWS_SECRET_ACCESS_KEY= 12 | 13 | LINKEDIN_CLIENT_ID= 14 | LINKEDIN_CLIENT_SECRET= 15 | 16 | RESEND_EMAIL= 17 | RESEND_API_KEY= 18 | 19 | EARLY_ACCESS_CODE= -------------------------------------------------------------------------------- /server/routes/admin.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { loginAdmin, verifyToken } = require("../controllers/adminController"); 3 | 4 | const router = express.Router(); 5 | 6 | // LOGIN user 7 | router.post("/login", loginAdmin); 8 | 9 | // VERIFY admin token 10 | router.post("/verify", verifyToken); 11 | 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # npm 2 | node_modules 3 | package-lock.json 4 | *.log 5 | *.gz 6 | 7 | # Coveralls 8 | .nyc_output 9 | coverage 10 | 11 | # Environmental Vars 12 | .env 13 | 14 | # Development testing 15 | testing/ 16 | 17 | # Benchmarking 18 | benchmarks/graphs 19 | build/ 20 | 21 | # ignore additional files using core.excludesFile 22 | # https://git-scm.com/docs/gitignore -------------------------------------------------------------------------------- /client/src/hooks/useAuthContext.js: -------------------------------------------------------------------------------- 1 | import { AuthContext } from '../context/AuthContext' 2 | import { useContext } from 'react' 3 | 4 | export const useAuthContext = () => { 5 | const context = useContext(AuthContext) 6 | 7 | if (!context) { 8 | throw Error('useAuthContext must be used inside an AuthContextProvider') 9 | } 10 | 11 | return context 12 | } 13 | -------------------------------------------------------------------------------- /client/src/hooks/useAdminContext.js: -------------------------------------------------------------------------------- 1 | import { AdminContext } from '../context/AdminContext' 2 | import { useContext } from 'react' 3 | 4 | export const useAdmin = () => { 5 | const context = useContext(AdminContext) 6 | 7 | if (!context) { 8 | throw Error( 9 | 'useAdminContext must be used inside an AdminContextProvider' 10 | ) 11 | } 12 | 13 | return context 14 | } 15 | -------------------------------------------------------------------------------- /server/controllers/mongodbIdController.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose') 2 | 3 | const checkMongodbId = async (req, res) => { 4 | const { id } = req.params 5 | 6 | if (!mongoose.Types.ObjectId.isValid(id)) { 7 | return res.status(200).json({ response: false }) 8 | } else { 9 | return res.status(200).json({ response: true }) 10 | } 11 | } 12 | 13 | module.exports = { 14 | checkMongodbId 15 | } -------------------------------------------------------------------------------- /server/models/offerModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const OfferSchema = new Schema({ 5 | companyId: { type: Schema.Types.ObjectId, ref: "Company" }, 6 | companyName: String, // Store as lowercase in the database 7 | title: String, 8 | startDate: Date, 9 | endDate: Date, 10 | isIndefinite: Boolean, 11 | }); 12 | 13 | module.exports = mongoose.model("Offer", OfferSchema); 14 | -------------------------------------------------------------------------------- /client/src/hooks/useEarlyAccess.js: -------------------------------------------------------------------------------- 1 | import { EarlyAccessContext } from '../context/EarlyAccessContext' 2 | import { useContext } from 'react' 3 | 4 | export const useEarlyAccess = () => { 5 | const context = useContext(EarlyAccessContext) 6 | 7 | if (!context) { 8 | throw Error( 9 | 'useEarlyAccessContext must be used inside an EarlyAccessContextProvider' 10 | ) 11 | } 12 | 13 | return context 14 | } 15 | -------------------------------------------------------------------------------- /server/controllers/earlyAccessController.js: -------------------------------------------------------------------------------- 1 | const checkCode = async (req, res) => { 2 | const { code } = req.body; 3 | 4 | if (!code) { 5 | return res.status(400).json({ error: "No code provided." }); 6 | } 7 | if (code !== process.env.EARLY_ACCESS_CODE) { 8 | return res.status(400).json({ error: "Incorrect code." }); 9 | } 10 | 11 | res.status(200).json({ code }); 12 | }; 13 | 14 | module.exports = { 15 | checkCode, 16 | }; 17 | -------------------------------------------------------------------------------- /server/routes/imageModeration.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const { 3 | recognizeImage 4 | } = require('../controllers/imageModerationController') 5 | 6 | const router = express.Router() 7 | 8 | const multer = require('multer') 9 | 10 | const storage = multer.memoryStorage() 11 | const upload = multer({ storage: storage }) 12 | 13 | // POST a check of a single image 14 | router.post('/', upload.single('pfp'), recognizeImage) 15 | 16 | module.exports = router; -------------------------------------------------------------------------------- /server/models/experienceModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const ExperienceSchema = new Schema({ 5 | companyId: { type: Schema.Types.ObjectId, ref: "Company" }, 6 | companyName: String, // Store as lowercase in the database 7 | displayName: String, 8 | title: String, 9 | startDate: Date, 10 | endDate: Date, 11 | isIndefinite: Boolean, 12 | rating: Number, 13 | logo: String, 14 | }); 15 | 16 | module.exports = mongoose.model("Experience", ExperienceSchema); 17 | -------------------------------------------------------------------------------- /server/routes/pfps.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const { 3 | getPfp, 4 | updatePfp 5 | } = require('../controllers/pfpController') 6 | 7 | const router = express.Router() 8 | 9 | const multer = require('multer') 10 | 11 | const storage = multer.memoryStorage() 12 | const upload = multer({ storage: storage }) 13 | 14 | // GET a single pfp (by id) 15 | router.get('/:id', getPfp) 16 | 17 | // UPDATE a single pfp (by id) 18 | router.patch('/:id', upload.single('pfp'), updatePfp); 19 | 20 | module.exports = router; -------------------------------------------------------------------------------- /server/models/schoolModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const schoolSchema = new Schema({ 5 | name: { 6 | type: String, 7 | required: true, 8 | }, 9 | domains: [String], 10 | state_province: String, 11 | country: String, 12 | alpha_two_code: String, 13 | webpages: [String], 14 | schoolTally: { 15 | type: Map, 16 | of: Number, 17 | }, 18 | rank: Number, 19 | logo: String, 20 | }); 21 | 22 | module.exports = mongoose.model("School", schoolSchema); 23 | -------------------------------------------------------------------------------- /client/src/util/mongoUtils.js: -------------------------------------------------------------------------------- 1 | import { HOST } from './apiRoutes' 2 | import { fetchWithAuth } from './fetchUtils' 3 | 4 | export const isMongoDBId = async (id) => { 5 | try { 6 | const response = await fetchWithAuth({ 7 | url: `${HOST}/api/mongodbId/${id}`, 8 | method: 'GET', 9 | headers: { 10 | 'Content-Type': 'application/json', 11 | }, 12 | }) 13 | 14 | return response 15 | } catch (error) { 16 | console.error(error.message) 17 | return true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/src/util/generalUtils.js: -------------------------------------------------------------------------------- 1 | export function isObjEmpty(obj) { 2 | return Object.keys(obj).length === 0 3 | } 4 | 5 | export function binarySearch(arr, target) { 6 | let left = 0 7 | let right = arr.length - 1 8 | while (left <= right) { 9 | let mid = Math.floor((left + right) / 2) 10 | if (arr[mid] === target) { 11 | return mid 12 | } else if (arr[mid] < target) { 13 | left = mid + 1 // Search in the right half 14 | } else { 15 | right = mid - 1 // Search in the left half 16 | } 17 | } 18 | 19 | return -1 20 | } 21 | -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Pipelines", 3 | "name": "Find your pipeline.", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /client/src/util/apiRoutes.js: -------------------------------------------------------------------------------- 1 | const HOST = 2 | process.env.REACT_APP_NODE_ENV === 'DEV' 3 | ? 'http://localhost:4000' 4 | : process.env.REACT_APP_NODE_ENV === 'PROD' 5 | ? process.env.REACT_APP_API_URL 6 | : (console.error('Unknown mode:', process.env.MODE), null) 7 | 8 | const HOMEPAGE = 9 | process.env.REACT_APP_NODE_ENV === 'DEV' 10 | ? 'http://localhost:3000' 11 | : process.env.REACT_APP_NODE_ENV === 'PROD' 12 | ? 'https://pipelines.lol' 13 | : (console.error('Unknown mode:', process.env.MODE), null) 14 | 15 | export { HOMEPAGE, HOST } 16 | -------------------------------------------------------------------------------- /server/utils/apiRoutes.js: -------------------------------------------------------------------------------- 1 | const dotenv = require("dotenv"); 2 | 3 | dotenv.config(); 4 | 5 | const config = { 6 | HOST: 7 | process.env.NODE_ENV === "DEV" 8 | ? "http://localhost:4000" 9 | : process.env.NODE_ENV === "PROD" 10 | ? process.env.API_URL 11 | : (console.error("Unknown mode:", process.env.MODE), null), 12 | 13 | HOMEPAGE: 14 | process.env.NODE_ENV === "DEV" 15 | ? "http://localhost:3000" 16 | : process.env.NODE_ENV === "PROD" 17 | ? "https://pipelines.lol" 18 | : (console.error("Unknown mode:", process.env.MODE), null), 19 | }; 20 | 21 | module.exports = config; 22 | -------------------------------------------------------------------------------- /server/routes/school.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { 3 | searchSchools, 4 | getSchool, 5 | updateSchool, 6 | createSchool, 7 | deleteSchool, 8 | } = require("../controllers/schoolController"); 9 | 10 | const read = express.Router(); 11 | const write = express.Router(); 12 | 13 | write.post("/create", createSchool); 14 | 15 | // GET schools by query 16 | read.get("/get/schools/:query", searchSchools); 17 | 18 | read.patch("/update/:id", updateSchool); 19 | 20 | read.get("/get/:id", getSchool); 21 | 22 | write.get("/delete/:id", deleteSchool); 23 | 24 | module.exports = { 25 | read, 26 | write, 27 | }; 28 | -------------------------------------------------------------------------------- /client/src/pages/Loading.js: -------------------------------------------------------------------------------- 1 | import { Triangle } from 'react-loader-spinner' 2 | function Loading() { 3 | return ( 4 | <> 5 |
6 | 15 |
16 | 17 | ) 18 | } 19 | 20 | export default Loading 21 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer utilities { 6 | .paused { 7 | animation-play-state: paused; 8 | } 9 | } 10 | 11 | body { 12 | margin: 0; 13 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 14 | 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 15 | 'Helvetica Neue', sans-serif; 16 | -webkit-font-smoothing: antialiased; 17 | -moz-osx-font-smoothing: grayscale; 18 | background-color: black; 19 | } 20 | 21 | code { 22 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 23 | monospace; 24 | } 25 | -------------------------------------------------------------------------------- /server/routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { 3 | loginUser, 4 | verifyToken, 5 | getLinkedinInfo, 6 | refreshLinkedinToken, 7 | } = require("../controllers/authController"); 8 | 9 | // middleware 10 | const { verifyUser } = require("../middleware/user"); 11 | 12 | const router = express.Router(); 13 | 14 | // LOGIN user 15 | router.post("/login", verifyUser, loginUser); 16 | 17 | // VERIFY linkedin token 18 | router.post("/verify", verifyToken); 19 | 20 | // GET linkedin user info 21 | router.get("/linkedin/userinfo", getLinkedinInfo); 22 | 23 | // REFRESH linkedin token 24 | router.post("/linkedin/refresh", refreshLinkedinToken); 25 | 26 | module.exports = router; 27 | -------------------------------------------------------------------------------- /server/routes/token.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { v4: uuidv4 } = require("uuid"); 3 | const { generateToken } = require("../middleware/token"); 4 | 5 | const router = express.Router(); 6 | 7 | const getToken = async (req, res) => { 8 | // Extract profileId from request parameters 9 | const { linkedinToken, adminToken } = req.query; 10 | 11 | // generate sessionId 12 | const sessionId = uuidv4(); 13 | 14 | // generate token with profileId included in the payload if it exists 15 | const token = generateToken(sessionId, linkedinToken, adminToken); 16 | 17 | res.json(token); 18 | }; 19 | 20 | // GET token 21 | router.get("/", getToken); 22 | 23 | module.exports = router; 24 | -------------------------------------------------------------------------------- /client/src/util/companyUtils.js: -------------------------------------------------------------------------------- 1 | import { companies } from '../data/companyData' 2 | 3 | // capitalizes the title of a company 4 | // lower case name -> display name 5 | export function capitalizeCompanyTitle(str) { 6 | // shoutout bobdagoat 7 | if (typeof str !== 'string' || str.trim() === '') { 8 | // bad input 9 | return str 10 | } 11 | 12 | const formattedCompany = companies.find( 13 | (company) => company.name.toLowerCase() === str.toLowerCase() 14 | ) 15 | 16 | if (formattedCompany) { 17 | return formattedCompany.name 18 | } 19 | 20 | return str 21 | .split(' ') 22 | .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) 23 | .join(' ') 24 | } 25 | -------------------------------------------------------------------------------- /server/routes/profiles.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { 3 | getProfiles, 4 | getProfile, 5 | getRandomProfiles, 6 | deleteProfile, 7 | updateProfile, 8 | } = require("../controllers/profileController"); 9 | 10 | const read = express.Router(); 11 | const write = express.Router(); 12 | 13 | // GET all profiles 14 | read.get("/", getProfiles); 15 | 16 | // GET a single profile 17 | read.get("/get/:id", getProfile); 18 | 19 | // GET a certain amount of random profiles 20 | read.get("/random", getRandomProfiles); 21 | 22 | // DELETE a profile 23 | write.delete("/:id", deleteProfile); 24 | 25 | // UPDATE a profile 26 | write.patch("/:id", updateProfile); 27 | 28 | module.exports = { 29 | read, 30 | write, 31 | }; 32 | -------------------------------------------------------------------------------- /server/routes/offers.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { 3 | createOffer, 4 | updateOffer, 5 | deleteOffer, 6 | getOffer, 7 | getAllOffers, 8 | } = require("../controllers/offerController.js"); 9 | 10 | const router = express.Router(); 11 | 12 | // CREATE an offer for a profile 13 | router.post("/:profileId", createOffer); 14 | 15 | // UPDATE an offer for a profile 16 | router.put("/:profileId/:offerId", updateOffer); 17 | 18 | // DELETE an offer for a profile 19 | router.delete("/:profileId/:offerId", deleteOffer); 20 | 21 | // GET an offer for a profile 22 | router.get("/:profileId/:offerId", getOffer); 23 | 24 | // GET all offers for a profile 25 | router.get("/:profileId", getAllOffers); 26 | 27 | module.exports = router; 28 | -------------------------------------------------------------------------------- /server/utils/generalUtils.js: -------------------------------------------------------------------------------- 1 | function binarySearch(arr, target) { 2 | let left = 0; 3 | let right = arr.length - 1; 4 | while (left <= right) { 5 | let mid = Math.floor((left + right) / 2); 6 | if (arr[mid] === target) { 7 | return mid; 8 | } else if (arr[mid] < target) { 9 | left = mid + 1; // Search in the right half 10 | } else { 11 | right = mid - 1; // Search in the left half 12 | } 13 | } 14 | 15 | return -1; 16 | } 17 | 18 | function shuffleArray(array) { 19 | for (let i = array.length - 1; i > 0; i--) { 20 | const j = Math.floor(Math.random() * (i + 1)); 21 | [array[i], array[j]] = [array[j], array[i]]; 22 | } 23 | return array; 24 | } 25 | 26 | module.exports = { binarySearch, shuffleArray }; 27 | -------------------------------------------------------------------------------- /client/src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import { Link } from 'react-router-dom' 2 | 3 | const Footer = () => { 4 | return ( 5 | <> 6 |
7 |

8 | @2024 pipelines.lol. All rights reserved. 9 |

10 | 14 | Have a suggestion? 15 | 16 |
17 | 18 | ) 19 | } 20 | 21 | export default Footer 22 | -------------------------------------------------------------------------------- /server/models/companyModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const companySchema = new Schema({ 5 | name: { 6 | type: String, 7 | required: true, 8 | }, 9 | displayName: { 10 | type: String, 11 | required: true, 12 | }, 13 | logo: String, 14 | description: String, 15 | rating: Number, 16 | prevCompanies: { 17 | type: Map, 18 | of: Number, 19 | }, 20 | postCompanies: { 21 | type: Map, 22 | of: Number, 23 | }, 24 | tenure: Number, 25 | Employees: [{ type: Schema.Types.ObjectId, ref: "Profile" }], 26 | interns: [{ type: Schema.Types.ObjectId, ref: "Profile" }], 27 | ratedEmployees: [{ type: Schema.Types.ObjectId, ref: "Profile" }], 28 | }); 29 | 30 | module.exports = mongoose.model("Company", companySchema); 31 | -------------------------------------------------------------------------------- /server/models/userModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const Schema = mongoose.Schema; 3 | 4 | const userSchema = new Schema( 5 | { 6 | email: { 7 | type: String, 8 | unique: true, 9 | required: true, 10 | }, 11 | profileId: String, 12 | }, 13 | { timestamps: true } 14 | ); 15 | 16 | userSchema.statics.login = async function (email) { 17 | // validation 18 | if (!email) { 19 | throw new Error("Email is required."); 20 | } 21 | 22 | let user = await this.findOne({ email }); 23 | 24 | if (!user) { 25 | user = await this.create({ email, profileId: null }); 26 | } 27 | 28 | //* Logs 29 | console.log(`User logged in: ${email}`); 30 | console.log(user); 31 | 32 | return user; 33 | }; 34 | 35 | module.exports = mongoose.model("User", userSchema); 36 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import './index.css' 4 | import App from './App' 5 | 6 | // context 7 | import { AuthContextProvider } from './context/AuthContext' 8 | import { AdminContextProvider } from './context/AdminContext' 9 | import { EarlyAccessContextProvider } from './context/EarlyAccessContext' 10 | 11 | // store contexts here 12 | const contextProviders = [ 13 | EarlyAccessContextProvider, 14 | AuthContextProvider, 15 | AdminContextProvider, 16 | ] 17 | 18 | const root = ReactDOM.createRoot(document.getElementById('root')) 19 | root.render( 20 | 21 | {contextProviders.reduceRight( 22 | (acc, Provider) => { 23 | return {acc} 24 | }, 25 | 26 | )} 27 | 28 | ) 29 | -------------------------------------------------------------------------------- /server/routes/emails.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const { 3 | addToNewsletter, 4 | sendEmails, 5 | addEmail, 6 | getEmails, 7 | getEmailById, 8 | removeEmail, 9 | removeEmailById, 10 | } = require("../controllers/emailController"); 11 | 12 | const read = express.Router(); 13 | const write = express.Router(); 14 | 15 | // send email + add to newsletter 16 | read.post("/newsletter", addToNewsletter); 17 | 18 | // SEND emails 19 | write.post("/send", sendEmails); 20 | 21 | // CREATE an email 22 | write.post("/", addEmail); 23 | 24 | // GET emails 25 | write.get("/", getEmails); 26 | 27 | // GET an email by id 28 | write.get("/:id", getEmailById); 29 | 30 | // DELETE an email 31 | write.delete("/:email", removeEmail); 32 | 33 | // DELETE an email by id 34 | write.delete("/:id", removeEmailById); 35 | 36 | module.exports = { 37 | read, 38 | write, 39 | }; 40 | -------------------------------------------------------------------------------- /client/src/pages/Home.js: -------------------------------------------------------------------------------- 1 | import About from '../components/landing/About' 2 | import CTA from '../components/landing/CTA' 3 | import Hero from '../components/landing/Hero' 4 | import SlidingImages from '../components/landing/Marquee' 5 | import Offerings from '../components/landing/Offerings' 6 | import People from '../components/landing/People' 7 | import Testimonies from '../components/landing/Testimony' 8 | 9 | function Home() { 10 | return ( 11 | <> 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | ) 23 | } 24 | 25 | export default Home 26 | -------------------------------------------------------------------------------- /client/src/context/EarlyAccessContext.js: -------------------------------------------------------------------------------- 1 | import { createContext, useEffect, useState } from 'react' 2 | import Cookies from 'js-cookie' 3 | 4 | export const EarlyAccessContext = createContext() 5 | 6 | export const EarlyAccessContextProvider = ({ children }) => { 7 | const [earlyAccess, setEarlyAccess] = useState(false) 8 | 9 | useEffect(() => { 10 | // check if user originally had early access 11 | const access = Cookies.get('earlyAccess') 12 | if (access === 'true') { 13 | setEarlyAccess(true) 14 | } 15 | }, []) 16 | 17 | const setAccess = (access) => { 18 | setEarlyAccess(access) 19 | Cookies.set('earlyAccess', access.toString()) 20 | } 21 | 22 | return ( 23 | 24 | {children} 25 | 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /client/src/util/tokenUtils.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | import { HOST } from './apiRoutes' 4 | 5 | export const generateToken = async () => { 6 | const linkedinToken = localStorage.getItem('linkedinToken') 7 | const adminToken = localStorage.getItem('adminToken') 8 | 9 | // Use fetch to get a new session ID if one does not already exist 10 | try { 11 | const url = `${HOST}/api/token${linkedinToken ? `?linkedinToken=${linkedinToken}` : ''}${adminToken ? `&adminToken=${adminToken}` : ''}` 12 | const response = await fetch(url) 13 | 14 | if (!response.ok) { 15 | throw new Error('Network response was not ok') 16 | } 17 | 18 | const data = await response.json() 19 | Cookies.set('token', data) // Store the session ID 20 | return data 21 | } catch (error) { 22 | console.error('Error:', error) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /server/controllers/adminController.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | const Admin = require("../models/adminModel"); 4 | const { verifyAdminToken } = require("../middleware/admin"); 5 | 6 | const createToken = (_id) => { 7 | return jwt.sign({ _id }, process.env.JWT_SECRET, { expiresIn: "3d" }); 8 | }; 9 | 10 | const verifyToken = async (req, res) => { 11 | const { token } = req.body; 12 | 13 | const isAdmin = await verifyAdminToken(token); 14 | 15 | res.status(200).json({ isAdmin }); 16 | }; 17 | 18 | const loginAdmin = async (req, res) => { 19 | const { email, password } = req.body; 20 | 21 | try { 22 | const admin = await Admin.login(email, password); 23 | 24 | // create token 25 | const token = createToken(admin._id); 26 | 27 | res.status(200).json({ _id: admin._id, token }); 28 | } catch (error) { 29 | res.status(400).json({ error: error.message }); 30 | } 31 | }; 32 | 33 | module.exports = { 34 | loginAdmin, 35 | verifyToken, 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Aidan O., Arthur P., Lewin B., and Tom N. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /client/src/pages/(admin)/Admin.js: -------------------------------------------------------------------------------- 1 | import { Routes, Route } from 'react-router-dom' 2 | import AdminLogin from './AdminLogin' 3 | import AdminDashboard from './AdminDashboard' 4 | 5 | import { useAdmin } from '../../hooks/useAdminContext' 6 | 7 | import { error404 } from '../../components/Error404' 8 | 9 | const Admin = () => { 10 | const { admin } = useAdmin() 11 | 12 | return ( 13 | 14 | } /> 15 | { 16 | 21 | ) : ( 22 | error404( 23 | 'You do not have permission to view this page.' 24 | ) 25 | ) 26 | } 27 | /> 28 | // Add more admin routes here 29 | } 30 | 31 | ) 32 | } 33 | 34 | export default Admin 35 | -------------------------------------------------------------------------------- /server/models/profileModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const random = require("mongoose-simple-random"); 3 | const Experience = require("./experienceModel"); // Import the Experience model 4 | const Offer = require("./offerModel"); // Import the Offer model 5 | 6 | const Schema = mongoose.Schema; 7 | 8 | const profileSchema = new Schema( 9 | { 10 | userId: String, 11 | firstName: String, 12 | lastName: String, 13 | username: String, 14 | linkedin: String, 15 | pfp: String, 16 | position: String, 17 | location: String, 18 | anonymous: Boolean, 19 | school: String, 20 | pipeline: [Experience.schema], 21 | offers: [Offer.schema], 22 | created: Boolean, 23 | }, 24 | { timestamps: true } 25 | ); 26 | profileSchema.plugin(random); 27 | 28 | // static methods 29 | profileSchema.statics.getByUserId = async function (userId) { 30 | const profile = await this.findOne({ userId }); 31 | 32 | if (!profile) { 33 | throw Error(`Invalid user ID.`); 34 | } 35 | 36 | return profile; 37 | }; 38 | 39 | module.exports = mongoose.model("Profile", profileSchema); 40 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js", 9 | "dev": "nodemon index.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@aws-sdk/client-s3": "^3.485.0", 15 | "@aws-sdk/s3-request-presigner": "^3.485.0", 16 | "aws-sdk": "^2.1533.0", 17 | "axios": "^1.6.5", 18 | "bcrypt": "^5.1.1", 19 | "body-parser": "^1.20.2", 20 | "cors": "^2.8.5", 21 | "crypto": "^1.0.1", 22 | "dotenv": "^16.3.1", 23 | "express": "^4.18.2", 24 | "jsonwebtoken": "^9.0.2", 25 | "math": "^0.0.3", 26 | "mathjs": "^12.4.1", 27 | "mongoose": "^8.0.3", 28 | "mongoose-simple-random": "^0.4.1", 29 | "multer": "^1.4.5-lts.1", 30 | "querystring": "^0.2.1", 31 | "resend": "^3.2.0", 32 | "uuid": "^9.0.1", 33 | "validator": "^13.11.0" 34 | }, 35 | "devDependencies": { 36 | "jest": "^29.7.0", 37 | "nodemon": "^3.0.3", 38 | "supertest": "^6.3.4" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/src/hooks/usePatchJson.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import Cookies from 'js-cookie' 3 | 4 | const usePatchJson = async (url, dataToUpdate) => { 5 | // State to manage response data 6 | const [responseData, setResponseData] = useState(null) 7 | // State to manage loading state 8 | const [loading, setLoading] = useState(true) 9 | // State to manage error state 10 | const [error, setError] = useState(null) 11 | 12 | try { 13 | const response = await fetch(url, { 14 | method: 'PATCH', 15 | headers: { 16 | 'Content-Type': 'application/json', 17 | Authorization: `Bearer ${Cookies.get('sessionId')}`, 18 | }, 19 | body: JSON.stringify(dataToUpdate), // Assuming you have data to update 20 | }) 21 | 22 | if (!response.ok) { 23 | throw new Error(`Failed to update data. Status: ${response.status}`) 24 | } 25 | 26 | const result = await response.json() 27 | setResponseData(result) 28 | } catch (error) { 29 | setError(error.message) 30 | } finally { 31 | setLoading(false) 32 | } 33 | 34 | // Return the state values 35 | return { responseData, loading, error } 36 | } 37 | 38 | export default usePatchJson 39 | -------------------------------------------------------------------------------- /client/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './src/**/*.{js,jsx,ts,tsx}', 5 | './node_modules/tailwind-datepicker-react/dist/**/*.js', 6 | ], 7 | theme: { 8 | extend: { 9 | colors: { 10 | 'pipelines-gray-100': '#F7F7F7', 11 | 'pipelines-gray-500': '#444444', 12 | 'pipeline-blue-200': '#0265AC', 13 | }, 14 | animation: { 15 | 'infinite-scroll': 'infinite-scroll 265s linear infinite', 16 | blob: 'blob 7s infinite', 17 | }, 18 | keyframes: { 19 | 'infinite-scroll': { 20 | from: { transform: 'translateX(0)' }, 21 | to: { transform: 'translateX(-180%)' }, 22 | }, 23 | blob: { 24 | '0%': { 25 | transform: 'translate(0px, 0px) scale(1)', 26 | }, 27 | '50%': { 28 | transform: 'translate(0px, -5px) scale(1.2)', 29 | }, 30 | '100%': { 31 | transform: 'translate(0px, 0px) scale(1)', 32 | }, 33 | }, 34 | }, 35 | }, 36 | }, 37 | plugins: [require('daisyui'), require('flowbite/plugin')], 38 | } 39 | -------------------------------------------------------------------------------- /server/routes/companies.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const bodyParser = require("body-parser"); 3 | const { 4 | createCompany, 5 | getCompany, 6 | getCompanyByName, 7 | getCompanies, 8 | getEmployees, 9 | updateCompany, 10 | updateCompanies, 11 | deleteCompany, 12 | } = require("../controllers/companyController"); 13 | 14 | const read = express.Router(); 15 | const write = express.Router(); 16 | 17 | //read a specific company 18 | write.post("/create", bodyParser.json(), createCompany); 19 | 20 | //get a specific company 21 | read.get("/get/:id", getCompany); 22 | 23 | // get a specific company by name 24 | read.get("/getBy", getCompanyByName); 25 | 26 | //get multiple companies based on a query 27 | read.get("/get/companies/:query", getCompanies); 28 | 29 | // get profiles of employees that work at company 30 | read.get("/employees/:id", getEmployees); 31 | 32 | //Update a specific company 33 | // ! TEMP READ COMMAND 34 | // TODO: change up backend to remove client changing of companies 35 | read.patch("/update/:id", bodyParser.json(), updateCompany); 36 | 37 | //Update a specific company 38 | // ! TEMP READ COMMAND 39 | // TODO: change up backend to remove client changing of companies 40 | read.patch("/update", bodyParser.json(), updateCompanies); 41 | 42 | //Delete a specific company 43 | write.delete("/delete/:id", deleteCompany); 44 | 45 | module.exports = { 46 | read, 47 | write, 48 | }; 49 | -------------------------------------------------------------------------------- /server/middleware/token.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | const generateToken = (sessionId, linkedinToken, adminToken) => { 4 | // Create payload object with sessionId 5 | const payload = { id: sessionId }; 6 | 7 | // If linkedinToken exists, include it in the payload 8 | if (linkedinToken) { 9 | payload.linkedinToken = linkedinToken; 10 | } 11 | 12 | // If adminToken exists, include it in the payload 13 | if (adminToken) { 14 | payload.adminToken = adminToken; 15 | } 16 | 17 | // Generate token with payload 18 | const token = jwt.sign(payload, process.env.JWT_SECRET, { 19 | expiresIn: "1d", 20 | }); 21 | 22 | return token; 23 | }; 24 | 25 | const verifyToken = (req, res, next) => { 26 | const authHeader = req.headers.authorization; 27 | 28 | if (!authHeader) { 29 | return res.status(401).json({ msg: "No authorization token provided." }); 30 | } 31 | 32 | const tokenParts = authHeader.split(" "); 33 | if (tokenParts.length !== 2 || tokenParts[0] !== "Bearer") { 34 | return res.status(401).json({ msg: "Token format is 'Bearer '." }); 35 | } 36 | 37 | const token = tokenParts[1]; 38 | 39 | try { 40 | jwt.verify(token, process.env.JWT_SECRET); 41 | next(); 42 | } catch (err) { 43 | console.error(err); 44 | return res.status(401).json({ msg: "Invalid or expired token." }); 45 | } 46 | }; 47 | 48 | module.exports = { 49 | generateToken, 50 | verifyToken, 51 | }; 52 | -------------------------------------------------------------------------------- /client/src/components/ProfilePicture.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import { useParams } from 'react-router-dom' 3 | 4 | import { HOST } from '../util/apiRoutes' 5 | import { fetchWithAuth } from '../util/fetchUtils' 6 | 7 | export const ProfilePicture = ({ profile, setPfp }) => { 8 | const { id } = useParams() 9 | 10 | const [fetchedPfp, setFetchedPfp] = useState(null) 11 | 12 | const fetchPfp = async () => { 13 | try { 14 | const data = await fetchWithAuth({ 15 | url: `${HOST}/api/pfp/${id}`, 16 | method: 'GET', 17 | }) 18 | 19 | setPfp(data.pfp) 20 | setFetchedPfp(data.pfp) 21 | } catch (error) { 22 | console.error(error.message) 23 | setPfp(null) 24 | } 25 | } 26 | 27 | useEffect(() => { 28 | const fetchInfo = async () => { 29 | await fetchPfp() 30 | } 31 | 32 | fetchInfo() 33 | }, []) 34 | 35 | const src = fetchedPfp || '/avatar.png' 36 | 37 | return ( 38 | <> 39 |
40 | {`${profile._id}_avatar`} 45 |
46 | 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /client/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true // hm...https://github.com/facebook/create-react-app/issues/12212 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:react/recommended", 10 | "plugin:prettier/recommended" 11 | ], 12 | "parserOptions": { 13 | "ecmaVersion": "latest", 14 | "sourceType": "module", 15 | "ecmaFeatures": { 16 | "jsx": true 17 | } 18 | }, 19 | "plugins": ["react"], 20 | "rules": { 21 | "react/react-in-jsx-scope": "off", 22 | "react/jsx-uses-react": "off", 23 | "react/prop-types": 0, 24 | "no-prototype-builtins": "off", 25 | "prettier/prettier": [ 26 | "error", 27 | { 28 | "endOfLine": "auto" 29 | } 30 | ], 31 | "eqeqeq": ["error", "always"], 32 | "no-eval": "error", 33 | "no-implied-eval": "error", 34 | "no-return-await": "error", 35 | "no-self-compare": "error", 36 | "no-throw-literal": "error", 37 | "no-unused-expressions": [ 38 | "error", 39 | { "allowShortCircuit": true, "allowTernary": true } 40 | ], 41 | "no-useless-return": "error", 42 | "no-void": "error", 43 | "wrap-iife": ["error", "any"] 44 | }, 45 | "settings": { 46 | "react": { 47 | "version": "detect" 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /client/src/context/AdminContext.js: -------------------------------------------------------------------------------- 1 | import { createContext, useReducer, useEffect } from 'react' 2 | 3 | import { fetchWithAuth } from '../util/fetchUtils' 4 | import { HOST } from '../util/apiRoutes' 5 | 6 | export const AdminContext = createContext() 7 | 8 | export const adminReducer = (state, action) => { 9 | switch (action.type) { 10 | case 'SET_ADMIN': 11 | return { admin: action.payload } // action.payload should be a boolean value 12 | default: 13 | return state 14 | } 15 | } 16 | 17 | const verifyToken = async (token) => { 18 | try { 19 | const { isAdmin } = await fetchWithAuth({ 20 | url: `${HOST}/api/admin/verify`, 21 | method: 'POST', 22 | data: { token }, 23 | }) 24 | return isAdmin 25 | } catch (error) { 26 | console.error('Error verifying token:', error) 27 | return false 28 | } 29 | } 30 | 31 | export const AdminContextProvider = ({ children }) => { 32 | const [state, dispatch] = useReducer(adminReducer, { 33 | admin: false, // Default to null 34 | }) 35 | 36 | useEffect(() => { 37 | const token = localStorage.getItem('adminToken') 38 | if (token) { 39 | verifyToken(token).then((isValidToken) => { 40 | dispatch({ type: 'SET_ADMIN', payload: isValidToken }) 41 | }) 42 | } 43 | }, []) 44 | 45 | return ( 46 | 47 | {children} 48 | 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /client/src/components/landing/Hero.js: -------------------------------------------------------------------------------- 1 | import CTAButton from './CTAButton' 2 | 3 | export default function Hero() { 4 | return ( 5 |
15 |
16 |

17 | Visualize Tech
18 | 19 | Career Pipelines
20 |
21 | With Ease 22 |

23 | 24 |

25 | Track, visualize, and explore your career journey. From top 26 | tech giants to small startups, discover career path insights 27 | effortlessly. 28 |

29 | 30 |
31 |
32 | ) 33 | } 34 | -------------------------------------------------------------------------------- /client/src/components/landing/CTAButton.js: -------------------------------------------------------------------------------- 1 | import { useNavigate } from 'react-router-dom' 2 | export default function CTAButton({ text, to, href }) { 3 | const navigate = useNavigate() 4 | if (href) { 5 | return ( 6 | <> 7 | 11 | 12 | 13 | {text} 14 | 15 | 16 | ) 17 | } 18 | 19 | return ( 20 | <> 21 | navigate(to)} 23 | className="group relative z-0 mt-6 inline-flex cursor-pointer items-center justify-center overflow-hidden rounded-lg bg-pipelines-gray-100 px-10 py-2 font-medium tracking-tighter text-black/80 hover:text-white" 24 | > 25 | 26 | 27 | {text} 28 | 29 | 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /server/models/adminModel.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const bcrypt = require("bcrypt"); 3 | const validator = require("validator"); 4 | 5 | const Schema = mongoose.Schema; 6 | 7 | const adminSchema = new Schema( 8 | { 9 | email: { 10 | type: String, 11 | unique: true, 12 | required: true, 13 | }, 14 | password: { 15 | type: String, 16 | required: true, 17 | }, 18 | }, 19 | { timestamps: true } 20 | ); 21 | 22 | adminSchema.statics.signup = async function (email, password) { 23 | // validation 24 | if (!email || !password) { 25 | throw Error(`All fields must be filled.`); 26 | } 27 | if (!validator.isEmail(email)) { 28 | throw Error(`Email is invalid.`); 29 | } 30 | 31 | // Enable when strong passwords are needed. 32 | // if (!validator.isStrongPassword(password)) { 33 | // throw Error(`Password is not strong enough.`) 34 | // } 35 | 36 | const exists = await this.findOne({ email }); 37 | 38 | if (exists) { 39 | throw Error(`Email already in use.`); 40 | } 41 | 42 | const salt = await bcrypt.genSalt(10); 43 | const hash = await bcrypt.hash(password, salt); 44 | 45 | const admin = await this.create({ email, password: hash }); 46 | 47 | return admin; 48 | }; 49 | 50 | adminSchema.statics.login = async function (email, password) { 51 | // validation 52 | if (!email) { 53 | throw new Error("Email is required."); 54 | } 55 | 56 | let admin = await this.findOne({ email }); 57 | 58 | if (!admin) { 59 | throw new Error("Invalid email."); 60 | } 61 | 62 | const match = await bcrypt.compare(password, admin.password); 63 | 64 | if (!match) { 65 | throw new Error(`Incorrect password.`); 66 | } 67 | 68 | return admin; 69 | }; 70 | 71 | module.exports = mongoose.model("Admin", adminSchema); 72 | -------------------------------------------------------------------------------- /server/middleware/admin.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | const Admin = require("../models/adminModel"); 4 | 5 | const verifyAdminToken = async (token) => { 6 | try { 7 | // Get decoded token 8 | const decodedToken = jwt.verify(token, process.env.JWT_SECRET); 9 | 10 | // Extract the id from the decoded token 11 | const { _id } = decodedToken; 12 | 13 | // Check if an admin account exists with the provided _id 14 | const admin = await Admin.findById(_id); 15 | 16 | // Return true if an admin account exists, false otherwise 17 | return admin ? true : false; 18 | } catch (err) { 19 | console.error(err); 20 | return false; 21 | } 22 | }; 23 | 24 | const verifyAdmin = async (req, res, next) => { 25 | // Log the requested URL 26 | console.log("Requested URL:", req.originalUrl); 27 | 28 | const authHeader = req.headers.authorization; 29 | 30 | if (!authHeader) { 31 | return res.status(401).json({ msg: "No authorization token provided." }); 32 | } 33 | 34 | const tokenParts = authHeader.split(" "); 35 | if (tokenParts.length !== 2 || tokenParts[0] !== "Bearer") { 36 | return res.status(401).json({ msg: "Token format is 'Bearer '." }); 37 | } 38 | 39 | // extract admin token from MOTHER token 40 | const token = tokenParts[1]; 41 | 42 | // try to get an admin token 43 | try { 44 | const decodedToken = jwt.verify(token, process.env.JWT_SECRET); 45 | const adminToken = decodedToken.adminToken; 46 | 47 | // Verify the token has admin privileges 48 | if (!adminToken || !(await verifyAdminToken(adminToken))) { 49 | throw new Error("Invalid admin token."); 50 | } 51 | } catch (err) { 52 | console.log(err); 53 | return res.status(403).json({ 54 | msg: "User does not have the required privileges for this request.", 55 | }); 56 | } 57 | 58 | next(); 59 | }; 60 | 61 | module.exports = { 62 | verifyAdminToken, 63 | verifyAdmin, 64 | }; 65 | -------------------------------------------------------------------------------- /client/src/components/Error404.js: -------------------------------------------------------------------------------- 1 | import { useNavigate } from 'react-router-dom' 2 | import { HOMEPAGE } from '../util/apiRoutes' 3 | 4 | export const error404 = (error_text) => { 5 | const navigate = useNavigate() 6 | return ( 7 |
15 |
16 | 17 |
18 |
19 |
20 |
21 |

22 | 404 Error 23 |

24 |

25 | {error_text} 26 |

27 |

28 | Sorry about that! Please visit our homepage to get 29 | where you need to go. 30 |

31 | 39 |
40 |
41 |
42 |
43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /client/src/data/index.js: -------------------------------------------------------------------------------- 1 | const mockPipelineData = [ 2 | { 3 | _id: '1', 4 | profileId: 'profile1', 5 | firstName: 'John', 6 | lastName: 'Doe', 7 | pfp: 'https://placekitten.com/200/300', 8 | anonymous: false, 9 | pipeline: [ 10 | { 11 | _id: 'exp1', 12 | company: 'Amazon', 13 | title: 'Software Engineer', 14 | date: 'Jan 2022 - Present', 15 | }, 16 | ], 17 | }, 18 | { 19 | _id: '2', 20 | profileId: 'profile2', 21 | firstName: 'Jane', 22 | lastName: 'Smith', 23 | pfp: 'https://placekitten.com/200/300', 24 | anonymous: true, 25 | pipeline: [ 26 | { 27 | _id: 'exp2', 28 | company: 'Apple', 29 | title: 'Product Manager', 30 | date: 'Mar 2020 - Dec 2021', 31 | }, 32 | ], 33 | }, 34 | { 35 | _id: '3', 36 | profileId: 'profile3', 37 | firstName: 'Alice', 38 | lastName: 'Johnson', 39 | pfp: 'https://placekitten.com/200/300', 40 | anonymous: false, 41 | pipeline: [ 42 | { 43 | _id: 'exp3', 44 | company: 'Google', 45 | title: 'UX Designer', 46 | date: 'Jul 2019 - Feb 2021', 47 | }, 48 | ], 49 | }, 50 | { 51 | id: '4', 52 | profileId: 'profile4', 53 | firstName: 'Bob', 54 | lastName: 'Williams', 55 | pfp: 'https://placekitten.com/200/300', 56 | anonymous: true, 57 | pipeline: [ 58 | { 59 | _id: 'exp4', 60 | company: 'Jane Street', 61 | title: 'Software Engineer', 62 | date: 'Jan 2018 - Jun 2019', 63 | }, 64 | ], 65 | }, 66 | ] 67 | 68 | export default mockPipelineData 69 | -------------------------------------------------------------------------------- /client/src/context/AuthContext.js: -------------------------------------------------------------------------------- 1 | import { createContext, useReducer, useEffect } from 'react' 2 | import Cookies from 'js-cookie' 3 | 4 | import { fetchWithAuth } from '../util/fetchUtils' 5 | import { HOST } from '../util/apiRoutes' 6 | 7 | export const AuthContext = createContext() 8 | 9 | export const authReducer = (state, action) => { 10 | switch (action.type) { 11 | case 'LOGIN': 12 | return { user: action.payload } 13 | case 'LOGOUT': 14 | return { user: null } 15 | case 'CREATED': 16 | return { user: { ...state.user, profileCreated: true } } 17 | default: 18 | return state 19 | } 20 | } 21 | 22 | const verifyToken = async (email, token) => { 23 | try { 24 | const { isVerified } = await fetchWithAuth({ 25 | url: `${HOST}/api/user/verify`, 26 | method: 'POST', 27 | data: { email, token }, 28 | }) 29 | return isVerified 30 | } catch (error) { 31 | console.error('Error verifying token:', error) 32 | return false 33 | } 34 | } 35 | 36 | export const AuthContextProvider = ({ children }) => { 37 | const [state, dispatch] = useReducer(authReducer, { 38 | user: null, 39 | }) 40 | 41 | useEffect(() => { 42 | const user = JSON.parse(localStorage.getItem('user')) 43 | const token = Cookies.get('token') 44 | 45 | if (user && token) { 46 | verifyToken(user.email, token).then((isValidToken) => { 47 | if (isValidToken) { 48 | dispatch({ type: 'LOGIN', payload: user }) 49 | 50 | if (user.profileCreated) { 51 | dispatch({ type: 'CREATED', payload: user }) 52 | } 53 | } 54 | }) 55 | } 56 | }, []) 57 | 58 | return ( 59 | 60 | {children} 61 | 62 | ) 63 | } 64 | -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Pipelines.lol - Find Your Next Company 13 | 14 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /server/middleware/user.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const jwt = require("jsonwebtoken"); 3 | 4 | const getEmailFromToken = async (token) => { 5 | try { 6 | // decode mother jwt 7 | const decodedToken = jwt.verify(token, process.env.JWT_SECRET); 8 | 9 | // extract linkedin token from mother jwt 10 | const linkedinToken = decodedToken.linkedinToken; 11 | 12 | // this request gets basic profile info from linkedin token 13 | const { data } = await axios.get("https://api.linkedin.com/v2/userinfo", { 14 | headers: { 15 | Authorization: `Bearer ${linkedinToken}`, 16 | }, 17 | }); 18 | 19 | // get the email from linkedin data 20 | return data.email; 21 | } catch (err) { 22 | console.error(err); 23 | return null; 24 | } 25 | }; 26 | 27 | const verifyUser = async (req, res, next) => { 28 | const { email } = req.body; 29 | 30 | // Log the requested URL 31 | console.log("Requested URL:", req.originalUrl); 32 | 33 | // verify token has linkedin token with 34 | // requested user's email 35 | const authHeader = req.headers.authorization; 36 | 37 | if (!authHeader) { 38 | return res.status(401).json({ msg: "No authorization token provided." }); 39 | } 40 | 41 | const tokenParts = authHeader.split(" "); 42 | if (tokenParts.length !== 2 || tokenParts[0] !== "Bearer") { 43 | return res.status(401).json({ msg: "Token format is 'Bearer '." }); 44 | } 45 | 46 | const token = tokenParts[1]; 47 | 48 | try { 49 | const emailFromToken = await getEmailFromToken(token); 50 | 51 | if (!emailFromToken) { 52 | throw new Error("Invalid token."); 53 | } 54 | 55 | // compare emails and break out if they dont match 56 | if (email !== emailFromToken) { 57 | return res.status(403).json({ 58 | msg: "Invalid Linkedin token for user login.", 59 | }); 60 | } 61 | } catch (err) { 62 | return res.status(401).json({ msg: "Invalid or expired Linkedin token." }); 63 | } 64 | 65 | next(); 66 | }; 67 | 68 | module.exports = { 69 | verifyUser, 70 | getEmailFromToken, 71 | }; 72 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .App { 6 | text-align: center; 7 | } 8 | 9 | .App-logo { 10 | height: 40vmin; 11 | pointer-events: none; 12 | } 13 | 14 | @media (prefers-reduced-motion: no-preference) { 15 | .App-logo { 16 | animation: App-logo-spin infinite 20s linear; 17 | } 18 | } 19 | 20 | .App-header { 21 | background-color: #282c34; 22 | min-height: 100vh; 23 | display: flex; 24 | flex-direction: column; 25 | align-items: center; 26 | justify-content: center; 27 | font-size: calc(10px + 2vmin); 28 | color: white; 29 | } 30 | 31 | .App-link { 32 | color: #61dafb; 33 | } 34 | 35 | @keyframes App-logo-spin { 36 | from { 37 | transform: rotate(0deg); 38 | } 39 | to { 40 | transform: rotate(360deg); 41 | } 42 | } 43 | .underline-hover { 44 | position: relative; 45 | text-decoration: none; 46 | color: white; 47 | font-weight: light; 48 | text-transform: uppercase; 49 | transition: color 0.3s ease-in-out; 50 | } 51 | 52 | .underline-hover:hover, 53 | .underline-hover.active { 54 | color: #0265ac; 55 | } 56 | 57 | .highlight { 58 | color: #0265ac; 59 | } 60 | 61 | .underline-hover span { 62 | position: absolute; 63 | bottom: 0; 64 | left: 50%; 65 | transform: translateX(-50%); 66 | width: 0; 67 | height: 1px; 68 | background-color: white; 69 | transition: all 0.3s ease-in-out; 70 | } 71 | 72 | .underline-hover:hover span, 73 | .underline-hover.active span { 74 | width: 60%; 75 | } 76 | 77 | .underline-force { 78 | position: relative; 79 | text-decoration: none; 80 | font-weight: light; 81 | text-transform: uppercase; 82 | } 83 | 84 | .underline-force span { 85 | position: absolute; 86 | bottom: 0; 87 | left: 50%; 88 | transform: translateX(-50%); 89 | width: 0; 90 | height: 1px; 91 | background-color: white; 92 | transition: all 0.3s ease-in-out; 93 | } 94 | 95 | .underline-force span, 96 | .underline-force.active span { 97 | width: 60%; 98 | } 99 | -------------------------------------------------------------------------------- /server/app.test.js: -------------------------------------------------------------------------------- 1 | const request = require("supertest"); 2 | const router = require("./routes/companies"); 3 | const Company = require("./models/companyModel"); 4 | const mongoose = require("mongoose"); 5 | const server = require("./index"); 6 | const app = require("./index"); 7 | 8 | const api = request(router); 9 | 10 | describe("Company tests", () => { 11 | describe("POST calls", () => { 12 | test("create-company", async () => { 13 | //build a new item 14 | const newCompany = { name: "TestCompany" }; 15 | const response = await api.post("/create").send(newCompany); 16 | 17 | const companies = await Company.find({}); 18 | 19 | expect(companies[companies.length - 1].name).toBe("TestCompany"); 20 | }); 21 | 22 | test("update-company", async () => { 23 | const name = "TestCompany"; 24 | const newCompany = { 25 | rating: 5, 26 | }; 27 | 28 | const response = await api.put(`/update/${name}`).send(newCompany); 29 | expect(response.ok).toBeTruthy(); 30 | }); 31 | 32 | test("delete-company", async () => { 33 | const name = "TestCompany"; 34 | const response = await api.delete(`/delete/${name}`); 35 | }); 36 | }); 37 | 38 | describe("GET calls", () => { 39 | test("get-company", async () => { 40 | const name = "TestCompany"; 41 | const response = await api.get(`/get/${name}`); 42 | 43 | // Check if the response status is okay (status code 200-299) 44 | expect(response.ok).toBeTruthy(); 45 | 46 | // Parse the JSON in the response 47 | const jsonData = await response.body; 48 | 49 | // Now you can assert or perform further checks on the extracted JSON data 50 | expect(jsonData).toHaveProperty("name"); 51 | expect(jsonData.name).toBe("TestCompany"); 52 | // Add more assertions based on your JSON structure 53 | }); 54 | }); 55 | }); 56 | 57 | describe("User tests", () => { 58 | test("create-profile", async () => { 59 | c; 60 | }); 61 | }); 62 | 63 | afterAll((done) => { 64 | // Closing the DB connection allows Jest to exit successfully. 65 | mongoose.connection.close(); 66 | done(); 67 | }); 68 | -------------------------------------------------------------------------------- /server/controllers/imageModerationController.js: -------------------------------------------------------------------------------- 1 | const aws = require('aws-sdk'); 2 | 3 | // Configure AWS SDK with your credentials and region 4 | aws.config.update({ 5 | accessKeyId: process.env.AWS_ACCESS_KEY_ID, 6 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 7 | region: process.env.BUCKET_REGION, 8 | }); 9 | 10 | // Create an instance of Rekognition 11 | const rekognition = new aws.Rekognition(); 12 | 13 | const recognizeImage = async (req, res) => { 14 | try { 15 | // if there is no file, then no changes will be made 16 | if (!req.file) { 17 | return res.status(200).json(profile); 18 | } 19 | let { buffer } = req.file 20 | 21 | // Perform Rekognition operation 22 | const moderationResult = await moderateImage(buffer); 23 | 24 | // Send the result back to the client 25 | res.json({ moderationResult }); 26 | } catch (error) { 27 | console.error(error); 28 | res.status(500).json({ error: 'Internal Server Error' }); 29 | } 30 | } 31 | 32 | async function moderateImage(binaryData) { 33 | const params = { 34 | Image: { 35 | Bytes: binaryData, 36 | }, 37 | MinConfidence: 70, 38 | }; 39 | 40 | try { 41 | const { ModerationLabels } = await rekognition.detectModerationLabels(params).promise(); 42 | 43 | // If no labels found -> image doesn't contain any forbidden content 44 | if (!ModerationLabels || ModerationLabels.length === 0) { 45 | return []; 46 | } 47 | 48 | // If some labels found -> compare them with forbidden labels 49 | const forbiddenLabels = ['Explicit Nudity', 'Violence', 'Visually Disturbing', 'Rude Gestures', 'Tobacco', 'Gambling', 'Hate Symbols']; 50 | const labels = ModerationLabels.map((label) => label.ParentName).filter(Boolean); 51 | const foundForbiddenLabels = labels.filter((label) => forbiddenLabels.includes(label)); 52 | 53 | return foundForbiddenLabels; 54 | } catch (error) { 55 | console.error(`Error in image moderation: ${error}`); 56 | throw error; 57 | } 58 | } 59 | 60 | module.exports = { 61 | recognizeImage 62 | } 63 | -------------------------------------------------------------------------------- /client/src/pages/(admin)/AdminDashboard.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | // dashboards 4 | import { CompanyPage } from './pages/CompanyDashboard' 5 | import { EmailPage } from './pages/EmailDashboard' 6 | 7 | function AdminDashboard() { 8 | const [page, setPage] = useState('company') 9 | 10 | return ( 11 |
22 | {/* Sidenav */} 23 |
24 |
25 |

Admin Dashboard

26 |
27 |
    28 | 31 | 34 | {/* Add more navigation links here */} 35 |
36 |
37 | 38 | {/* Main Dashboard Content */} 39 |
46 | {page === 'company' ? ( 47 | 48 | ) : page === 'email' ? ( 49 | 50 | ) : ( 51 | <> 52 | )} 53 |
54 |
55 | ) 56 | } 57 | 58 | export default AdminDashboard 59 | -------------------------------------------------------------------------------- /client/src/util/fetchUtils.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | import { generateToken } from './tokenUtils' 4 | 5 | export const fetchWithAuth = async ({ 6 | url, 7 | method, 8 | data = {}, 9 | headers = {}, 10 | retry = false, 11 | }) => { 12 | // Default headers including Authorization 13 | const defaultHeaders = { 14 | 'Content-Type': 'application/json', 15 | Authorization: `Bearer ${Cookies.get('token')}`, 16 | } 17 | 18 | // Combine default headers with any custom headers passed in 19 | const combinedHeaders = { ...defaultHeaders, ...headers } 20 | 21 | const fetchOptions = { 22 | method: method, 23 | headers: combinedHeaders, 24 | } 25 | 26 | if (data && Object.keys(data).length) { 27 | fetchOptions.body = JSON.stringify(data) 28 | } 29 | 30 | try { 31 | const response = await fetch(url, fetchOptions) 32 | 33 | // if this is the first catch at an unauthorized call 34 | // try and regenerate the token 35 | if (!retry && response.status === 401) { 36 | // Invalid token, regenerate it and retry the request 37 | const newToken = await generateToken() 38 | combinedHeaders.Authorization = `Bearer ${newToken}` 39 | 40 | // Retry the request with the new token 41 | return fetchWithAuth({ 42 | url, 43 | method, 44 | data, 45 | headers: combinedHeaders, 46 | retry: true, 47 | }) 48 | } 49 | 50 | if (!response.ok) { 51 | const errorMessage = await getErrorMessage(response) 52 | throw new Error(errorMessage) 53 | } 54 | 55 | return response.json() 56 | } catch (error) { 57 | throw new Error( 58 | error.message || 'An error occurred during the fetch operation.' 59 | ) 60 | } 61 | } 62 | 63 | async function getErrorMessage(response) { 64 | try { 65 | const error = await response.json() 66 | return ( 67 | error.error || 68 | error.message || 69 | error.msg || 70 | `Error occurred with response ${error.response}` 71 | ) 72 | } catch (err) { 73 | return `Error occurred with response ${response.status} ${response.statusText}` 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /client/src/components/CompanyCard.js: -------------------------------------------------------------------------------- 1 | // assets 2 | import BigSmiley from '../static/ratings/BigSmiley.png' 3 | import smiley from '../static/ratings/smiley.png' 4 | import neutral from '../static/ratings/neutral.png' 5 | import frown from '../static/ratings/frown.png' 6 | import demon from '../static/ratings/demon.png' 7 | 8 | export const CompanyCard = ({ company }) => { 9 | const options = [demon, frown, neutral, smiley, BigSmiley] 10 | 11 | return ( 12 |
13 |
14 | 18 |
19 |

20 | {company.name} 21 |

22 |
23 |
24 |
25 |

{company.info}

26 | {company.rating !== null ? ( 27 |
28 |

29 | Rating: 30 |

31 |
35 |
36 | rating 40 |
41 |
42 |
43 | ) : ( 44 |
45 | )} 46 |
47 |
48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /client/public/logos/Yelp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 13 | 17 | 21 | 25 | 26 | -------------------------------------------------------------------------------- /server/middleware/profile.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | const jwt = require("jsonwebtoken"); 3 | const Profile = require("../models/profileModel"); 4 | const User = require("../models/userModel"); 5 | 6 | const getProfileIdFromToken = async (token) => { 7 | try { 8 | // get decoded token 9 | const decodedToken = jwt.verify(token, process.env.JWT_SECRET); 10 | 11 | // extract linkedin token and use this as user identifier 12 | const linkedinToken = decodedToken.linkedinToken; 13 | 14 | // this request gets basic profile info from linkedin token 15 | const { data } = await axios.get("https://api.linkedin.com/v2/userinfo", { 16 | headers: { 17 | Authorization: `Bearer ${linkedinToken}`, 18 | }, 19 | }); 20 | const email = data.email; 21 | 22 | // Query MongoDB model to find user with matching email 23 | const user = await User.findOne({ email: email }); 24 | if (!user) { 25 | throw Error(`User not found: ${email}`); 26 | } 27 | 28 | // Find profile using user's _id 29 | const profile = await Profile.findOne({ userId: user._id }); 30 | if (!profile) { 31 | throw Error(`Profile not found for user: ${user._id}`); 32 | } 33 | 34 | // extract id from profile object 35 | const profileId = profile._id.toString(); 36 | 37 | // return profile id 38 | return profileId; 39 | } catch (err) { 40 | console.error(err); 41 | return null; 42 | } 43 | }; 44 | 45 | const verifyProfile = async (req, res, next) => { 46 | // Log the requested URL 47 | console.log("Requested URL:", req.originalUrl); 48 | 49 | const authHeader = req.headers.authorization; 50 | 51 | if (!authHeader) { 52 | return res.status(401).json({ msg: "No authorization token provided." }); 53 | } 54 | 55 | const tokenParts = authHeader.split(" "); 56 | if (tokenParts.length !== 2 || tokenParts[0] !== "Bearer") { 57 | return res.status(401).json({ msg: "Token format is 'Bearer '." }); 58 | } 59 | 60 | const token = tokenParts[1]; 61 | 62 | // Extract the ID from the end of the URL path 63 | const idParts = req.originalUrl.split("/"); 64 | const requestedProfileId = idParts[idParts.length - 1]; 65 | 66 | const profileIdFromToken = await getProfileIdFromToken(token); 67 | 68 | if (!profileIdFromToken) { 69 | return res.status(401).json({ msg: "Invalid or expired token." }); 70 | } 71 | 72 | if (profileIdFromToken !== requestedProfileId) { 73 | return res.status(403).json({ 74 | msg: "Profile ID in the token does not match the requested profile ID.", 75 | }); 76 | } 77 | 78 | next(); 79 | }; 80 | 81 | module.exports = { 82 | verifyProfile, 83 | }; 84 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | First off, thank you for considering contributing to Pipelines. We're still in the early stages of development and we're excited to have you join us on this journey. If you don't already know what Pipelines is, we recommend learning more about the project by visiting our [website](https://pipelines.lol). This will give you a better understanding of what we're trying to accomplish and build here. 4 | 5 | The following is a set of guidelines for contributing to Pipelines. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | _Pull requests, bug reports, and all other forms of contribution are welcomed and highly encouraged!_ :octocat: 8 | 9 | ### Contents 10 | 11 | - [Code of Conduct](#book-code-of-conduct) 12 | - [Opening an Issue](#inbox_tray-opening-an-issue) 13 | - [Reporting Security Issues](#lock-reporting-security-issues) 14 | 15 | > **This guide serves to set clear expectations for everyone involved with the project so that we can improve it together while also creating a welcoming space for everyone to participate in the development of Pipelines. Following these guidelines will help ensure a positive experience for contributors and maintainers.** 16 | 17 | ## :book: Code of Conduct 18 | 19 | Please review our [Code of Conduct](/CODE_OF_CONDUCT.md). It is in effect at all times. We expect it to be honored by everyone who contributes to this project. Acting in accordance with this code is a requirement for contributing to the project. 20 | 21 | ## :inbox_tray: Opening an Issue 22 | 23 | Before [creating an issue](https://help.github.com/en/github/managing-your-work-on-github/creating-an-issue), confirm that a similar issue has not already been reported. If you find a closed issue that seems to be the same as the one you're experiencing, open a new issue and link to the original issue in the body of your new one. 24 | 25 | When creating an issue, please provide as much detail as possible. This includes: 26 | 27 | - A clear and descriptive title 28 | - A detailed description of the issue 29 | - Steps to reproduce the issue 30 | - Expected behavior 31 | - Actual behavior 32 | - Screenshots, if applicable 33 | - Any other relevant information 34 | 35 | ### :lock: Reporting Security Issues 36 | 37 | **Do not** file a public issue for security vulnerabilities. Instead, please email **support@pipelines.lol**. This will help ensure that any vulnerabilities that are found are addressed as quickly as possible. If you are not sure whether you are dealing with a security issue, please err on the side of caution, and report it via email. 38 | 39 | # TODO: Finish this document 40 | -------------------------------------------------------------------------------- /client/src/components/landing/Marquee.js: -------------------------------------------------------------------------------- 1 | import { companies } from '../../data/companyData' 2 | 3 | const LogoMarquee = () => { 4 | const logos = Array.from( 5 | { length: 30 }, 6 | () => companies[Math.floor(Math.random() * companies.length)] 7 | ) 8 | return ( 9 | <> 10 |
11 |
    12 | {logos.map((logo, index) => ( 13 |
  • 14 | {logo.alt} 19 |
  • 20 | ))} 21 |
22 | 36 |
37 | 38 | ) 39 | } 40 | 41 | const SlidingImages = () => { 42 | return ( 43 | <> 44 |
45 |

46 | Pipelines is Trusted by Engineers at Top Tech Companies 47 |

48 | 49 |
50 | 51 | ) 52 | } 53 | 54 | export default SlidingImages 55 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@formkit/auto-animate": "^0.8.1", 7 | "@fortawesome/fontawesome-svg-core": "^6.5.1", 8 | "@fortawesome/free-solid-svg-icons": "^6.5.1", 9 | "@fortawesome/react-fontawesome": "^0.2.0", 10 | "@testing-library/jest-dom": "^5.17.0", 11 | "@testing-library/react": "^13.4.0", 12 | "@testing-library/user-event": "^13.5.0", 13 | "aws-sdk": "^2.1532.0", 14 | "daisyui": "^4.6.0", 15 | "dotenv": "^16.3.1", 16 | "flowbite": "^2.3.0", 17 | "flowbite-react": "^0.8.0", 18 | "framer-motion": "^10.18.0", 19 | "js-cookie": "^3.0.5", 20 | "lucide-react": "^0.307.0", 21 | "react": "^18.2.0", 22 | "react-dom": "^18.2.0", 23 | "react-loader-spinner": "^6.1.6", 24 | "react-router-dom": "^6.21.2", 25 | "react-scripts": "5.0.1", 26 | "tailwind-datepicker-react": "^1.4.3", 27 | "tailwind-merge": "^2.2.0", 28 | "web-vitals": "^2.1.4" 29 | }, 30 | "scripts": { 31 | "start": "react-scripts start", 32 | "build": "react-scripts build", 33 | "test": "react-scripts test", 34 | "eject": "react-scripts eject", 35 | "lint": "eslint \"src/**/*.{js,jsx}\"", 36 | "format": "prettier --write \"src/**/*.{js,jsx}\"", 37 | "lint:fix": "eslint --fix \"src/**/*.{js,jsx}\"" 38 | }, 39 | "eslintConfig": { 40 | "extends": [ 41 | "react-app", 42 | "react-app/jest" 43 | ] 44 | }, 45 | "browserslist": { 46 | "production": [ 47 | ">0.2%", 48 | "not dead", 49 | "not op_mini all" 50 | ], 51 | "development": [ 52 | "last 1 chrome version", 53 | "last 1 firefox version", 54 | "last 1 safari version" 55 | ] 56 | }, 57 | "devDependencies": { 58 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 59 | "eslint": "^8.56.0", 60 | "eslint-config-airbnb": "^19.0.4", 61 | "eslint-config-prettier": "^9.1.0", 62 | "eslint-config-standard": "^17.1.0", 63 | "eslint-plugin-import": "^2.29.1", 64 | "eslint-plugin-jsx-a11y": "^6.8.0", 65 | "eslint-plugin-n": "^16.6.2", 66 | "eslint-plugin-prettier": "^5.1.3", 67 | "eslint-plugin-promise": "^6.1.1", 68 | "eslint-plugin-react": "^7.33.2", 69 | "eslint-plugin-react-hooks": "^4.6.0", 70 | "prettier": "^3.2.4", 71 | "prettier-plugin-tailwindcss": "^0.5.11", 72 | "tailwindcss": "^3.3.7" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /client/src/hooks/useValidateExperience.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react' 2 | 3 | const useValidateExperience = (experience) => { 4 | const [companyName, setCompanyName] = useState('') 5 | const [displayName, setDisplayName] = useState('') 6 | const [title, setTitle] = useState('') 7 | const [startDate, setStartDate] = useState('') 8 | const [endDate, setEndDate] = useState('') 9 | const [isIndefinite, setIsIndefinite] = useState(false) 10 | const [rating, setRating] = useState(0) 11 | const [selectedOption, setSelectedOption] = useState(1) 12 | const [companyId, setCompanyId] = useState('') 13 | const [first, setFirst] = useState(true) 14 | const [globalId, setId] = useState(0) 15 | const [logo, setLogo] = useState('') 16 | 17 | // initialize experience if one exists 18 | useEffect(() => { 19 | if (experience) { 20 | // Set basic experience details 21 | setCompanyName(experience.companyName) 22 | setDisplayName(experience.displayName) 23 | setTitle(experience.title) 24 | setCompanyId(experience.companyId) 25 | setRating(experience.rating) 26 | setSelectedOption(experience.rating / 20) 27 | setIsIndefinite(experience.isIndefinite) 28 | 29 | // Set ID and logo, with default values if not provided 30 | setId(experience.tempId2 || 0) 31 | setLogo(experience.logo || '') 32 | 33 | // Initialize startDate and endDate 34 | let startDate = '' 35 | let endDate = '' 36 | 37 | // Set startDate if provided 38 | if (experience.startDate) { 39 | startDate = new Date(experience.startDate) 40 | } 41 | 42 | // Set endDate if provided and not indefinite 43 | if (experience.endDate && !experience.isIndefinite) { 44 | endDate = new Date(experience.endDate) 45 | } 46 | 47 | // Update state with calculated startDate and endDate 48 | setStartDate(startDate) 49 | setEndDate(endDate) 50 | } 51 | }, [experience]) 52 | 53 | return { 54 | globalId, 55 | companyName, 56 | displayName, 57 | companyId, 58 | title, 59 | startDate, 60 | endDate, 61 | isIndefinite, 62 | rating, 63 | selectedOption, 64 | first, 65 | logo, 66 | setCompanyName, 67 | setDisplayName, 68 | setCompanyId, 69 | setTitle, 70 | setIsIndefinite, 71 | setSelectedOption, 72 | setRating, 73 | setFirst, 74 | setStartDate, 75 | setEndDate, 76 | setId, 77 | setLogo, 78 | } 79 | } 80 | 81 | export default useValidateExperience 82 | -------------------------------------------------------------------------------- /client/src/pages/Code.js: -------------------------------------------------------------------------------- 1 | import { useNavigate } from 'react-router-dom' 2 | import { useEarlyAccess } from '../hooks/useEarlyAccess' 3 | import { useState } from 'react' 4 | 5 | import { HOST } from '../util/apiRoutes' 6 | import { fetchWithAuth } from '../util/fetchUtils' 7 | 8 | function Code() { 9 | const [code, setCode] = useState() 10 | 11 | const [errorMessage, setErrorMessage] = useState('') 12 | 13 | const navigate = useNavigate() 14 | const { setAccess } = useEarlyAccess() 15 | 16 | const handleSubmit = async (e) => { 17 | e.preventDefault() 18 | 19 | // authentication 20 | try { 21 | await fetchWithAuth({ 22 | url: `${HOST}/api/earlyAccess/check`, 23 | method: 'POST', 24 | data: { code }, 25 | }) 26 | 27 | setAccess(true) 28 | navigate('/') 29 | } catch (error) { 30 | console.error('Error:', error.message) 31 | setErrorMessage(error.message) 32 | setAccess(false) 33 | } 34 | } 35 | 36 | return ( 37 |
47 |
48 | {/* Input field for code */} 49 |
50 |
51 | setCode(e.target.value)} 60 | /> 61 | 67 |
68 |
69 | 70 | {errorMessage &&

{errorMessage}

} 71 |
72 |
73 | ) 74 | } 75 | 76 | export default Code 77 | -------------------------------------------------------------------------------- /client/src/components/TitleQuerySearchInput.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import { titles } from '../data/companyData' 3 | 4 | export const TitleQuerySearchInput = ({ value, handleSearch }) => { 5 | const [query, setQuery] = useState('') 6 | const [results, setResults] = useState([]) 7 | const hasResults = results.length > 0 8 | 9 | // initialize company if one exists 10 | useEffect(() => { 11 | // reset query before checking if theres a previous value 12 | setQuery('') 13 | 14 | // check if there was a previous value 15 | // if there was, set query to it 16 | if (value) { 17 | setQuery(value) 18 | } 19 | }, [value]) 20 | 21 | const handleInputChange = async (event) => { 22 | const inputValue = event.target.value 23 | setQuery(inputValue) 24 | 25 | // make sure theres an input before querying 26 | if (inputValue.length > 0) { 27 | const filteredCompanies = titles.filter((title) => 28 | title.toLowerCase().startsWith(inputValue.toLowerCase()) 29 | ) 30 | setResults(filteredCompanies) 31 | } else { 32 | setResults([]) 33 | } 34 | 35 | await handleSearch(inputValue) 36 | } 37 | 38 | const handleTitleButtonClick = async (title) => { 39 | // reset text input 40 | setQuery(title) 41 | setResults([]) 42 | 43 | await handleSearch(title) 44 | } 45 | 46 | return ( 47 | <> 48 |
e.preventDefault()} // Prevent form submission 51 | > 52 | 61 |
64 | {hasResults && 65 | results.map((title) => ( 66 |
70 | 79 |
80 | ))} 81 |
82 |
83 | 84 | ) 85 | } 86 | -------------------------------------------------------------------------------- /client/src/components/DatePicker.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useRef } from 'react' 2 | import Datepicker from 'tailwind-datepicker-react' 3 | import { ArrowLeft, ArrowRight } from 'lucide-react' 4 | 5 | const options = { 6 | autoHide: true, 7 | todayBtn: false, 8 | clearBtn: true, 9 | clearBtnText: 'Clear', 10 | maxDate: new Date('2030-01-01'), 11 | minDate: new Date('1950-01-01'), 12 | theme: { 13 | background: 'bg-gray-700', 14 | todayBtn: '', 15 | clearBtn: '', 16 | icons: 'bg-gray-700 text-white hover:bg-opacity-20', 17 | text: 'text-white hover:bg-opacity-20', 18 | disabledText: '', 19 | input: '', 20 | inputIcon: '', 21 | selected: 'bg-pipeline-blue-200 hover:bg-opacity-80', 22 | }, 23 | icons: { 24 | // () => ReactElement | JSX.Element 25 | prev: () => , 26 | next: () => , 27 | }, 28 | datepickerClassNames: 'top-32 right-10', 29 | language: 'en', 30 | disabledDates: [], 31 | inputNameProp: 'date', 32 | inputIdProp: 'date', 33 | inputPlaceholderProp: 'Select Date ', 34 | inputDateFormatProp: { 35 | day: 'numeric', 36 | month: 'long', 37 | year: 'numeric', 38 | }, 39 | } 40 | 41 | export const DatePicker = ({ value, onChange }) => { 42 | const [date, setDate] = useState(value || null) 43 | const [show, setShow] = useState(false) 44 | const wrapperRef = useRef(null) 45 | 46 | const handleChange = (selectedDate) => { 47 | setDate(selectedDate) 48 | onChange(selectedDate) 49 | } 50 | const handleClose = (state) => { 51 | setShow(state) 52 | } 53 | 54 | useEffect(() => { 55 | if (value) { 56 | setDate(value) 57 | } 58 | }, [value]) 59 | 60 | useEffect(() => { 61 | function handleClickOutside(event) { 62 | if ( 63 | wrapperRef.current && 64 | !wrapperRef.current.contains(event.target) 65 | ) { 66 | setShow(false) 67 | } 68 | } 69 | document.addEventListener('mousedown', handleClickOutside) 70 | return () => { 71 | document.removeEventListener('mousedown', handleClickOutside) 72 | } 73 | }, [wrapperRef]) 74 | 75 | return ( 76 |
77 | 84 | setShow(true)} 98 | readOnly 99 | /> 100 | 101 |
102 | ) 103 | } 104 | -------------------------------------------------------------------------------- /server/controllers/pfpController.js: -------------------------------------------------------------------------------- 1 | const Profile = require('../models/profileModel') 2 | const mongoose = require('mongoose') 3 | const crypto = require('crypto') 4 | 5 | // const sharp = require('sharp') 6 | 7 | const { S3Client, PutObjectCommand, GetObjectCommand } = require('@aws-sdk/client-s3') 8 | const { getSignedUrl } = require('@aws-sdk/s3-request-presigner') 9 | 10 | const randomImageName = (bytes = 32) => crypto.randomBytes(bytes).toString('hex') 11 | 12 | const BUCKET_NAME = process.env.BUCKET_NAME 13 | const BUCKET_REGION = process.env.BUCKET_REGION 14 | const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID 15 | const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY 16 | 17 | const s3 = new S3Client({ 18 | credentials: { 19 | accessKeyId: AWS_ACCESS_KEY_ID, 20 | secretAccessKey: AWS_SECRET_ACCESS_KEY, 21 | }, 22 | region: BUCKET_REGION 23 | }) 24 | 25 | const isLinkedInImage = (pfp) => { 26 | const linkedInImageRegex = /^https:\/\/media\.licdn\.com\/dms\/image\/.+$/; 27 | 28 | return linkedInImageRegex.test(pfp); 29 | }; 30 | 31 | const getPfp = async (req, res) => { 32 | const { id } = req.params 33 | 34 | const profile = await Profile.findById(id); 35 | 36 | if (!profile) { 37 | return res.status(404).json({ error: 'No such Profile.' }); 38 | } 39 | 40 | const pfp = profile.pfp 41 | 42 | if (!pfp) { 43 | return res.status(404).json({ error: 'No such profile picture.' }); 44 | } else if (pfp === "") { 45 | return res.status(200).json({ pfp: "" }); 46 | } 47 | 48 | if (isLinkedInImage(pfp)) { 49 | return res.status(200).json({ pfp: pfp }); 50 | } 51 | 52 | const getObjectParams = { 53 | Bucket: BUCKET_NAME, 54 | Key: pfp 55 | } 56 | 57 | const command = new GetObjectCommand(getObjectParams) 58 | const url = await getSignedUrl(s3, command, { expiresIn: 3600 }) 59 | 60 | res.status(200).json({ pfp: url }); 61 | } 62 | 63 | const updatePfp = async (req, res) => { 64 | const { id } = req.params 65 | 66 | let profile = await Profile.findOne({ _id: id }); 67 | 68 | if (!profile) { 69 | return res.status(404).json({ error: 'No such Profile.' }); 70 | } 71 | 72 | // if there is no file, then no changes will be made 73 | if (!req.file) { 74 | return res.status(200).json(profile); 75 | } 76 | let { buffer, mimetype } = req.file 77 | 78 | // resize image 79 | // const buffer = sharp(buffer).resize({ 80 | // height: 320, 81 | // width: 320, 82 | // fit: "contain" 83 | // }).toBuffer() 84 | 85 | let imageName; 86 | if (profile.pfp === "") { 87 | imageName = randomImageName() 88 | } else { 89 | imageName = profile.pfp 90 | } 91 | 92 | const params = { 93 | Bucket: BUCKET_NAME, 94 | Key: imageName, 95 | Body: buffer, 96 | ContentType: mimetype 97 | } 98 | 99 | const command = new PutObjectCommand(params) 100 | await s3.send(command) 101 | 102 | // save image name (key) to mongodb 103 | const pfpData = { pfp: imageName } 104 | profile = await Profile.findOneAndUpdate({ _id: id }, pfpData, { new: true }); 105 | 106 | if (!profile) { 107 | return res.status(404).json({ error: 'No such Profile.' }); 108 | } 109 | 110 | res.status(200).json(profile); 111 | } 112 | 113 | module.exports = { 114 | getPfp, 115 | updatePfp 116 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at **support@pipelines.lol**. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /client/src/components/QuerySearchInput.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | 3 | import { HOST } from '../util/apiRoutes' 4 | import { fetchWithAuth } from '../util/fetchUtils' 5 | 6 | export const QuerySearchInput = ({ handleSearch }) => { 7 | const [query, setQuery] = useState('') 8 | const [results, setResults] = useState([]) 9 | const hasResults = results.length > 0 10 | 11 | const handleInputChange = async (event) => { 12 | const inputValue = event.target.value 13 | setQuery(inputValue) 14 | 15 | // make sure theres an input before querying 16 | if (inputValue.length > 0) { 17 | try { 18 | const data = await fetchWithAuth({ 19 | url: `${HOST}/api/company/get/companies/${inputValue.toLowerCase()}`, 20 | method: 'GET', 21 | }) 22 | 23 | setResults(data) 24 | } catch (error) { 25 | console.error(error.message) 26 | } 27 | } else { 28 | setResults([]) 29 | } 30 | } 31 | 32 | const handleCompanyButtonClick = async (company) => { 33 | // reset text input 34 | setQuery(company.displayName) 35 | setResults([]) 36 | 37 | await handleSearch(company) 38 | } 39 | 40 | return ( 41 | <> 42 |
e.preventDefault()} // Prevent form submission 45 | > 46 | 55 |
58 | {hasResults && 59 | results.map((company) => ( 60 |
64 | {`logo_${company.displayName}`} 69 | 78 |
79 | ))} 80 |
81 |
82 | 83 | ) 84 | } 85 | -------------------------------------------------------------------------------- /client/src/components/landing/CTA.js: -------------------------------------------------------------------------------- 1 | import { useNavigate } from 'react-router-dom' 2 | import { HOMEPAGE } from '../../util/apiRoutes' 3 | import { CLIENT_ID, SCOPE } from '../../util/linkedinUtils' 4 | import { useAuthContext } from '../../hooks/useAuthContext' 5 | 6 | export default function CTA() { 7 | const navigate = useNavigate() 8 | const { user } = useAuthContext() 9 | const linkedinRedirectUrl = `https://linkedin.com/oauth/v2/authorization?client_id=${CLIENT_ID}&response_type=code&scope=${SCOPE}&redirect_uri=${HOMEPAGE}` 10 | 11 | const handleNavigation = () => { 12 | if (user) { 13 | navigate('/edit') 14 | } else { 15 | window.location.href = linkedinRedirectUrl 16 | } 17 | } 18 | 19 | return ( 20 | <> 21 |
29 | 75 |
76 | 77 | ) 78 | } 79 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | // App.js 2 | import { 3 | Route, 4 | BrowserRouter as Router, 5 | Routes, 6 | useLocation, 7 | } from 'react-router-dom' 8 | import './App.css' 9 | 10 | // Components 11 | import Footer from './components/Footer' 12 | import Navbar from './components/Navbar' 13 | 14 | // Pages 15 | import Discover from './pages/Discover' 16 | import EditProfile from './pages/EditProfile' 17 | import Home from './pages/Home' 18 | import Login from './pages/Login' 19 | import Profile from './pages/Profile' 20 | import Search from './pages/Search' 21 | import Signup from './pages/Signup' 22 | import Suggestions from './pages/Suggestions' 23 | import Company from './pages/Company' 24 | import School from './pages/School' 25 | import Admin from './pages/(admin)/Admin' 26 | 27 | // Context 28 | import { useAuthContext } from './hooks/useAuthContext' 29 | import { useEarlyAccess } from './hooks/useEarlyAccess' 30 | import { error404 } from './components/Error404' 31 | import Newsletter from './pages/Newsletter' 32 | import Code from './pages/Code' 33 | 34 | // Navbar Component 35 | function AppNavbar() { 36 | return 37 | } 38 | 39 | // Footer Component 40 | function AppFooter() { 41 | return