From 1ea9ff91d7c9cbb9e20e186f4a29429adae2e6b6 Mon Sep 17 00:00:00 2001 From: Brett Hayes Date: Tue, 15 Feb 2022 21:55:32 -0500 Subject: [PATCH 1/5] 404 page --- src/pages/404.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/pages/404.tsx diff --git a/src/pages/404.tsx b/src/pages/404.tsx new file mode 100644 index 00000000..1c8edafb --- /dev/null +++ b/src/pages/404.tsx @@ -0,0 +1,21 @@ +import SignDirectionIcon from 'mdi-react/SignDirectionIcon' +import React from 'react' + +import { Layout } from '@components' + +const Custom404: React.FunctionComponent = () => ( + +
+
+
+ +
+
+ +

404: Not Found

+

Sorry, the requested URL was not found.

+
+
+) + +export default Custom404 From 1b777d6b69af9244eed6ef81036ff3dfe528b39e Mon Sep 17 00:00:00 2001 From: Brett Hayes Date: Tue, 15 Feb 2022 23:12:54 -0500 Subject: [PATCH 2/5] use cases page and dependant components --- package.json | 1 + .../CustomerLogosSectionAnimated.tsx | 472 ++++++++++++++++++ src/components/TrySourcegraph.tsx | 44 ++ src/components/index.ts | 2 + src/pages/use-cases.tsx | 338 +++++++++++++ yarn.lock | 98 ++++ 6 files changed, 955 insertions(+) create mode 100644 src/components/CustomerLogosSectionAnimated.tsx create mode 100644 src/components/TrySourcegraph.tsx create mode 100644 src/pages/use-cases.tsx diff --git a/package.json b/package.json index 50dac0df..751aaa94 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "mdi-react": "^8.2.0", "prettier": "^2.5.1", "react-bootstrap": "1.6.1", + "react-spring": "9.4.2", "sass": "^1.49.7", "typescript": "4.5.5" } diff --git a/src/components/CustomerLogosSectionAnimated.tsx b/src/components/CustomerLogosSectionAnimated.tsx new file mode 100644 index 00000000..28c30551 --- /dev/null +++ b/src/components/CustomerLogosSectionAnimated.tsx @@ -0,0 +1,472 @@ +import ArrowRightBoxIcon from 'mdi-react/ArrowRightBoxIcon' +import React, { useRef, useState, useEffect } from 'react' +import { useSpring, animated } from 'react-spring' + +const ITEMS: { + name: string + url: string + link?: { + url: string + target?: string + rel?: string + } +}[] = [ + { + name: 'Amazon', + url: '/external-logos/amazon-logo.svg', + }, + { + name: 'Dropbox', + url: '/external-logos/dropbox-logo.svg', + }, + { + name: 'Cloudflare', + url: '/external-logos/cloudflare-color-logo.svg', + }, + { + name: 'GE', + url: '/external-logos/general-electric-logo.svg', + }, + { + name: 'Reddit', + url: '/external-logos/reddit-logo.png', + }, + { + name: 'Paypal', + url: '/external-logos/paypal-logo.svg', + }, + { + name: 'Indeed', + url: '/external-logos/indeed-logo.svg', + }, + { + name: 'Uber', + url: '/external-logos/uber.svg', + }, + { + name: 'Plaid', + url: '/external-logos/plaid-logo.svg', + }, + { + name: 'Lyft', + url: '/external-logos/lyft-logo.svg', + }, + { + name: 'Unity', + url: '/external-logos/unity.svg', + }, + { + name: 'Collective Health', + url: '/external-logos/collective-health-logo.svg', + }, + { + name: 'F5', + url: '/external-logos/f5-logo.svg', + }, + { + name: 'Qualtrics', + url: '/external-logos/qualtrics-logo.svg', + }, + { + name: 'Toast', + url: '/external-logos/toast-logo.svg', + }, + { + name: 'SoFi', + url: '/external-logos/sofi-logo.svg', + }, + { + name: 'Yelp', + url: '/external-logos/yelp.svg', + }, + { + name: 'Prezi', + url: '/external-logos/prezi-logo.svg', + }, + { + name: 'Thought Machine', + url: '/external-logos/thought-machine-logo.svg', + }, + { + name: 'Adidas Running', + url: '/external-logos/adidas-runtastic-sq-logo.svg', + }, + { + name: 'Nutanix', + url: '/external-logos/nutanix-logo.svg', + }, + { + name: 'Quantcast', + url: '/external-logos/quantcast-logo.svg', + }, + { + name: 'Criteo', + url: '/external-logos/criteo-logo.svg', + }, + { + name: 'Convoy', + url: '/external-logos/convoy-logo.svg', + }, + { + name: 'Eventbrite', + url: '/external-logos/eventbrite.png', + }, + { + name: 'Cornerstone OnDemand', + url: '/external-logos/cornerstone-ondemand-logo.svg', + }, + { + name: 'Skelter Labs', + url: '/external-logos/skelter-labs-logo.svg', + }, + { + name: 'Factset', + url: '/external-logos/factset-logo.svg', + }, + { + name: 'Cambridge University Press', + url: '/external-logos/cambridge-university-press-logo.svg', + }, + { + name: 'Workiva', + url: '/external-logos/workiva-vector-logo.svg', + }, + { + name: 'Apex Clearing', + url: '/external-logos/apex-clearing-logo.png', + }, + { + name: 'Blend', + url: '/external-logos/blend.svg', + }, + { + name: 'AppLovin', + url: '/external-logos/applovin-logo.svg', + }, + { + name: 'TripActions', + url: '/external-logos/tripactions-logo.svg', + }, + { + name: 'Mercari', + url: '/external-logos/mercari.svg', + }, + { + name: 'Handy', + url: '/external-logos/handy-logo.svg', + }, + { + name: 'Capella Space', + url: '/external-logos/capella_space.svg', + }, + { + name: 'Motley Fool', + url: '/external-logos/motley_fool.svg', + }, + { + name: 'Twilio', + url: '/external-logos/twilio-segment-horizontal-darkacai-logo.svg', + }, +] + +interface Props { + showButton: boolean + className: String + showSection: boolean +} + +export const CustomerLogosSectionAnimated: React.FC = ({ showButton, className, showSection }) => { + const [buttonClass, setButtonClass] = useState('') + const [windowWidth, setWindowWidth] = useState(0) + const [imagesWidth, setImagesWidth] = useState(0) + const [scrollAnimation, setScrollAnimation] = useState(false) + const [readyToScroll, setReadyToScroll] = useState(false) + + const innerContainerRef = useRef(null) + const firstLogoContainerRef = useRef(null) + const secondLogoContainerRefClone = useRef(null) + const thirdLogoContainerRefClone = useRef(null) + const [{ x, y, scale }, set] = useSpring(() => ({ x: 0, y: 0, scale: 0 })) + const minDeviceWidth = 991 + const animationTimeInSeconds = 25 + let extraSpace = 0 + if (ITEMS.length % 3 !== 0) { + extraSpace = 135 + } + + useEffect(() => { + setWindowWidth(window.innerWidth) + window.addEventListener('resize', adjustWindowWidth) + return () => { + window.removeEventListener('resize', adjustWindowWidth) + } + }, []) + + useEffect(() => { + let promises = ITEMS.map(image => { + return new Promise((resolve, _) => { + const imageRef = new Image() + imageRef.onload = function () { + if (this.height && this.width) { + let calculatedWidth = (this.width / this.height) * 50 + if (calculatedWidth > 135) calculatedWidth = 135 + setImagesWidth(prevState => (prevState += calculatedWidth + 70)) //Total width of all images + } else { + setImagesWidth(prevState => (prevState += 135 + 70)) + } + resolve() + } + imageRef.src = image.url + }) + }) + Promise.all(promises).then(() => { + const logoElement = document.getElementById('logo-container-reference')! + logoElement.classList.remove('hidden') + const secondLogoContainerClone = logoElement.cloneNode(true) + const thirdLogoContainerClone = logoElement.cloneNode(true) + logoElement?.parentNode?.insertBefore(secondLogoContainerClone, logoElement.nextSibling) + logoElement?.parentNode?.insertBefore(thirdLogoContainerClone, logoElement.nextSibling) + secondLogoContainerRefClone.current = secondLogoContainerClone + thirdLogoContainerRefClone.current = thirdLogoContainerClone + setReadyToScroll(true) + }) + }, []) + + useEffect(() => { + if (scrollAnimation) { + startAnimation() + } + }, [scrollAnimation]) + + useEffect(() => { + if (readyToScroll && windowWidth < minDeviceWidth) { + setTimeout(() => { + startAnimation() + }, 500) + } + }, [readyToScroll]) + + useEffect(() => { + if ( + firstLogoContainerRef.current && + secondLogoContainerRefClone.current && + thirdLogoContainerRefClone.current + ) { + if (windowWidth > minDeviceWidth) { + innerContainerRef.current!.addEventListener('mouseenter', handleMouseEnter) + innerContainerRef.current!.addEventListener('mousemove', handleMouseMove) + innerContainerRef.current!.addEventListener('mouseleave', handleMouseLeaveInnerArea) + } + } + }, [ + firstLogoContainerRef.current, + secondLogoContainerRefClone.current, + thirdLogoContainerRefClone.current, + scrollAnimation, + ]) + + function adjustWindowWidth() { + setWindowWidth(window.innerWidth) + } + + function startAnimation() { + let logoElement = document.getElementById('logo-container-reference')! + logoElement.addEventListener('transitionend', transitionEnd) + transitionStart() + } + + function transitionStart() { + const logoContainerOne = firstLogoContainerRef.current! + const logoContainerTwo = secondLogoContainerRefClone.current! + const logoContainerThree = thirdLogoContainerRefClone.current! + let totalWidth = imagesWidth / 3 + 30 + extraSpace + + logoContainerOne.style.transition = `${animationTimeInSeconds}s linear` + logoContainerTwo.style.transition = `${animationTimeInSeconds}s linear` + logoContainerThree.style.transition = `${animationTimeInSeconds}s linear` + logoContainerOne.style.transform = `translateX(${-totalWidth}px)` + logoContainerTwo.style.transform = `translateX(${-totalWidth}px)` + logoContainerThree.style.transform = `translateX(${-totalWidth}px)` + } + + function transitionEnd(e) { + if (e.target.id !== 'logo-container-reference') return + const logoContainerOne = firstLogoContainerRef.current! + const logoContainerTwo = secondLogoContainerRefClone.current! + const logoContainerThree = thirdLogoContainerRefClone.current! + logoContainerOne.style.transition = 'none' + logoContainerTwo.style.transition = 'none' + logoContainerThree.style.transition = 'none' + logoContainerOne.style.transform = `translateX(0px)` + logoContainerTwo.style.transform = `translateX(0px)` + logoContainerThree.style.transform = `translateX(0px)` + setTimeout(() => { + transitionStart() + }, 0) + } + + function pauseAnimation() { + const logoContainerOne = firstLogoContainerRef.current! + const logoContainerTwo = secondLogoContainerRefClone.current! + const logoContainerThree = thirdLogoContainerRefClone.current! + let transformOne = window.getComputedStyle(logoContainerOne).transform + let transformTwo = window.getComputedStyle(logoContainerTwo).transform + let transformThree = window.getComputedStyle(logoContainerThree).transform + + logoContainerOne.style.transform = transformOne + logoContainerTwo.style.transform = transformTwo + logoContainerThree.style.transform = transformThree + + logoContainerOne.style.transition = 'none' + logoContainerTwo.style.transition = 'none' + logoContainerThree.style.transition = 'none' + } + + function continueAnimationFromCurrentPosition() { + const logoContainerOne = firstLogoContainerRef.current! + const logoContainerTwo = secondLogoContainerRefClone.current! + const logoContainerThree = thirdLogoContainerRefClone.current! + + let transformOne = window.getComputedStyle(logoContainerOne).transform + let matrixValueXOne = transformOne.match(/matrix.*\((.+)\)/)[1].split(', ')[4] + let totalWidth = imagesWidth / 3 + 30 + extraSpace + let xPosition = parseInt(matrixValueXOne) + let newPosition = -totalWidth - xPosition + + const pixelsPersecond = Math.abs(totalWidth) / animationTimeInSeconds + const newpositiontime = (Math.abs(newPosition) / pixelsPersecond).toString() + + logoContainerOne.style.transition = `${newpositiontime}s linear` + logoContainerTwo.style.transition = `${newpositiontime}s linear` + logoContainerThree.style.transition = `${newpositiontime}s linear` + + logoContainerOne.style.transform = `translateX(${-totalWidth}px)` + logoContainerTwo.style.transform = `translateX(${-totalWidth}px)` + logoContainerThree.style.transform = `translateX(${-totalWidth}px)` + } + + function buttonFollowsMouse(e) { + const containerRec = innerContainerRef.current?.getBoundingClientRect() + if ( + e.clientX - containerRec?.left! > 150 && + e.clientY - containerRec?.top! > 60 && + containerRec?.left! + innerContainerRef.current?.offsetWidth! - e.clientX > 150 && + containerRec?.top! + innerContainerRef.current?.offsetHeight! - e.clientY > 60 + ) { + setButtonClass('') + set({ scale: 1 }) + } else { + setButtonClass('sourcegraph-cta-button-edge') + set({ scale: 0.1 }) + } + set({ + x: e.clientX - containerRec?.left! + innerContainerRef.current?.scrollLeft!, + y: e.clientY - containerRec?.top!, + }) + } + + function handleMouseEnter() { + if (readyToScroll) { + if (!scrollAnimation) { + setScrollAnimation(true) + } else { + continueAnimationFromCurrentPosition() + } + } + } + + function handleMouseMove(e) { + if (showButton && readyToScroll) buttonFollowsMouse(e) + } + + function handleMouseLeaveInnerArea() { + if (readyToScroll) { + pauseAnimation() + if (showButton) set({ scale: 0 }) + } + } + + return ( +
+ {showSection && ( +

+ Our customers use Sourcegraph every day to build software you rely on. +

+ )} + {!showButton && ( + + )} +
+ {windowWidth > minDeviceWidth && showButton && ( + + `scale(${s}) translate(-50%, -50%)`), + }} + > + Learn how customers
use Sourcegraph +
+
+ )} +
+ {ITEMS.map((logo, i) => ( +
+ {logo.link ? ( + + minDeviceWidth + ? 'customer-logos-section__item-logo-animation' + : 'link-hover') + } + src={logo.url} + alt={logo.name} + /> + + ) : ( + minDeviceWidth + ? 'customer-logos-section__item-logo-animation' + : '') + } + src={logo.url} + alt={logo.name} + /> + )} +
+ ))} +
+
+ + {windowWidth < minDeviceWidth && showButton && ( + + )} +
+ ) +} diff --git a/src/components/TrySourcegraph.tsx b/src/components/TrySourcegraph.tsx new file mode 100644 index 00000000..25b49c08 --- /dev/null +++ b/src/components/TrySourcegraph.tsx @@ -0,0 +1,44 @@ +import Link from 'next/link' +import React from 'react' + +import { ContentSection } from '@components' + +interface Props { + demoFormURL?: string + className?: string +} + +export const TrySourcegraph: React.FunctionComponent = ({ + demoFormURL = 'https://info.sourcegraph.com/demo-request', + className = '', +}) => ( + +
+
+

Try Sourcegraph for free today

+

+ You'll be searching your own code in 10 minutes. You can run it self-hosted (all of your code stays + local and secure). +

+
+ +
+ {demoFormURL !== '' && ( + + + Schedule a demo + + + )} + + + Try Sourcegraph now + +
+
+
+) diff --git a/src/components/index.ts b/src/components/index.ts index c4fcb047..132cf7b3 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -3,6 +3,8 @@ export { Layout } from './Layout' export { ContentSection } from './ContentSection' export { Jumbotron, COLORS } from './Jumbotron' export { RequestDemoForm } from './RequestDemoForm' +export { CustomerLogosSectionAnimated } from './CustomerLogosSectionAnimated' +export { TrySourcegraph } from './TrySourcegraph' // Page Specific export { CaseStudyJumbotron, CaseStudyLayout, InContentBlockquote, InContentImage, MediaQuote } from './CaseStudies' diff --git a/src/pages/use-cases.tsx b/src/pages/use-cases.tsx new file mode 100644 index 00000000..3103ea09 --- /dev/null +++ b/src/pages/use-cases.tsx @@ -0,0 +1,338 @@ +import ArrowRightBoxIcon from 'mdi-react/ArrowRightBoxIcon' +import ArrowRightIcon from 'mdi-react/ArrowRightIcon' +import Link from 'next/link' +import React from 'react' + +import { Layout, ContentSection, CustomerLogosSectionAnimated, TrySourcegraph } from '@components' +import { stringToDashCase } from '@util' + +const features: string[] = [ + 'Find and fix security vulnerabilities', + 'Accelerate developer onboarding', + 'Resolve incidents faster', + 'Streamline code reuse', + 'Boost code health', +] + +const UseCases: React.FunctionComponent = () => ( + +
+
+

