-
Notifications
You must be signed in to change notification settings - Fork 55
SaraEnderborg-js-project-portfolio #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a876cf8
2b6f4a1
89683ea
39e56c9
9353571
a5a4833
0a566ae
7a237d9
1bb6de4
f7c75bb
649d82d
e619db8
efbc0c8
eb1908f
094c2c9
b9d6a64
f44a335
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,3 @@ | ||
| Netlify: https://portfolio-saraenderborg.netlify.app/ | ||
| Figma:https://www.figma.com/design/er7xor6mcZzPVT8ZM0tY0w/Portfolio-designs?node-id=10817-954&t=SPZgu2bO284eVn9U-0 | ||
| # Portfolio |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none"> | ||
| <path d="M12.1094 22.6562C12.1094 22.5625 12.0156 22.4688 11.875 22.4688C11.7344 22.4688 11.6406 22.5625 11.6406 22.6562C11.6406 22.75 11.7344 22.8438 11.875 22.7969C12.0156 22.7969 12.1094 22.75 12.1094 22.6562ZM10.6562 22.4219C10.6562 22.5156 10.75 22.6562 10.8906 22.6562C10.9844 22.7031 11.125 22.6562 11.1719 22.5625C11.1719 22.4688 11.125 22.375 10.9844 22.3281C10.8438 22.2812 10.7031 22.3281 10.6562 22.4219ZM12.7656 22.375C12.625 22.375 12.5312 22.4688 12.5312 22.6094C12.5312 22.7031 12.6719 22.75 12.8125 22.7031C12.9531 22.6562 13.0469 22.6094 13 22.5156C13 22.4219 12.8594 22.3281 12.7656 22.375ZM15.8125 4.375C9.34375 4.375 4.375 9.34375 4.375 15.8125C4.375 21.0156 7.60938 25.4688 12.2969 27.0625C12.9062 27.1562 13.0938 26.7812 13.0938 26.5C13.0938 26.1719 13.0938 24.5781 13.0938 23.5938C13.0938 23.5938 9.8125 24.2969 9.10938 22.1875C9.10938 22.1875 8.59375 20.8281 7.84375 20.5C7.84375 20.5 6.76562 19.75 7.89062 19.75C7.89062 19.75 9.0625 19.8438 9.71875 20.9688C10.75 22.7969 12.4375 22.2812 13.1406 21.9531C13.2344 21.2031 13.5156 20.6875 13.8906 20.3594C11.2656 20.0781 8.59375 19.7031 8.59375 15.2031C8.59375 13.8906 8.96875 13.2812 9.71875 12.4375C9.57812 12.1094 9.20312 10.8906 9.85938 9.25C10.7969 8.96875 13.0938 10.5156 13.0938 10.5156C14.0312 10.2344 15.0156 10.1406 16 10.1406C17.0312 10.1406 18.0156 10.2344 18.9531 10.5156C18.9531 10.5156 21.2031 8.92188 22.1875 9.25C22.8438 10.8906 22.4219 12.1094 22.3281 12.4375C23.0781 13.2812 23.5469 13.8906 23.5469 15.2031C23.5469 19.7031 20.7812 20.0781 18.1562 20.3594C18.5781 20.7344 18.9531 21.4375 18.9531 22.5625C18.9531 24.1094 18.9062 26.0781 18.9062 26.4531C18.9062 26.7812 19.1406 27.1562 19.75 27.0156C24.4375 25.4688 27.625 21.0156 27.625 15.8125C27.625 9.34375 22.3281 4.375 15.8125 4.375ZM8.92188 20.5469C8.82812 20.5938 8.875 20.7344 8.92188 20.8281C9.01562 20.875 9.10938 20.9219 9.20312 20.875C9.25 20.8281 9.25 20.6875 9.15625 20.5938C9.0625 20.5469 8.96875 20.5 8.92188 20.5469ZM8.40625 20.1719C8.35938 20.2656 8.40625 20.3125 8.5 20.3594C8.59375 20.4062 8.6875 20.4062 8.73438 20.3125C8.73438 20.2656 8.6875 20.2188 8.59375 20.1719C8.5 20.125 8.45312 20.125 8.40625 20.1719ZM9.90625 21.8594C9.85938 21.9062 9.85938 22.0469 10 22.1406C10.0938 22.2344 10.2344 22.2812 10.2812 22.1875C10.3281 22.1406 10.3281 22 10.2344 21.9062C10.1406 21.8125 10 21.7656 9.90625 21.8594ZM9.39062 21.1562C9.29688 21.2031 9.29688 21.3438 9.39062 21.4375C9.48438 21.5312 9.57812 21.5781 9.67188 21.5312C9.71875 21.4844 9.71875 21.3438 9.67188 21.25C9.57812 21.1562 9.48438 21.1094 9.39062 21.1562Z" fill="#FD6F00"/> | ||
| </svg> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,21 @@ | ||
| export const App = () => { | ||
| import Contact from "./sections/Contact/Contact"; | ||
| import Hero from "./sections/Hero/Hero"; | ||
| import Skills from "./sections/Skills/Skills"; | ||
| import Projects from "./sections/Projects/Projects"; | ||
| import Tech from "./sections/Tech/Tech"; | ||
| import Journey from "./sections/Journey/Journey"; | ||
|
|
||
| function App() { | ||
| return ( | ||
| <> | ||
| <h1>Portfolio</h1> | ||
| <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, laborum! Maxime animi nostrum facilis distinctio neque labore consectetur beatae eum ipsum excepturi voluptatum, dicta repellendus incidunt fugiat, consequatur rem aperiam.</p> | ||
| <Hero /> | ||
| <Skills /> | ||
| <Projects /> | ||
| <Tech /> | ||
| <Journey /> | ||
| <Contact /> | ||
| </> | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| export default App; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| export const Github = () => ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| width="32" | ||
| height="32" | ||
| viewBox="0 0 32 32" | ||
| fill="none" | ||
| > | ||
| <path | ||
| d="M12.1094 22.6562C12.1094 22.5625 12.0156 22.4688 11.875 22.4688C11.7344 22.4688 11.6406 22.5625 11.6406 22.6562C11.6406 22.75 11.7344 22.8438 11.875 22.7969C12.0156 22.7969 12.1094 22.75 12.1094 22.6562ZM10.6562 22.4219C10.6562 22.5156 10.75 22.6562 10.8906 22.6562C10.9844 22.7031 11.125 22.6562 11.1719 22.5625C11.1719 22.4688 11.125 22.375 10.9844 22.3281C10.8438 22.2812 10.7031 22.3281 10.6562 22.4219ZM12.7656 22.375C12.625 22.375 12.5312 22.4688 12.5312 22.6094C12.5312 22.7031 12.6719 22.75 12.8125 22.7031C12.9531 22.6562 13.0469 22.6094 13 22.5156C13 22.4219 12.8594 22.3281 12.7656 22.375ZM15.8125 4.375C9.34375 4.375 4.375 9.34375 4.375 15.8125C4.375 21.0156 7.60938 25.4688 12.2969 27.0625C12.9062 27.1562 13.0938 26.7812 13.0938 26.5C13.0938 26.1719 13.0938 24.5781 13.0938 23.5938C13.0938 23.5938 9.8125 24.2969 9.10938 22.1875C9.10938 22.1875 8.59375 20.8281 7.84375 20.5C7.84375 20.5 6.76562 19.75 7.89062 19.75C7.89062 19.75 9.0625 19.8438 9.71875 20.9688C10.75 22.7969 12.4375 22.2812 13.1406 21.9531C13.2344 21.2031 13.5156 20.6875 13.8906 20.3594C11.2656 20.0781 8.59375 19.7031 8.59375 15.2031C8.59375 13.8906 8.96875 13.2812 9.71875 12.4375C9.57812 12.1094 9.20312 10.8906 9.85938 9.25C10.7969 8.96875 13.0938 10.5156 13.0938 10.5156C14.0312 10.2344 15.0156 10.1406 16 10.1406C17.0312 10.1406 18.0156 10.2344 18.9531 10.5156C18.9531 10.5156 21.2031 8.92188 22.1875 9.25C22.8438 10.8906 22.4219 12.1094 22.3281 12.4375C23.0781 13.2812 23.5469 13.8906 23.5469 15.2031C23.5469 19.7031 20.7812 20.0781 18.1562 20.3594C18.5781 20.7344 18.9531 21.4375 18.9531 22.5625C18.9531 24.1094 18.9062 26.0781 18.9062 26.4531C18.9062 26.7812 19.1406 27.1562 19.75 27.0156C24.4375 25.4688 27.625 21.0156 27.625 15.8125C27.625 9.34375 22.3281 4.375 15.8125 4.375ZM8.92188 20.5469C8.82812 20.5938 8.875 20.7344 8.92188 20.8281C9.01562 20.875 9.10938 20.9219 9.20312 20.875C9.25 20.8281 9.25 20.6875 9.15625 20.5938C9.0625 20.5469 8.96875 20.5 8.92188 20.5469ZM8.40625 20.1719C8.35938 20.2656 8.40625 20.3125 8.5 20.3594C8.59375 20.4062 8.6875 20.4062 8.73438 20.3125C8.73438 20.2656 8.6875 20.2188 8.59375 20.1719C8.5 20.125 8.45312 20.125 8.40625 20.1719ZM9.90625 21.8594C9.85938 21.9062 9.85938 22.0469 10 22.1406C10.0938 22.2344 10.2344 22.2812 10.2812 22.1875C10.3281 22.1406 10.3281 22 10.2344 21.9062C10.1406 21.8125 10 21.7656 9.90625 21.8594ZM9.39062 21.1562C9.29688 21.2031 9.29688 21.3438 9.39062 21.4375C9.48438 21.5312 9.57812 21.5781 9.67188 21.5312C9.71875 21.4844 9.71875 21.3438 9.67188 21.25C9.57812 21.1562 9.48438 21.1094 9.39062 21.1562Z" | ||
| fill="#FD6F00" | ||
| /> | ||
| </svg> | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| export const Linkedin = () => ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| width="32" | ||
| height="32" | ||
| viewBox="0 0 32 32" | ||
| fill="none" | ||
| > | ||
| <path | ||
| d="M10.1875 25V10.9844H5.82812V25H10.1875ZM7.98438 9.10938C9.39062 9.10938 10.5156 7.9375 10.5156 6.53125C10.5156 5.17188 9.39062 4.04688 7.98438 4.04688C6.625 4.04688 5.5 5.17188 5.5 6.53125C5.5 7.9375 6.625 9.10938 7.98438 9.10938ZM26.4531 25H26.5V17.3125C26.5 13.5625 25.6562 10.6562 21.25 10.6562C19.1406 10.6562 17.7344 11.8281 17.125 12.9062H17.0781V10.9844H12.9062V25H17.2656V18.0625C17.2656 16.2344 17.5938 14.5 19.8438 14.5C22.0938 14.5 22.1406 16.5625 22.1406 18.2031V25H26.4531Z" | ||
| fill="#FD6F00" | ||
| /> | ||
| </svg> | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import styled from "styled-components"; | ||
|
|
||
| const StyledButton = styled.a` | ||
| display: inline-flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
|
|
||
| font-size: ${({ theme }) => theme.typography.button.size}; | ||
| font-weight: ${({ theme }) => theme.typography.button.weight}; | ||
| line-height: ${({ theme }) => theme.typography.button.lineHeight}; | ||
|
|
||
| height: ${({ theme }) => theme.buttons.height}; | ||
| border-radius: ${({ theme }) => theme.buttons.radius}; | ||
| padding: 0 ${({ theme }) => theme.buttons.paddingX}; | ||
| gap: ${({ theme }) => theme.buttons.gap}; | ||
|
|
||
| background-color: ${({ theme, $variant }) => | ||
| theme.colors.button[$variant].bg}; | ||
| color: ${({ theme, $variant }) => theme.colors.button[$variant].text}; | ||
|
|
||
| border: ${({ theme, $variant }) => | ||
| $variant === "secondary" | ||
| ? `2px solid ${theme.colors.button.secondary.border}` | ||
| : "none"}; | ||
|
|
||
| transition: all 0.2s ease; | ||
| cursor: pointer; | ||
|
|
||
| &:hover { | ||
| opacity: 0.9; | ||
| transform: translateY(-2px); | ||
| } | ||
|
|
||
| &:active { | ||
| transform: translateY(0); | ||
| } | ||
| `; | ||
|
|
||
| export default function Button({ | ||
| href, | ||
| children, | ||
| variant = "primary", | ||
| ariaLabel, | ||
| title, | ||
| }) { | ||
| const label = | ||
| ariaLabel || (typeof children === "string" ? children : "Open link"); | ||
| return ( | ||
| <StyledButton | ||
| href={href} | ||
| target="_blank" | ||
| rel="noreferrer" | ||
| $variant={variant} | ||
| aria-label={label} | ||
| title={title || label} | ||
| > | ||
| {children} | ||
| </StyledButton> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| import Button from "./Button"; | ||
| import { Card as StyledCard } from "./Card.styles"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See comment in Card.styles.jsx |
||
|
|
||
| export default function Card({ | ||
| image, | ||
| title, | ||
| description, | ||
| date, | ||
| text, | ||
| demo, | ||
| code, | ||
| link, | ||
| buttonText = "Read more", | ||
| }) { | ||
| return ( | ||
| <StyledCard> | ||
| <img src={image} alt={title} /> | ||
|
|
||
| {date && <p style={{ fontSize: "0.8rem", opacity: 0.6 }}>{date}</p>} | ||
| <h3>{title}</h3> | ||
| <p>{description || text}</p> | ||
|
|
||
| <div style={{ display: "flex", gap: "1rem", flexWrap: "wrap" }}> | ||
| {demo && ( | ||
| <Button | ||
| href={demo} | ||
| variant="primary" | ||
| ariaLabel={`Open live demo for ${title}`} | ||
| > | ||
| Live demo | ||
| </Button> | ||
| )} | ||
|
|
||
| {code && ( | ||
| <Button | ||
| href={code} | ||
| variant="secondary" | ||
| ariaLabel={`${buttonText} about ${title}`} | ||
| > | ||
| View Code | ||
| </Button> | ||
| )} | ||
|
|
||
| {link && ( | ||
| <Button | ||
| href={link} | ||
| variant="secondary" | ||
| ariaLabel={`${buttonText} about ${title}`} | ||
| > | ||
| {buttonText} | ||
| </Button> | ||
| )} | ||
| </div> | ||
| </StyledCard> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import styled from "styled-components"; | ||
|
|
||
| export const Card = styled.article` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be easier to name is StyledCard directly here so you don't have to rename it in the import in Card.jsx :) |
||
| display: flex; | ||
| flex-direction: column; | ||
| height: 100%; | ||
| max-height: 520px; | ||
| background: white; | ||
| padding: 1.5rem; | ||
| border-radius: 16px; | ||
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); | ||
| transition: 0.2s ease; | ||
|
|
||
| &:hover { | ||
| transform: translateY(-3px); | ||
| } | ||
|
|
||
| img { | ||
| width: 100%; | ||
| height: 300px; | ||
| object-fit: cover; | ||
| border-radius: 12px; | ||
| margin-bottom: 16px; | ||
| } | ||
|
|
||
| h3 { | ||
| margin-bottom: 0.5rem; | ||
| font-family: ${({ theme }) => theme.fonts.heading}; | ||
| } | ||
|
|
||
| p { | ||
| margin-bottom: 16px; | ||
| line-height: 1.5; | ||
| font-size: 15px; | ||
| display: -webkit-box; | ||
| -webkit-line-clamp: 3; | ||
| -webkit-box-orient: vertical; | ||
| overflow: hidden; | ||
| } | ||
| `; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| import styled from "styled-components"; | ||
| import { Swiper, SwiperSlide } from "swiper/react"; | ||
| import "swiper/css"; | ||
| import "swiper/css/scrollbar"; | ||
| import { Scrollbar, Mousewheel } from "swiper/modules"; | ||
|
|
||
| export const Carousel = ({ data, renderItem }) => { | ||
| return ( | ||
| <CarouselWrapper> | ||
| <Swiper | ||
| modules={[Scrollbar, Mousewheel]} | ||
| scrollbar={{ draggable: true, hide: false }} | ||
| grabCursor={true} | ||
| mousewheel={{ forceToAxis: true, sensitivity: 1 }} | ||
| spaceBetween={64} | ||
| slidesPerView="auto" | ||
| speed={700} | ||
| freeMode={true} | ||
| watchOverflow={false} | ||
| > | ||
| {data.map((item, index) => ( | ||
| <SwiperSlide key={index} className="slide" tabIndex={0}> | ||
| {renderItem(item, index)} | ||
| </SwiperSlide> | ||
| ))} | ||
| </Swiper> | ||
| </CarouselWrapper> | ||
| ); | ||
| }; | ||
|
|
||
| const CarouselWrapper = styled.div` | ||
| margin-top: 64px; | ||
| padding: 0 64px; | ||
| width: 100%; | ||
| overflow: visible; | ||
|
|
||
| .swiper { | ||
| width: 100%; | ||
| padding-bottom: 80px; | ||
| } | ||
|
|
||
| .swiper-wrapper { | ||
| align-items: stretch; | ||
| } | ||
|
|
||
| .swiper-slide { | ||
| width: 400px !important; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using .swiper-slide.swiper-slide {
width: 400px;
...
} |
||
| height: auto; | ||
| display: flex; | ||
| } | ||
|
|
||
| .swiper-scrollbar { | ||
| height: 12px; | ||
| background: #e5e5e5; | ||
| border-radius: 20px; | ||
| margin: 32px auto 0; | ||
| width: 80%; | ||
| cursor: pointer; | ||
| } | ||
|
|
||
| .swiper-scrollbar-drag { | ||
| background: ${({ theme }) => theme.colors.primary}; | ||
| border-radius: 20px; | ||
| height: 100%; | ||
| cursor: grab; | ||
| } | ||
|
|
||
| .swiper-scrollbar-drag:active { | ||
| cursor: grabbing; | ||
| } | ||
|
|
||
| @media (max-width: 768px) { | ||
| padding: 0 20px; | ||
|
|
||
| .swiper-slide { | ||
| width: 300px !important; | ||
| } | ||
| } | ||
| `; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import styled from "styled-components"; | ||
|
|
||
| const Column = styled.div` | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| gap: 12px; | ||
| text-align: center; | ||
| `; | ||
|
|
||
| const Title = styled.h3` | ||
| font-family: "Poppins", sans-serif; | ||
| font-weight: 500; | ||
| color: #202020; | ||
| margin: 0; | ||
| font-size: clamp(18px, 2vw, 22px); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! using clamp for font sizes is a really nice way of making it smooth. |
||
| `; | ||
|
|
||
| const Item = styled.p` | ||
| font-family: "Poppins", sans-serif; | ||
| color: #202020; | ||
| margin: 0; | ||
| font-size: clamp(13px, 1.5vw, 15px); | ||
| line-height: 1.6; | ||
| `; | ||
|
|
||
| export default function SkillColumn({ title, items }) { | ||
| return ( | ||
| <Column> | ||
| <Title>{title}</Title> | ||
| {items.map((item) => ( | ||
| <Item key={item}>{item}</Item> | ||
| ))} | ||
| </Column> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really clean! A small tip is to maybe add a main-tag, and/or change some sections to to instead be header- and footer elements to improve accessibility scoring on Lighthouse :-)