Our customers move faster with Sourcegraph

+

+ Companies of all sizes and in all industries use Sourcegraph universal code search to solve + big code problems. +

+
+ +
+

+ See how customers use Sourcegraph to +

+ +
+ {features.map((feature: string) => ( + + {feature} + + + ))} +
+
+
+ + } + > +
+ + +
+ + +
+
+

Find and fix security vulnerabilities

+
Find, fix, and track vulnerable code quickly across your entire codebase.
+

+ You can't fix what you can't find. Remediate vulnerabilities with confidence knowing you + found every instance of affected code. Track your remediation initiatives to completion with + automated fixes and pull requests. With Sourcegraph, timely resolution is a search away. +

+
    +
  • Reduce time to recovery with a single search
  • +
  • + Automate fixing, merging, and deploying changes with{' '} + + Batch Changes + +
  • +
  • Alert for known vulnerabilities and risky code changes with code monitoring
  • +
+ + Request a demo + +
+
+
+

+ [Sourcegraph] is the best way to prove we're not vulnerable to a particular CVE, if and + when we get asked by an auditor. +

+
David Haynes, Security Engineer at Cloudflare
+
+ + + Cloudflare + + +
+
+
+
+
+ +
+ + +
+
+
+

+ For our new developers, Sourcegraph has been invaluable to get to know the repository + structure, to track down where code lives, and self-service during their investigations. +

+
Owen Kim, Senior Software Engineer, Convoy
+ +
+ + + Convoy + + +
+
+
+
+

Accelerate developer onboarding

+
+ Decrease time to first commit with self-serve onboarding, codebase exploration, and + knowledge sharing. +
+

+ Onboard teammates faster and improve dev velocity by making it easy to search and find code + and context. Unlike splintered tooling and knowledge management systems that require manual + interaction and upkeep, Sourcegraph helps devs self-serve. +

+
    +
  • + Search across all repositories and multiple branches to find answers in staging, dev, + and production environments +
  • +
  • + Navigate large codebases with definitions and references with advanced Code Intelligence +
  • +
  • Get answers faster with shareable links to specific code
  • +
+ + Request a demo + +
+
+
+ +
+ + +
+
+

Resolve incidents faster

+
Identify the root cause in code and fix the issue everywhere.
+

+ Every minute matters when responding to a business-critical incident. Downtime = revenue + lost. Sourcegraph helps development teams identify the root cause in code, understand why + the problem occurred and its potential impact on other services, fix the issue everywhere so + it won't reoccur, and assure incident responders that all holes are plugged. +

+
    +
  • + Quickly understand all context & dependencies around the codebase to self-serve or + involve relevant teams +
  • +
  • + Refactor code to replace insecure functions, update vulnerable packages, or modify + container configurations across hundreds of repositories +
  • +
  • + Document your solution by sharing links to searches and files and recording work in a + search notebook +
  • +
+ + Request a demo + +
+
+
+

+ Sourcegraph's search gave us confidence because we knew we wouldn't overlook anything: + Sourcegraph returns all search results, it doesn't drop or elide them. +

+
Simon Law, Staff Software Engineer, Quantcast
+
+ + + Quantcast + + +
+
+
+
+
+ +
+ + +
+
+
+

+ If I'm developing code for a library that might draw charts, for example, we don't want + 30 different ways to draw a chart at FactSet. With Sourcegraph, I can search the code to + find other chart examples, and simply copy the code. This saves us time and ensures + consistency. +

+
Joseph Majesky, Software Engineer, FactSet
+
+ + + FactSet + + +
+
+
+
+

Streamline code reuse

+
Stop wasting time rewriting code.
+

+ With Sourcegraph, you can find existing code libraries for reuse and avoid spending time on + problems you know a teammate already solved. This means a more secure and coherent codebase + and more time for you to spend on more interesting work. Sourcegraph makes it easy to: +

+
    +
  • + Quickly discover code you can trust for reuse by typing your query and getting an answer +
  • +
  • + Evaluate signals from multiple sources and tools to help you assess if you should use + the code +
  • +
  • + Safely and efficiently maintain code that is being reused and easily make changes + everywhere with Batch Changes +
  • +
  • Add a code monitor to alert you of commits using an out-of-date library
  • +
+ + Request a demo + +
+
+
+ +
+ + +
+
+

Boost code health

+
+ Improve code posture with large-scale changes and track code health initiatives towards + completion. +
+

+ Engineering teams need to monitor code health across their entire codebase to track and + measure code quality consistently. Sourcegraph helps teams figure out the components of code + health they have all agreed on and work towards a healthier codebase. +

+
    +
  • + Search for and refactor references to deprecated services, libraries, URL patterns, and + more across all your repositories with confidence +
  • +
  • + Understand the impact of changes on health and find interventions for improving code + health +
  • +
  • Efficiently tackle tech debt from legacy systems and acquisitions
  • +
+ + Request a demo + +
+
+
+

+ With the help of Sourcegraph, we were able to quickly look at all clients of an API and + remove unused attributes that lived in different repositories, ultimately simplifying + our APIs and speeding up developer iteration time. +

+
Justin Phillips, Software Engineer, Lyft
+
+ + + Lyft + + +
+
+
+
+
+ +
+ + +
+
+) + +export default UseCases diff --git a/yarn.lock b/yarn.lock index bc2fa573..5d73a7cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -388,6 +388,92 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9" integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA== +"@react-spring/animated@~9.4.3-beta.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.4.3.tgz#2f8d2b50dfc1975fa490ed3bc03f5ad865180866" + integrity sha512-hKKmeXPoGpJ/zrG/RC8stwW8PmMH0BbewHD8aUPLbyzD9fNvZEJ0mjKmOI0CcSwMpb43kuwY2nX3ZJVImPQCoQ== + dependencies: + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/core@~9.4.0", "@react-spring/core@~9.4.3-beta.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.4.3.tgz#95c883fa53ff534ff882ba42f863a26a26a6a1c8" + integrity sha512-Jr6/GjHwXYxAtttcYDXOtH36krO0XGjYaSsGR6g+vOUO4y0zAPPXoAwpK6vS7Haip5fRwk7rMdNG+OzU7bB4Bg== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/rafz" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/konva@~9.4.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/konva/-/konva-9.4.3.tgz#ef5332fc0960fa4313ac0ab6a122fd9247b3b111" + integrity sha512-JWxx0YIwipjJTDs7q9XtArlBCTjejyAJZrbhvxmizOM6ZukUj8hcEFYU03Vt5HUTSC4WfG0rkg2O9V1EAXuzCQ== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/core" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/native@~9.4.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/native/-/native-9.4.3.tgz#748ee1f588c1515a76766e319aa48151308bd5ad" + integrity sha512-dfOwzSxJcbHKTNJ26pceZ7xCrqf2+L6W/U17/7aogQwGec4yf1zocWXV3QS+h0HDuY0Bk/yYa7PEy+D+HWc7Og== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/core" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/rafz@~9.4.3-beta.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.4.3.tgz#0d578072c9692ef5ab74a3b1d49c1432dce32ab6" + integrity sha512-KnujiZNIHzXsRq1D4tVbCajl8Lx+e6vtvUk7o69KbuneSpEgil9P/x3b+hMDk8U0NHGhJjzhU7723/CNsQansA== + +"@react-spring/shared@~9.4.3-beta.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.4.3.tgz#86e03ddd47911ba89be1d0f5a6d11966e305ee04" + integrity sha512-mB1UUD/pl1LzaY0XeNWZtvJzxMa8gLQf02nY12HAz4Rukm9dFRj0jeYwQYLdfYLsGFo1ldvHNurun6hZMG7kiQ== + dependencies: + "@react-spring/rafz" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/three@~9.4.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.4.3.tgz#1836ea12f7cb7ccb4c4a1f39101f4fb17955c386" + integrity sha512-AhCPqoZZXUnzVcKal01sdYBRqkVd2iNxDMk7BGXZsQNWeqaOMaaBT/a6d3oG3wwPX6xIa9ogBtzmzEasN6HYzA== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/core" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/types@~9.4.3-beta.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.4.3.tgz#8926d7a09812374127b1f8a904a755c7579124e6" + integrity sha512-dzJrPvUc42K2un9y6D1IsrPQO5tKsbWwUo+wsATnXjG3ePWyuDBIOMJuPe605NhIXUmPH+Vik2wMoZz06hD1uA== + +"@react-spring/web@~9.4.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.4.3.tgz#b59c1491de344545590598b7fde52b607c4e5d10" + integrity sha512-llKve/uJ73JVagBAVvA74S/LfZP4oSB3XP1qmggSUNXzPZZo5ylIMrs55PxpLyxgzzihuhDU5N17ct3ATViOHw== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/core" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + +"@react-spring/zdog@~9.4.0": + version "9.4.3" + resolved "https://registry.yarnpkg.com/@react-spring/zdog/-/zdog-9.4.3.tgz#0a76564ea635ab00a1720a3843faf4f46ca3c82a" + integrity sha512-ujRJBKEWC6miwPhCwHkn13h9OfqK+Kkq49crebo5neY4kCK2efNoagQo54DwXFgbVNFJV+6GwcAZVI2ybS5L1Q== + dependencies: + "@react-spring/animated" "~9.4.3-beta.0" + "@react-spring/core" "~9.4.3-beta.0" + "@react-spring/shared" "~9.4.3-beta.0" + "@react-spring/types" "~9.4.3-beta.0" + "@restart/context@^2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" @@ -2468,6 +2554,18 @@ react-overlays@^5.0.1: uncontrollable "^7.2.1" warning "^4.0.3" +react-spring@9.4.2: + version "9.4.2" + resolved "https://registry.yarnpkg.com/react-spring/-/react-spring-9.4.2.tgz#71fcbe2d317fae9271058c8b70823af0c3b8ad4d" + integrity sha512-mK9xdq1kAhbe5YpP4EG2IzRa2C1M1UfR/MO1f83PE+IpHwCm1nGQhteF3MGyX6I3wnkoBWTXbY6n4443Dp52Og== + dependencies: + "@react-spring/core" "~9.4.0" + "@react-spring/konva" "~9.4.0" + "@react-spring/native" "~9.4.0" + "@react-spring/three" "~9.4.0" + "@react-spring/web" "~9.4.0" + "@react-spring/zdog" "~9.4.0" + react-transition-group@^4.4.1: version "4.4.2" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" From 30911e87923a6b057007e31457a90bff056764e1 Mon Sep 17 00:00:00 2001 From: Brett Hayes Date: Wed, 2 Mar 2022 18:21:24 -0500 Subject: [PATCH 3/5] use cases and 404 page fixes --- src/pages/404/404.module.scss | 24 ++++++++++++ src/pages/{404.tsx => 404/index.tsx} | 8 ++-- .../{use-cases.tsx => use-cases/index.tsx} | 38 ++++++++++--------- src/pages/use-cases/useCases.module.scss | 12 ++++++ src/styles/globals.scss | 2 - src/styles/pages/_404.scss | 30 --------------- src/styles/pages/_use-cases.scss | 15 -------- 7 files changed, 61 insertions(+), 68 deletions(-) create mode 100644 src/pages/404/404.module.scss rename src/pages/{404.tsx => 404/index.tsx} (61%) rename src/pages/{use-cases.tsx => use-cases/index.tsx} (94%) create mode 100644 src/pages/use-cases/useCases.module.scss delete mode 100644 src/styles/pages/_404.scss delete mode 100644 src/styles/pages/_use-cases.scss diff --git a/src/pages/404/404.module.scss b/src/pages/404/404.module.scss new file mode 100644 index 00000000..6f0f8f67 --- /dev/null +++ b/src/pages/404/404.module.scss @@ -0,0 +1,24 @@ +.errorPage { + flex: 1 0 auto; + padding: 15% 4rem 25% 4rem; + background: url('/c-sprinkles-blank.svg'); + background-size: cover; +} + +.circle { + height: 8rem; + width: 8rem; + margin: 0 auto; + background: #afbcd4; +} + +.icon { + height: 8rem; + width: 8rem; + + svg { + height: 8rem; + width: 8rem; + fill: #e4e9f1; + } +} diff --git a/src/pages/404.tsx b/src/pages/404/index.tsx similarity index 61% rename from src/pages/404.tsx rename to src/pages/404/index.tsx index 1c8edafb..3806d6cb 100644 --- a/src/pages/404.tsx +++ b/src/pages/404/index.tsx @@ -3,11 +3,13 @@ import React from 'react' import { Layout } from '@components' +import styles from './404.module.scss' + const Custom404: React.FunctionComponent = () => ( -
-
-
+
+
+
diff --git a/src/pages/use-cases.tsx b/src/pages/use-cases/index.tsx similarity index 94% rename from src/pages/use-cases.tsx rename to src/pages/use-cases/index.tsx index 3103ea09..a7af798e 100644 --- a/src/pages/use-cases.tsx +++ b/src/pages/use-cases/index.tsx @@ -4,7 +4,9 @@ import Link from 'next/link' import React from 'react' import { Layout, ContentSection, CustomerLogosSectionAnimated, TrySourcegraph } from '@components' -import { stringToDashCase } from '@util' +import { stringToKebabCase } from '@util' + +import styles from './useCases.module.scss' const features: string[] = [ 'Find and fix security vulnerabilities', @@ -22,9 +24,9 @@ const UseCases: React.FunctionComponent = () => ( 'See how the most productive dev teams use Sourcegraph to build software you rely on. From remediating vulnerabilities to streamlining code reuse, our customers use Sourcegraph to solve big code problems.', image: 'https://about.sourcegraph.com/sourcegraph-og.png', }} - heroAndHeaderClassName="use-cases-page__header-and-hero" + heroAndHeaderClassName={styles.headerAndHero} hero={ -
+

Our customers move faster with Sourcegraph

@@ -35,7 +37,7 @@ const UseCases: React.FunctionComponent = () => (
-

+

See how customers use Sourcegraph to

@@ -43,8 +45,8 @@ const UseCases: React.FunctionComponent = () => ( {features.map((feature: string) => ( {feature} @@ -56,7 +58,7 @@ const UseCases: React.FunctionComponent = () => (
} > -
+

@@ -76,7 +78,7 @@ const UseCases: React.FunctionComponent = () => (
  • Automate fixing, merging, and deploying changes with{' '} - Batch Changes + Batch Changes
  • Alert for known vulnerabilities and risky code changes with code monitoring
  • @@ -97,8 +99,8 @@ const UseCases: React.FunctionComponent = () => (

    David Haynes, Security Engineer at Cloudflare
    - - + + (
    Owen Kim, Senior Software Engineer, Convoy
    - - + + Convoy @@ -208,8 +210,8 @@ const UseCases: React.FunctionComponent = () => (

    Simon Law, Staff Software Engineer, Quantcast
    - - + + Quantcast @@ -233,8 +235,8 @@ const UseCases: React.FunctionComponent = () => (

    Joseph Majesky, Software Engineer, FactSet
    - - + + FactSet @@ -317,8 +319,8 @@ const UseCases: React.FunctionComponent = () => (

    Justin Phillips, Software Engineer, Lyft
    - - + + Lyft diff --git a/src/pages/use-cases/useCases.module.scss b/src/pages/use-cases/useCases.module.scss new file mode 100644 index 00000000..3ab1bf6c --- /dev/null +++ b/src/pages/use-cases/useCases.module.scss @@ -0,0 +1,12 @@ +.headerAndHero { + background: url('/customers-page-bg.svg') no-repeat; + background-size: cover; +} + +.seeHow { + font-size: 1.25rem; +} + +.listGroupItem { + background-color: rgba(255, 255, 255, 0.75); +} diff --git a/src/styles/globals.scss b/src/styles/globals.scss index dcbffa6f..5926694e 100644 --- a/src/styles/globals.scss +++ b/src/styles/globals.scss @@ -248,7 +248,6 @@ table { @import 'components/PrismTheme'; @import 'components/TestimonialCarousel'; @import 'components/Tweets'; -@import 'pages/404'; @import 'pages/about'; @import 'pages/batch-changes'; @import 'pages/cloud-beta'; @@ -271,7 +270,6 @@ table { @import 'pages/support'; @import 'pages/uninstall'; @import 'pages/universal-code-search'; -@import 'pages/use-cases'; @import 'templates/PostTemplate'; @import 'pages/dev-tools-quiz'; diff --git a/src/styles/pages/_404.scss b/src/styles/pages/_404.scss deleted file mode 100644 index f8d704a5..00000000 --- a/src/styles/pages/_404.scss +++ /dev/null @@ -1,30 +0,0 @@ -// stylelint-disable declaration-property-unit-whitelist - -.error-page { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - flex: 1 0 auto; - padding: 15% 4rem 25% 4rem; - background: url('/c-sprinkles-blank.svg'); - background-size: cover; - - &__circle { - height: 8rem; - width: 8rem; - margin: 0 auto; - background: #afbcd4; - } - - &__icon { - height: 8rem; - width: 8rem; - margin: 0 auto; - svg { - height: 8rem; - width: 8rem; - fill: #e4e9f1; - } - } -} diff --git a/src/styles/pages/_use-cases.scss b/src/styles/pages/_use-cases.scss deleted file mode 100644 index 188404e7..00000000 --- a/src/styles/pages/_use-cases.scss +++ /dev/null @@ -1,15 +0,0 @@ -.use-cases-page { - &__header-and-hero { - background: url('/customers-page-bg.svg') no-repeat; - background-size: cover; - } - &__see-how { - font-size: 1.25rem; - } - .list-group-item { - background-color: rgba(255, 255, 255, 0.75); - display: flex; - justify-content: space-between; - align-items: center; - } -} From e2167933b9e2a4145e354acc94f87b7ef826e683 Mon Sep 17 00:00:00 2001 From: Brett Hayes Date: Wed, 2 Mar 2022 19:31:02 -0500 Subject: [PATCH 4/5] updating logos section via sourcegraph/about#5173 --- public/external-logos/mercado-libre.svg | 1 + src/components/CustomerLogosSectionAnimated.tsx | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 public/external-logos/mercado-libre.svg diff --git a/public/external-logos/mercado-libre.svg b/public/external-logos/mercado-libre.svg new file mode 100644 index 00000000..15897e60 --- /dev/null +++ b/public/external-logos/mercado-libre.svg @@ -0,0 +1 @@ + diff --git a/src/components/CustomerLogosSectionAnimated.tsx b/src/components/CustomerLogosSectionAnimated.tsx index 28c30551..d79bafee 100644 --- a/src/components/CustomerLogosSectionAnimated.tsx +++ b/src/components/CustomerLogosSectionAnimated.tsx @@ -132,8 +132,8 @@ const ITEMS: { url: '/external-logos/workiva-vector-logo.svg', }, { - name: 'Apex Clearing', - url: '/external-logos/apex-clearing-logo.png', + name: 'Mercado Libre', + url: '/external-logos/mercado-libre.svg', }, { name: 'Blend', @@ -167,6 +167,10 @@ const ITEMS: { name: 'Twilio', url: '/external-logos/twilio-segment-horizontal-darkacai-logo.svg', }, + { + name: 'Apex Clearing', + url: '/external-logos/apex-clearing-logo.png', + }, ] interface Props { From d7a21dd56c95d5e8e1fc0012be20bf9de36dc0ee Mon Sep 17 00:00:00 2001 From: Brett Hayes Date: Mon, 14 Mar 2022 17:20:04 -0400 Subject: [PATCH 5/5] rm logos section and fix linting errors --- .../CustomerLogosSectionAnimated.tsx | 476 ------------------ src/components/index.ts | 1 - src/pages/use-cases/index.tsx | 12 +- 3 files changed, 5 insertions(+), 484 deletions(-) delete mode 100644 src/components/CustomerLogosSectionAnimated.tsx diff --git a/src/components/CustomerLogosSectionAnimated.tsx b/src/components/CustomerLogosSectionAnimated.tsx deleted file mode 100644 index d79bafee..00000000 --- a/src/components/CustomerLogosSectionAnimated.tsx +++ /dev/null @@ -1,476 +0,0 @@ -import ArrowRightBoxIcon from 'mdi-react/ArrowRightBoxIcon' -import React, { useRef, useState, useEffect } from 'react' -import { useSpring, animated } from 'react-spring' - -const ITEMS: { - name: string - url: string - link?: { - url: string - target?: string - rel?: string - } -}[] = [ - { - name: 'Amazon', - url: '/external-logos/amazon-logo.svg', - }, - { - name: 'Dropbox', - url: '/external-logos/dropbox-logo.svg', - }, - { - name: 'Cloudflare', - url: '/external-logos/cloudflare-color-logo.svg', - }, - { - name: 'GE', - url: '/external-logos/general-electric-logo.svg', - }, - { - name: 'Reddit', - url: '/external-logos/reddit-logo.png', - }, - { - name: 'Paypal', - url: '/external-logos/paypal-logo.svg', - }, - { - name: 'Indeed', - url: '/external-logos/indeed-logo.svg', - }, - { - name: 'Uber', - url: '/external-logos/uber.svg', - }, - { - name: 'Plaid', - url: '/external-logos/plaid-logo.svg', - }, - { - name: 'Lyft', - url: '/external-logos/lyft-logo.svg', - }, - { - name: 'Unity', - url: '/external-logos/unity.svg', - }, - { - name: 'Collective Health', - url: '/external-logos/collective-health-logo.svg', - }, - { - name: 'F5', - url: '/external-logos/f5-logo.svg', - }, - { - name: 'Qualtrics', - url: '/external-logos/qualtrics-logo.svg', - }, - { - name: 'Toast', - url: '/external-logos/toast-logo.svg', - }, - { - name: 'SoFi', - url: '/external-logos/sofi-logo.svg', - }, - { - name: 'Yelp', - url: '/external-logos/yelp.svg', - }, - { - name: 'Prezi', - url: '/external-logos/prezi-logo.svg', - }, - { - name: 'Thought Machine', - url: '/external-logos/thought-machine-logo.svg', - }, - { - name: 'Adidas Running', - url: '/external-logos/adidas-runtastic-sq-logo.svg', - }, - { - name: 'Nutanix', - url: '/external-logos/nutanix-logo.svg', - }, - { - name: 'Quantcast', - url: '/external-logos/quantcast-logo.svg', - }, - { - name: 'Criteo', - url: '/external-logos/criteo-logo.svg', - }, - { - name: 'Convoy', - url: '/external-logos/convoy-logo.svg', - }, - { - name: 'Eventbrite', - url: '/external-logos/eventbrite.png', - }, - { - name: 'Cornerstone OnDemand', - url: '/external-logos/cornerstone-ondemand-logo.svg', - }, - { - name: 'Skelter Labs', - url: '/external-logos/skelter-labs-logo.svg', - }, - { - name: 'Factset', - url: '/external-logos/factset-logo.svg', - }, - { - name: 'Cambridge University Press', - url: '/external-logos/cambridge-university-press-logo.svg', - }, - { - name: 'Workiva', - url: '/external-logos/workiva-vector-logo.svg', - }, - { - name: 'Mercado Libre', - url: '/external-logos/mercado-libre.svg', - }, - { - name: 'Blend', - url: '/external-logos/blend.svg', - }, - { - name: 'AppLovin', - url: '/external-logos/applovin-logo.svg', - }, - { - name: 'TripActions', - url: '/external-logos/tripactions-logo.svg', - }, - { - name: 'Mercari', - url: '/external-logos/mercari.svg', - }, - { - name: 'Handy', - url: '/external-logos/handy-logo.svg', - }, - { - name: 'Capella Space', - url: '/external-logos/capella_space.svg', - }, - { - name: 'Motley Fool', - url: '/external-logos/motley_fool.svg', - }, - { - name: 'Twilio', - url: '/external-logos/twilio-segment-horizontal-darkacai-logo.svg', - }, - { - name: 'Apex Clearing', - url: '/external-logos/apex-clearing-logo.png', - }, -] - -interface Props { - showButton: boolean - className: String - showSection: boolean -} - -export const CustomerLogosSectionAnimated: React.FC = ({ showButton, className, showSection }) => { - const [buttonClass, setButtonClass] = useState('') - const [windowWidth, setWindowWidth] = useState(0) - const [imagesWidth, setImagesWidth] = useState(0) - const [scrollAnimation, setScrollAnimation] = useState(false) - const [readyToScroll, setReadyToScroll] = useState(false) - - const innerContainerRef = useRef(null) - const firstLogoContainerRef = useRef(null) - const secondLogoContainerRefClone = useRef(null) - const thirdLogoContainerRefClone = useRef(null) - const [{ x, y, scale }, set] = useSpring(() => ({ x: 0, y: 0, scale: 0 })) - const minDeviceWidth = 991 - const animationTimeInSeconds = 25 - let extraSpace = 0 - if (ITEMS.length % 3 !== 0) { - extraSpace = 135 - } - - useEffect(() => { - setWindowWidth(window.innerWidth) - window.addEventListener('resize', adjustWindowWidth) - return () => { - window.removeEventListener('resize', adjustWindowWidth) - } - }, []) - - useEffect(() => { - let promises = ITEMS.map(image => { - return new Promise((resolve, _) => { - const imageRef = new Image() - imageRef.onload = function () { - if (this.height && this.width) { - let calculatedWidth = (this.width / this.height) * 50 - if (calculatedWidth > 135) calculatedWidth = 135 - setImagesWidth(prevState => (prevState += calculatedWidth + 70)) //Total width of all images - } else { - setImagesWidth(prevState => (prevState += 135 + 70)) - } - resolve() - } - imageRef.src = image.url - }) - }) - Promise.all(promises).then(() => { - const logoElement = document.getElementById('logo-container-reference')! - logoElement.classList.remove('hidden') - const secondLogoContainerClone = logoElement.cloneNode(true) - const thirdLogoContainerClone = logoElement.cloneNode(true) - logoElement?.parentNode?.insertBefore(secondLogoContainerClone, logoElement.nextSibling) - logoElement?.parentNode?.insertBefore(thirdLogoContainerClone, logoElement.nextSibling) - secondLogoContainerRefClone.current = secondLogoContainerClone - thirdLogoContainerRefClone.current = thirdLogoContainerClone - setReadyToScroll(true) - }) - }, []) - - useEffect(() => { - if (scrollAnimation) { - startAnimation() - } - }, [scrollAnimation]) - - useEffect(() => { - if (readyToScroll && windowWidth < minDeviceWidth) { - setTimeout(() => { - startAnimation() - }, 500) - } - }, [readyToScroll]) - - useEffect(() => { - if ( - firstLogoContainerRef.current && - secondLogoContainerRefClone.current && - thirdLogoContainerRefClone.current - ) { - if (windowWidth > minDeviceWidth) { - innerContainerRef.current!.addEventListener('mouseenter', handleMouseEnter) - innerContainerRef.current!.addEventListener('mousemove', handleMouseMove) - innerContainerRef.current!.addEventListener('mouseleave', handleMouseLeaveInnerArea) - } - } - }, [ - firstLogoContainerRef.current, - secondLogoContainerRefClone.current, - thirdLogoContainerRefClone.current, - scrollAnimation, - ]) - - function adjustWindowWidth() { - setWindowWidth(window.innerWidth) - } - - function startAnimation() { - let logoElement = document.getElementById('logo-container-reference')! - logoElement.addEventListener('transitionend', transitionEnd) - transitionStart() - } - - function transitionStart() { - const logoContainerOne = firstLogoContainerRef.current! - const logoContainerTwo = secondLogoContainerRefClone.current! - const logoContainerThree = thirdLogoContainerRefClone.current! - let totalWidth = imagesWidth / 3 + 30 + extraSpace - - logoContainerOne.style.transition = `${animationTimeInSeconds}s linear` - logoContainerTwo.style.transition = `${animationTimeInSeconds}s linear` - logoContainerThree.style.transition = `${animationTimeInSeconds}s linear` - logoContainerOne.style.transform = `translateX(${-totalWidth}px)` - logoContainerTwo.style.transform = `translateX(${-totalWidth}px)` - logoContainerThree.style.transform = `translateX(${-totalWidth}px)` - } - - function transitionEnd(e) { - if (e.target.id !== 'logo-container-reference') return - const logoContainerOne = firstLogoContainerRef.current! - const logoContainerTwo = secondLogoContainerRefClone.current! - const logoContainerThree = thirdLogoContainerRefClone.current! - logoContainerOne.style.transition = 'none' - logoContainerTwo.style.transition = 'none' - logoContainerThree.style.transition = 'none' - logoContainerOne.style.transform = `translateX(0px)` - logoContainerTwo.style.transform = `translateX(0px)` - logoContainerThree.style.transform = `translateX(0px)` - setTimeout(() => { - transitionStart() - }, 0) - } - - function pauseAnimation() { - const logoContainerOne = firstLogoContainerRef.current! - const logoContainerTwo = secondLogoContainerRefClone.current! - const logoContainerThree = thirdLogoContainerRefClone.current! - let transformOne = window.getComputedStyle(logoContainerOne).transform - let transformTwo = window.getComputedStyle(logoContainerTwo).transform - let transformThree = window.getComputedStyle(logoContainerThree).transform - - logoContainerOne.style.transform = transformOne - logoContainerTwo.style.transform = transformTwo - logoContainerThree.style.transform = transformThree - - logoContainerOne.style.transition = 'none' - logoContainerTwo.style.transition = 'none' - logoContainerThree.style.transition = 'none' - } - - function continueAnimationFromCurrentPosition() { - const logoContainerOne = firstLogoContainerRef.current! - const logoContainerTwo = secondLogoContainerRefClone.current! - const logoContainerThree = thirdLogoContainerRefClone.current! - - let transformOne = window.getComputedStyle(logoContainerOne).transform - let matrixValueXOne = transformOne.match(/matrix.*\((.+)\)/)[1].split(', ')[4] - let totalWidth = imagesWidth / 3 + 30 + extraSpace - let xPosition = parseInt(matrixValueXOne) - let newPosition = -totalWidth - xPosition - - const pixelsPersecond = Math.abs(totalWidth) / animationTimeInSeconds - const newpositiontime = (Math.abs(newPosition) / pixelsPersecond).toString() - - logoContainerOne.style.transition = `${newpositiontime}s linear` - logoContainerTwo.style.transition = `${newpositiontime}s linear` - logoContainerThree.style.transition = `${newpositiontime}s linear` - - logoContainerOne.style.transform = `translateX(${-totalWidth}px)` - logoContainerTwo.style.transform = `translateX(${-totalWidth}px)` - logoContainerThree.style.transform = `translateX(${-totalWidth}px)` - } - - function buttonFollowsMouse(e) { - const containerRec = innerContainerRef.current?.getBoundingClientRect() - if ( - e.clientX - containerRec?.left! > 150 && - e.clientY - containerRec?.top! > 60 && - containerRec?.left! + innerContainerRef.current?.offsetWidth! - e.clientX > 150 && - containerRec?.top! + innerContainerRef.current?.offsetHeight! - e.clientY > 60 - ) { - setButtonClass('') - set({ scale: 1 }) - } else { - setButtonClass('sourcegraph-cta-button-edge') - set({ scale: 0.1 }) - } - set({ - x: e.clientX - containerRec?.left! + innerContainerRef.current?.scrollLeft!, - y: e.clientY - containerRec?.top!, - }) - } - - function handleMouseEnter() { - if (readyToScroll) { - if (!scrollAnimation) { - setScrollAnimation(true) - } else { - continueAnimationFromCurrentPosition() - } - } - } - - function handleMouseMove(e) { - if (showButton && readyToScroll) buttonFollowsMouse(e) - } - - function handleMouseLeaveInnerArea() { - if (readyToScroll) { - pauseAnimation() - if (showButton) set({ scale: 0 }) - } - } - - return ( -
    - {showSection && ( -

    - Our customers use Sourcegraph every day to build software you rely on. -

    - )} - {!showButton && ( - - )} -
    - {windowWidth > minDeviceWidth && showButton && ( - - `scale(${s}) translate(-50%, -50%)`), - }} - > - Learn how customers
    use Sourcegraph -
    -
    - )} -
    - {ITEMS.map((logo, i) => ( -
    - {logo.link ? ( - - minDeviceWidth - ? 'customer-logos-section__item-logo-animation' - : 'link-hover') - } - src={logo.url} - alt={logo.name} - /> - - ) : ( - minDeviceWidth - ? 'customer-logos-section__item-logo-animation' - : '') - } - src={logo.url} - alt={logo.name} - /> - )} -
    - ))} -
    -
    - - {windowWidth < minDeviceWidth && showButton && ( - - )} -
    - ) -} diff --git a/src/components/index.ts b/src/components/index.ts index 772d9c64..f6b9b2fe 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -3,7 +3,6 @@ export { Layout } from './Layout' export { ContentSection } from './ContentSection' export { Jumbotron } from './Jumbotron' export { RequestDemoForm } from './RequestDemoForm' -export { CustomerLogosSectionAnimated } from './CustomerLogosSectionAnimated' export { TrySourcegraph } from './TrySourcegraph' // Actions diff --git a/src/pages/use-cases/index.tsx b/src/pages/use-cases/index.tsx index a7af798e..8baaf275 100644 --- a/src/pages/use-cases/index.tsx +++ b/src/pages/use-cases/index.tsx @@ -3,7 +3,7 @@ import ArrowRightIcon from 'mdi-react/ArrowRightIcon' import Link from 'next/link' import React from 'react' -import { Layout, ContentSection, CustomerLogosSectionAnimated, TrySourcegraph } from '@components' +import { Layout, ContentSection, TrySourcegraph } from '@components' import { stringToKebabCase } from '@util' import styles from './useCases.module.scss' @@ -59,12 +59,10 @@ const UseCases: React.FunctionComponent = () => ( } >
    - + {/* Todo: Add new Customer Logos Section when homepage updates are finalized */} -
    - - -
    + +

    Find and fix security vulnerabilities

    Find, fix, and track vulnerable code quickly across your entire codebase.
    @@ -261,7 +259,7 @@ const UseCases: React.FunctionComponent = () => (
  • Safely and efficiently maintain code that is being reused and easily make changes - everywhere with Batch Changes + everywhere with Batch Changes
  • Add a code monitor to alert you of commits using an out-of-date library