diff --git a/README.md b/README.md index 200f4282..434e7cd3 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Portfolio + +netlify link: https://carolina-oldertz-portfolio.netlify.app/ \ No newline at end of file diff --git a/index.html b/index.html index 6676fb2d..cbcbcfb4 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,88 @@ - - - - - Portfolio - - -
- - - + + + + + + + + + + + + + + + + + Portfolio + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/package.json b/package.json index 48911600..7ad41f04 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "dependencies": { "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "styled-components": "^6.1.19" }, "devDependencies": { "@eslint/js": "^9.21.0", diff --git a/public/favicon/android-chrome-192x192.png b/public/favicon/android-chrome-192x192.png new file mode 100644 index 00000000..77cd3b46 Binary files /dev/null and b/public/favicon/android-chrome-192x192.png differ diff --git a/public/favicon/android-chrome-512x512.png b/public/favicon/android-chrome-512x512.png new file mode 100644 index 00000000..468a8f04 Binary files /dev/null and b/public/favicon/android-chrome-512x512.png differ diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png new file mode 100644 index 00000000..29bf0805 Binary files /dev/null and b/public/favicon/apple-touch-icon.png differ diff --git a/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png new file mode 100644 index 00000000..ee7bf16d Binary files /dev/null and b/public/favicon/favicon-16x16.png differ diff --git a/public/favicon/favicon-32x32.png b/public/favicon/favicon-32x32.png new file mode 100644 index 00000000..1e64a2d4 Binary files /dev/null and b/public/favicon/favicon-32x32.png differ diff --git a/public/favicon/favicon.ico b/public/favicon/favicon.ico new file mode 100644 index 00000000..cbe5952a Binary files /dev/null and b/public/favicon/favicon.ico differ diff --git a/public/favicon/site.webmanifest b/public/favicon/site.webmanifest new file mode 100644 index 00000000..45dc8a20 --- /dev/null +++ b/public/favicon/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/public/icons/ArrowDown.svg b/public/icons/ArrowDown.svg new file mode 100644 index 00000000..85a85622 --- /dev/null +++ b/public/icons/ArrowDown.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Btn - github.svg b/public/icons/Btn - github.svg new file mode 100644 index 00000000..f4cc66bc --- /dev/null +++ b/public/icons/Btn - github.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Btn - instagram.svg b/public/icons/Btn - instagram.svg new file mode 100644 index 00000000..60fedfbd --- /dev/null +++ b/public/icons/Btn - instagram.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Btn - linkedin.svg b/public/icons/Btn - linkedin.svg new file mode 100644 index 00000000..cd79edde --- /dev/null +++ b/public/icons/Btn - linkedin.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Btn - stackoverflow.svg b/public/icons/Btn - stackoverflow.svg new file mode 100644 index 00000000..b6308076 --- /dev/null +++ b/public/icons/Btn - stackoverflow.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Btn - twitter.svg b/public/icons/Btn - twitter.svg new file mode 100644 index 00000000..fb608bc3 --- /dev/null +++ b/public/icons/Btn - twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Github.svg b/public/icons/Github.svg new file mode 100644 index 00000000..89f5ddb4 --- /dev/null +++ b/public/icons/Github.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/icons/Netlify.svg b/public/icons/Netlify.svg new file mode 100644 index 00000000..e752b728 --- /dev/null +++ b/public/icons/Netlify.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/articles/Article-carerr-change.png b/public/images/articles/Article-carerr-change.png new file mode 100644 index 00000000..0d2d5089 Binary files /dev/null and b/public/images/articles/Article-carerr-change.png differ diff --git a/public/images/articles/Article-imposter.jpg b/public/images/articles/Article-imposter.jpg new file mode 100644 index 00000000..37cca45c Binary files /dev/null and b/public/images/articles/Article-imposter.jpg differ diff --git a/public/images/articles/Article-newbie.jpg b/public/images/articles/Article-newbie.jpg new file mode 100644 index 00000000..848157e8 Binary files /dev/null and b/public/images/articles/Article-newbie.jpg differ diff --git a/public/images/hero/Headshot-heroImg-1.png b/public/images/hero/Headshot-heroImg-1.png new file mode 100644 index 00000000..6f089207 Binary files /dev/null and b/public/images/hero/Headshot-heroImg-1.png differ diff --git a/public/images/hero/Painting-heroImg-3.jpg b/public/images/hero/Painting-heroImg-3.jpg new file mode 100644 index 00000000..826e0fbb Binary files /dev/null and b/public/images/hero/Painting-heroImg-3.jpg differ diff --git a/public/images/hero/SideProfile-heroImg-2.jpg b/public/images/hero/SideProfile-heroImg-2.jpg new file mode 100644 index 00000000..7d9453e5 Binary files /dev/null and b/public/images/hero/SideProfile-heroImg-2.jpg differ diff --git a/public/images/projects/Accesibility-site.png b/public/images/projects/Accesibility-site.png new file mode 100644 index 00000000..40e9d57f Binary files /dev/null and b/public/images/projects/Accesibility-site.png differ diff --git a/public/images/projects/Recipe-library.png b/public/images/projects/Recipe-library.png new file mode 100644 index 00000000..424d19a0 Binary files /dev/null and b/public/images/projects/Recipe-library.png differ diff --git a/public/images/projects/Weather-app.png b/public/images/projects/Weather-app.png new file mode 100644 index 00000000..3aa6a3ab Binary files /dev/null and b/public/images/projects/Weather-app.png differ diff --git a/public/images/projects/business-site.png b/public/images/projects/business-site.png new file mode 100644 index 00000000..79c587b4 Binary files /dev/null and b/public/images/projects/business-site.png differ diff --git a/pull_request_template.md b/pull_request_template.md index 4263c7e8..0fea62c6 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1 +1,3 @@ -Please include a link to your Figma design and a Netlify link. \ No newline at end of file +Please include a link to your Figma design and a Netlify link. + +figma design: https://www.figma.com/design/YFJswIB708jYUoHg3swht2/Portfolio-designs--Copy-?node-id=0-1&p=f&t=lRVOFqJdJeShs1sk-0 \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index a161d8d3..ecea21f1 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,8 +1,33 @@ +import styled, { createGlobalStyle } from "styled-components" +import { HeroSection } from "./components/hero/HeroSection" +import { TechSection } from "./components/Tech/TechSection" +import { ProjectSection } from "./components/projects/ProjectSection" +import { SkillSection } from "./components/Skills/SkillSection" +import { ArticleSection } from "./components/articles/ArticleSection" +import { FooterSection } from "./components/footer/FooterSection" + +const GlobalStyles = createGlobalStyle` +* { +box-sizing: border-box; +} + + +body { +font-family: "Poppins", sans-serif; +margin: 0; +} +` + export const App = () => { return ( <> -

Portfolio

-

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.

+ + + + + + + ) } diff --git a/src/components/Skills/SkillHeading.jsx b/src/components/Skills/SkillHeading.jsx new file mode 100644 index 00000000..2c384579 --- /dev/null +++ b/src/components/Skills/SkillHeading.jsx @@ -0,0 +1,10 @@ +import styled from "styled-components" +import { H2 } from "../typography/H2" + +const StyledHeading = styled(H2)` +color: ${({ theme }) => theme.color.secondary}; +` + +export const SkillHeading = () => { + return Skills +} \ No newline at end of file diff --git a/src/components/Skills/SkillInfo.jsx b/src/components/Skills/SkillInfo.jsx new file mode 100644 index 00000000..f65c5525 --- /dev/null +++ b/src/components/Skills/SkillInfo.jsx @@ -0,0 +1,30 @@ +import styled from "styled-components" +import { P } from "../typography/P" + +const StyledInfoContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + align-items: center; + } + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + align-items: flex-start; + } +` + +export const SkillInfo = ({ info }) => { + const skillItems = info.split('\n') + + return ( + + {skillItems.map((item, index) => ( +

+ {item.trim()} +

+ ))} +
+ ) +} \ No newline at end of file diff --git a/src/components/Skills/SkillInfoCard.jsx b/src/components/Skills/SkillInfoCard.jsx new file mode 100644 index 00000000..89740dab --- /dev/null +++ b/src/components/Skills/SkillInfoCard.jsx @@ -0,0 +1,29 @@ +import styled from "styled-components" +import { SkillInfo } from "./SkillInfo" +import { SkillTags } from "./SkillTags" + +const StyledInfoCard = styled.div` +display: flex; +width: 250px; +flex-direction: column; +align-items: flex-start; +gap: 16px; +flex-shrink: 0; + +@media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + align-items: center; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + align-items: flex-start; + } +` + +export const SkillInfoCard = ({ tag, info }) => { + return ( + + + + + ) +} \ No newline at end of file diff --git a/src/components/Skills/SkillSection.jsx b/src/components/Skills/SkillSection.jsx new file mode 100644 index 00000000..1032ef61 --- /dev/null +++ b/src/components/Skills/SkillSection.jsx @@ -0,0 +1,78 @@ +import styled from "styled-components" +import { SkillHeading } from "./SkillHeading" +import { SkillInfoCard } from "./SkillInfoCard" + +const StyledSkillSection = styled.div` +display: flex; + +flex-direction: column; +align-items: center; +align-self: stretch; +background: ${({ theme }) => theme.color.primary}; +color: ${({ theme }) => theme.color.secondary}; +padding: 64px 16px; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + padding: 64px 24px; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + padding: 128px 0; + } +` + +const skillsData = [ + { + tag: "Code", + info: "HTML5\nCSS3\nJavascript ES6\nTypeScript\nStyled Components\nGitHub", + }, + { + tag: "Toolbox", + info: "Atom\nPostman\nAdobe Photoshop\nAdobe Illustrator\nAdobe InDesign\nAdobe Acrobat\nAdobe Premiere Pro & Rush\nAdobe After Effects\nCamera raw\nBridge\nWordpress\nSitecore (CMS)\nSitevison (CMS)\nShopify\nFigma\nMicrosoft (Word, ppt, etc)\nSlack", + }, + { + tag: "Upcoming", + info: "Node.js\nReact\nMongoDB\nExpress.js", + }, + { + tag: "More", + info: "Branding\nStrategy\nProcess Design\nConcept Development\nAgile methodology\nAccessibility (WCAG)\nVersion Control (Git workflows)\nCreative Problem-Solving\nCross-functional Collaboration\nUX & UI", + }, +] + +const StyledCardContainer = styled.div` + display: flex; + gap: 24px; + max-width: 803px; + width: 90%; + margin-top: 0; + align-items: flex-start; + align-self: stretch; + flex-direction: column; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + align-items: center; + align-self: center; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + flex-direction: row; + width: 982px; + justify-content: center; + align-self: center; + align-items: flex-start; + } +` + +export const SkillSection = () => { + return ( + + + + {skillsData.map((skill) => ( + + ))} + + + ) +} \ No newline at end of file diff --git a/src/components/Skills/SkillTags.jsx b/src/components/Skills/SkillTags.jsx new file mode 100644 index 00000000..a38499fe --- /dev/null +++ b/src/components/Skills/SkillTags.jsx @@ -0,0 +1,31 @@ +import styled from "styled-components" + + +const StyledTag = styled.div` +display: flex; +height: 28px; +padding: 2px 6px; +justify-content: center; +align-items: center; +align-self: stretch; +border-radius: 4px; +border: 1px solid ${({ theme }) => theme.color.secondary}; +background: ${({ theme }) => theme.color.primary}; +` + +const StyledTagText = styled.p` +color: ${({ theme }) => theme.color.secondary}; +font-size: 16px; +font-style: normal; +font-weight: 500; +line-height: normal; +margin: 0; +` + +export const SkillTags = ({ tag }) => { + return ( + + {tag} + + ) +} \ No newline at end of file diff --git a/src/components/Tech/TechHeading.jsx b/src/components/Tech/TechHeading.jsx new file mode 100644 index 00000000..9b969644 --- /dev/null +++ b/src/components/Tech/TechHeading.jsx @@ -0,0 +1,7 @@ + +import { H2 } from "../typography/H2" + + +export const TechHeading = () => { + return

Tech

+} \ No newline at end of file diff --git a/src/components/Tech/TechSection.jsx b/src/components/Tech/TechSection.jsx new file mode 100644 index 00000000..1c6aabe5 --- /dev/null +++ b/src/components/Tech/TechSection.jsx @@ -0,0 +1,34 @@ +import styled from "styled-components" +import { TechHeading } from "./TechHeading" +import { TechText } from "./TechText" + +const StyledTechSection = styled.div` +background-color: ${({ theme }) => theme.color.primary}; +color: white; +display: flex; +padding: 128px 0; +flex-direction: column; +align-items: center; +gap: 16px; +align-self: stretch; +margin-top: 98.13px; +` +const StyledTextContainer = styled.div` + text-align: center; + + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 782px; + } +` + +export const TechSection = () => { + return ( + + + + + + + ) +} \ No newline at end of file diff --git a/src/components/Tech/TechText.jsx b/src/components/Tech/TechText.jsx new file mode 100644 index 00000000..f0365d92 --- /dev/null +++ b/src/components/Tech/TechText.jsx @@ -0,0 +1,10 @@ +import styled from "styled-components" +import { P } from "../typography/P" + +const StyledText = styled(P)` + color: ${({ theme }) => theme.color.secondary}; +` + +export const TechText = () => { + return HTML, CSS, Flexbox, JavaScript, ES6, Typescript, JSX, React, React Hooks, Node.js, Express.js, Mongo DB, Web Accessibility, APIs, mob-programming, pair-programming, GitHub. +} diff --git a/src/components/articles/ArticleCard.jsx b/src/components/articles/ArticleCard.jsx new file mode 100644 index 00000000..4dcbc2eb --- /dev/null +++ b/src/components/articles/ArticleCard.jsx @@ -0,0 +1,92 @@ +import styled from "styled-components" +import { ArticleCardText } from "./ArticleCardText" +import { ArticleCardImage } from "./ArticleCardImage" +import { Button } from "../assets/Button" +import { Tag } from "../assets/Tag" + +const StyledArticleCard = styled.div` + display: flex; + align-items: center; + align-self: stretch; + gap: 32px; + margin: 0 auto 64px auto; + flex-direction: column; + width: 90%; + max-width: 1195px; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + align-items: flex-start; + flex-direction: row; + width: 90%; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + gap: 125px; + margin: 0 auto 128px auto; + + } +` +const StyledTextContainer = styled.div` + display: flex; +flex-direction: column; +align-items: flex-start; +gap: 32px; +align-self: stretch; + +@media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + width: 464px; + flex: 1 0 0; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 580px; + gap: 16px; + } + +` + +const StyledTagContainer = styled.div` + display: flex; + align-items: flex-start; + gap: 4px; + align-self: stretch; + flex-wrap: wrap; +` + +const StyledButtonContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + align-self: stretch; + margin-top: 16px; +` +const StyledButton = styled(Button)` + background: ${({ theme }) => theme.color.primary}; + color: ${({ theme }) => theme.color.secondary}; +` + +const StyledArticleTag = styled(Tag)` +width: 142px; +` + +export const ArticleCard = ({ name, info, image, date, link }) => { + return ( + + + + + {date.map(singleDate => ( + + ))} + + + + + + + + ) +} \ No newline at end of file diff --git a/src/components/articles/ArticleCardImage.jsx b/src/components/articles/ArticleCardImage.jsx new file mode 100644 index 00000000..3519039b --- /dev/null +++ b/src/components/articles/ArticleCardImage.jsx @@ -0,0 +1,25 @@ +import styled from "styled-components" + +const StyledImage = styled.img` + object-fit: cover; + border-radius: 12px; + align-self: stretch; + + @media (min-width: ${({ theme }) => theme.breakpoints.mobile}) { + width: 100%; + height: 200px; +} + +@media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + width: 200px; +} + +@media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 479px; + height: 320px; +} +` + +export const ArticleCardImage = ({ src, alt }) => { + return +} \ No newline at end of file diff --git a/src/components/articles/ArticleCardText.jsx b/src/components/articles/ArticleCardText.jsx new file mode 100644 index 00000000..33683eeb --- /dev/null +++ b/src/components/articles/ArticleCardText.jsx @@ -0,0 +1,13 @@ + +import { H3 } from "../typography/H3" +import { P } from "../typography/P" + + +export const ArticleCardText = ({ name, info }) => { + return ( + <> +

{name}

+

{info}

+ + ) +} \ No newline at end of file diff --git a/src/components/articles/ArticleHeading.jsx b/src/components/articles/ArticleHeading.jsx new file mode 100644 index 00000000..7f856719 --- /dev/null +++ b/src/components/articles/ArticleHeading.jsx @@ -0,0 +1,14 @@ +import styled from "styled-components" +import { H2 } from "../typography/H2" + +const StyledHeadingContainer = styled.div` +margin: 128px auto; +` + +export const ArticleHeading = () => { + return ( + +

My Words

+
+ ) +} \ No newline at end of file diff --git a/src/components/articles/ArticleSection.jsx b/src/components/articles/ArticleSection.jsx new file mode 100644 index 00000000..027768ce --- /dev/null +++ b/src/components/articles/ArticleSection.jsx @@ -0,0 +1,23 @@ + +import { ArticleHeading } from "./ArticleHeading.jsx" +import { ArticleCard } from "./ArticleCard" +import Data from "../../data/articles.json" + + +export const ArticleSection = () => { + return ( + <> + + {Data.articles.map(article => ( + + ))} + + ) +} \ No newline at end of file diff --git a/src/components/assets/Button.jsx b/src/components/assets/Button.jsx new file mode 100644 index 00000000..9c390084 --- /dev/null +++ b/src/components/assets/Button.jsx @@ -0,0 +1,34 @@ +import styled from "styled-components" + +const StyledButton = styled.a` + display: flex; + width: 303px; + height: 48px; + padding: 0 16px; + align-items: center; + gap: 16px; + border-radius: 12px; + font-size: 18px; + text-decoration: none; + cursor: pointer; +` +const IconWrapper = styled.span` + width: 24px; + height: 24px; + display: flex; + justify-content: center; + align-items: center; +` + +export const Button = ({ icon, text, href, className }) => { + return ( + <> + + + + + {text} + + + ) +} \ No newline at end of file diff --git a/src/components/assets/Tag.jsx b/src/components/assets/Tag.jsx new file mode 100644 index 00000000..6ea63a53 --- /dev/null +++ b/src/components/assets/Tag.jsx @@ -0,0 +1,31 @@ +import styled from "styled-components" + +const StyledTagContainer = styled.div` +display: flex; +padding: 2px 6px; +justify-content: center; +height: 28px; +border-radius: 4px; +border: 1px solid ${({ theme }) => theme.color.primary}; +background: ${({ theme }) => theme.color.secondary}; +` + +const StyledTagText = styled.p` +color: ${({ theme }) => theme.color.primary}; +font-family: Poppins; +font-size: 16px; +font-style: normal; +font-weight: 500; +line-height: normal; +margin: auto; +` + +export const Tag = ({ tag, className }) => { + return ( + <> + + {tag} + + + ) +} \ No newline at end of file diff --git a/src/components/footer/FooterAvatar.jsx b/src/components/footer/FooterAvatar.jsx new file mode 100644 index 00000000..9d70d480 --- /dev/null +++ b/src/components/footer/FooterAvatar.jsx @@ -0,0 +1,12 @@ +import styled from "styled-components" + +const StyledAvatar = styled.img` +width: 164px; +height: 164px; +border-radius: 164px; +object-fit: cover; +` + +export const FooterAvatar = (props) => { + return +} \ No newline at end of file diff --git a/src/components/footer/FooterContactInfo.jsx b/src/components/footer/FooterContactInfo.jsx new file mode 100644 index 00000000..256f179e --- /dev/null +++ b/src/components/footer/FooterContactInfo.jsx @@ -0,0 +1,28 @@ +import styled from "styled-components" +import { P } from "../typography/P" + + +const StyledTextContainer = styled.div` +display: flex; +flex-direction: column; +align-items: flex-start; +gap: 8px; + +@media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + align-items: center; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 580px; + } +` + +export const FooterContactInfo = () => { + return ( + +

Carolina Oldertz

+

+46(0)72 251 25 95

+

carolina.oldertz@gmail.com

+
+ ) +} \ No newline at end of file diff --git a/src/components/footer/FooterHeading.jsx b/src/components/footer/FooterHeading.jsx new file mode 100644 index 00000000..72b3203b --- /dev/null +++ b/src/components/footer/FooterHeading.jsx @@ -0,0 +1,7 @@ + +import { H2 } from "../typography/H2" + + +export const FooterHeading = () => { + return

Let's Talk

+} \ No newline at end of file diff --git a/src/components/footer/FooterSection.jsx b/src/components/footer/FooterSection.jsx new file mode 100644 index 00000000..6ce05622 --- /dev/null +++ b/src/components/footer/FooterSection.jsx @@ -0,0 +1,37 @@ +import styled from "styled-components" +import { FooterHeading } from "./FooterHeading" +import { FooterAvatar } from "./FooterAvatar" +import { FooterContactInfo } from "./FooterContactInfo" +import { FooterSocials } from "./FooterSocials" + +const StyledFooter = styled.footer` + display: flex; + flex-direction: column; + align-items: center; + padding: 128px 20px; + background-color: ${({ theme }) => theme.color.primary}; + color: ${({ theme }) => theme.color.secondary}; + text-align: center; + gap: 32px; +` +const StyledSocialsContainer = styled.div` + display: flex; + flex-direction: row; + align-items: flex-end; + gap: 32px; +` + +export const FooterSection = (props) => { + return ( + + + + + + + + + + + ) +} \ No newline at end of file diff --git a/src/components/footer/FooterSocials.jsx b/src/components/footer/FooterSocials.jsx new file mode 100644 index 00000000..83501f6d --- /dev/null +++ b/src/components/footer/FooterSocials.jsx @@ -0,0 +1,22 @@ +import styled from "styled-components" + +const SocialIconLink = styled.a` + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 50%; + font-size: 24px; + text-decoration: none; +` + +export const FooterSocials = (props) => { + return ( + <> + + {props.alt} + + + ) +} \ No newline at end of file diff --git a/src/components/hero/HeroHeading.jsx b/src/components/hero/HeroHeading.jsx new file mode 100644 index 00000000..ea267a54 --- /dev/null +++ b/src/components/hero/HeroHeading.jsx @@ -0,0 +1,29 @@ +import styled from "styled-components" +import { H1 } from "../typography/H1" +import { H3 } from "../typography/H3" + +const StyledHeadingContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; + margin-top: 64px; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + margin-top; 64px + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + margin-top: 128px; + } +` + + + +export const HeroHeading = () => { + return ( + +

Hi there, I'm

+

Carolina Oldertz

+
+ ) +} \ No newline at end of file diff --git a/src/components/hero/HeroImage.jsx b/src/components/hero/HeroImage.jsx new file mode 100644 index 00000000..5419f355 --- /dev/null +++ b/src/components/hero/HeroImage.jsx @@ -0,0 +1,65 @@ +import styled from "styled-components" + +const getPositionStyling = (position) => { + switch (position) { + case "left": + return ` + transform: rotate(-4.695deg); + ` + case "middle": + return ` + z-index: 1; + ` + case "right": + return ` + transform: rotate(4.695deg); + ` + default: + return "" + } +} + +const StyledImage = styled.img` + object-fit: cover; + border-radius: 12px; + ${props => getPositionStyling(props.$position)}; + + width: 144px; + height: 154px; + + ${props => + props.$position === "left" + ? `margin-right: -76px; margin-top: 26px;` + : props.$position === "right" + ? `margin-left: -76px; margin-top: 26px;` + : `margin: 16px 0;`} + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + width: 260px; + height: 277px; + + ${props => + props.$position === "left" + ? `margin-right: -114px; margin-top: 32px;` + : props.$position === "right" + ? `margin-left: -114px; margin-top: 32px;` + : `margin: 16px 0;`} +} + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 358px; + height: 382px; + + ${props => + props.$position === "left" + ? `margin-right: -160px; margin-top: 43px;` + : props.$position === "right" + ? `margin-left: -160px; margin-top: 43px;` + : `margin: 16px 0;`} + } +} +` + +export const HeroImage = (props) => { + return +} \ No newline at end of file diff --git a/src/components/hero/HeroSection.jsx b/src/components/hero/HeroSection.jsx new file mode 100644 index 00000000..9425b2e3 --- /dev/null +++ b/src/components/hero/HeroSection.jsx @@ -0,0 +1,44 @@ +import styled from "styled-components" +import { HeroHeading } from "./HeroHeading" +import { HeroImage } from "./HeroImage" +import { HeroText } from "./HeroText" + + +const StyledImageContainer = styled.div` + display: flex; + justify-content: center; + margin: 32px 0; +` + + +const StyledHeroSection = styled.section` + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + padding: 32px 16px; + + @media (min-width: ${({ theme }) => theme.breakpoints.tablet}) { + padding: 48px 24px; + } + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + padding-top: 128px; + } +` + + + +export const HeroSection = (props) => { + return ( + + + + + + + + + + ) +} \ No newline at end of file diff --git a/src/components/hero/HeroSmallHeading.jsx b/src/components/hero/HeroSmallHeading.jsx new file mode 100644 index 00000000..e24239c7 --- /dev/null +++ b/src/components/hero/HeroSmallHeading.jsx @@ -0,0 +1,5 @@ +import { H3 } from "../typography/H3" + +export const HeroSmallHeading = () => { + return

Web Developer with a Background in Content creation and marketing

+} \ No newline at end of file diff --git a/src/components/hero/HeroText.jsx b/src/components/hero/HeroText.jsx new file mode 100644 index 00000000..5740d10f --- /dev/null +++ b/src/components/hero/HeroText.jsx @@ -0,0 +1,27 @@ +import styled from "styled-components" +import { H3 } from "../typography/H3" +import { P } from "../typography/P" + +const StyledTextContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + margin: 16px auto; + color: ${({ theme }) => theme.color.primary}; + gap: 16px; + align-self: stretch; + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 782px; + } +` + +export const HeroText = () => { + return ( + +

Web Developer with a Background in Content creation and marketing

+

I'm a driven Web developer who turned my creative background into a new passion for coding. I thrive on solving complex challenges and bring fresh, design-minded thinking to every project.

+
+ ) +} \ No newline at end of file diff --git a/src/components/projects/ProjectCard.jsx b/src/components/projects/ProjectCard.jsx new file mode 100644 index 00000000..42cdc24a --- /dev/null +++ b/src/components/projects/ProjectCard.jsx @@ -0,0 +1,85 @@ + +import styled from "styled-components" +import { ProjectCardText } from "./ProjectCardText" +import { ProjectCardImage } from "./ProjectCardImage" +import { Tag } from "../assets/Tag" +import { Button } from "../assets/Button" + + +const StyledProjectCard = styled.div` + display: flex; + align-items: center; + gap: 64px; + align-self: stretch; + justify-content: center; + max-width: 1184px; + width: 90%; + margin: 0 auto 128px auto; + flex-direction: column; + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + flex-direction: ${props => (props.$reverse ? 'row-reverse' : 'row')}; + gap: 125px; + } +` + + +const StyledLeftContent = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + gap: 16px; + align-self: stretch; +` +const StyledTagContainer = styled.div` + display: flex; + align-items: flex-start; + gap: 4px; + align-self: stretch; +` + +const StyledButtonContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; +` +const StyledButton = styled(Button)` + background: ${({ theme }) => theme.color.primary}; + color: ${({ theme }) => theme.color.secondary}; +` + +const StyledProjectTag = styled(Tag)` +flex: 1 0 0; +` + +export const ProjectCard = ({ name, info, netlify, github, image, tags, index }) => { + const shouldReverse = index % 2 !== 0 + + return ( + + + + + {tags.map(tag => ( + + ))} + + + + + + + + + ) +} + diff --git a/src/components/projects/ProjectCardImage.jsx b/src/components/projects/ProjectCardImage.jsx new file mode 100644 index 00000000..751cbf20 --- /dev/null +++ b/src/components/projects/ProjectCardImage.jsx @@ -0,0 +1,21 @@ + +import styled from "styled-components" + +const StyledImage = styled.img` + object-fit: cover; + border-radius: 12px; + box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25); + object-position: ${props => (props.$altText === 'Screenshot of RECIPE LIBRARY' ? 'left' : 'center')}; + height: 479px; + align-self: stretch; + + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + width: 479px; + height: 479px; + } + +` +export const ProjectCardImage = ({ src, alt }) => { + return +} \ No newline at end of file diff --git a/src/components/projects/ProjectCardText.jsx b/src/components/projects/ProjectCardText.jsx new file mode 100644 index 00000000..8b6f8315 --- /dev/null +++ b/src/components/projects/ProjectCardText.jsx @@ -0,0 +1,18 @@ + +import styled from "styled-components" +import { H3 } from "../typography/H3" +import { P } from "../typography/P" + +const StyledTextContainer = styled.div` + display: flex; + flex-direction: column; + align-self: stretch; +` +export const ProjectCardText = ({ name, info }) => { + return ( + +

{name}

+

{info}

+
+ ) +} diff --git a/src/components/projects/ProjectHeading.jsx b/src/components/projects/ProjectHeading.jsx new file mode 100644 index 00000000..aaccd6a9 --- /dev/null +++ b/src/components/projects/ProjectHeading.jsx @@ -0,0 +1,18 @@ +import styled from "styled-components" +import { H2 } from "../typography/H2" + +const StyledHeadingContainer = styled.div` +margin: 64px 0; + +@media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + margin : 128px 0; + } +` + +export const ProjectHeading = () => { + return ( + +

Featured Projects

+
+ ) +} \ No newline at end of file diff --git a/src/components/projects/ProjectSection.jsx b/src/components/projects/ProjectSection.jsx new file mode 100644 index 00000000..e7cfa3e7 --- /dev/null +++ b/src/components/projects/ProjectSection.jsx @@ -0,0 +1,38 @@ +import styled from "styled-components" +import { ProjectHeading } from "./ProjectHeading" +import { ProjectCard } from "./ProjectCard" +import data from "../../data/projects.json" +import { Button } from "../assets/Button" + +const StyledButton = styled(Button)` + background: ${({ theme }) => theme.color.secondary}; + color: ${({ theme }) => theme.color.primary}; + border: 2px solid ${({ theme }) => theme.color.primary}; + margin: 0 auto 128px auto; +` + +export const ProjectSection = () => { + return ( + <> + + + {data.projects.map((project, index) => ( + + ))} + + + ) +} diff --git a/src/components/typography/H1.jsx b/src/components/typography/H1.jsx new file mode 100644 index 00000000..9ca27d14 --- /dev/null +++ b/src/components/typography/H1.jsx @@ -0,0 +1,18 @@ +import styled from "styled-components" + +const StyledHeading = styled.h1` + margin: 0; + font-style: normal; + font-weight: 700; + line-height: normal; + text-align: center; + font-size: 52px; + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + margin: 16px 0; + font-size: 100px; + } +` +export const H1 = ({ children }) => { + return {children} +} \ No newline at end of file diff --git a/src/components/typography/H2.jsx b/src/components/typography/H2.jsx new file mode 100644 index 00000000..35ac5604 --- /dev/null +++ b/src/components/typography/H2.jsx @@ -0,0 +1,19 @@ +import styled from "styled-components" + +const StyledHeading = styled.h2` +text-align: center; +font-size: 80px; +font-style: normal; +font-weight: 700; +line-height: normal; +margin: 0; +font-size: 48px; + +@media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + font-size: 80px; +} +` + +export const H2 = ({ children }) => { + return {children} +} \ No newline at end of file diff --git a/src/components/typography/H3.jsx b/src/components/typography/H3.jsx new file mode 100644 index 00000000..d43fa9a1 --- /dev/null +++ b/src/components/typography/H3.jsx @@ -0,0 +1,16 @@ +import styled from "styled-components" + +const StyledHeading = styled.h3` + font-style: normal; + font-weight: 500; + line-height: normal; + margin: 0; + font-size: 24px; + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + font-size: 30px; + } +` +export const H3 = ({ children }) => { + return {children} +} \ No newline at end of file diff --git a/src/components/typography/P.jsx b/src/components/typography/P.jsx new file mode 100644 index 00000000..e5013d4f --- /dev/null +++ b/src/components/typography/P.jsx @@ -0,0 +1,16 @@ +import styled from "styled-components" + +const StyledText = styled.p` + font-style: normal; + font-weight: 400; + line-height: normal; + margin: 0; + font-size: 16px; + + @media (min-width: ${({ theme }) => theme.breakpoints.desktop}) { + font-size: 18px; + } +` +export const P = ({ children }) => { + return {children} +} \ No newline at end of file diff --git a/src/data/articles.json b/src/data/articles.json new file mode 100644 index 00000000..d42dc92b --- /dev/null +++ b/src/data/articles.json @@ -0,0 +1,25 @@ +{ + "articles": [ + { + "name": "From Content Creator to Web Developer", + "info": "I recently made the choice to switch career path. It was a hard decision but today 2,5 month later I can say that I so glad that i took this step and found a passion in coding.", + "image": "/images/articles/Article-carerr-change.png", + "date": "Nov 14th", + "link": "https://www.linkedin.com/feed/update/urn:li:activity:7393693049324814336/" + }, + { + "name": "How to cope with being an imposter", + "info": "This new course haven’t always been easy and fun, and a lot of the time you can feel like an imposter. To start over can be very difficult but you have to remember that every journey has it’s obstacles. How you tackle those obstacles is what makes the diffrence.", + "image": "/images/articles/Article-imposter.jpg", + "date": "Nov 14th", + "link": "https://www.linkedin.com/feed/update/urn:li:activity:7393693049324814336/" + }, + { + "name": "Best ways to learn as a newbie", + "info": "As a newbie in the tech world it can seem very overwhelming. But I have a few tips that can help you on your coding journey. First of all try to be comfortable with not understanding right now: you will get there and understand that it might take time. Tools to help: AI, W3schools, youtube ...", + "image": "/images/articles/Article-newbie.jpg", + "date": "Nov 14th", + "link": "https://www.linkedin.com/feed/update/urn:li:activity:7393693049324814336/" + } + ] +} \ No newline at end of file diff --git a/src/data/projects.json b/src/data/projects.json index 7c426028..32bdbf3f 100644 --- a/src/data/projects.json +++ b/src/data/projects.json @@ -1,19 +1,34 @@ { "projects": [ { - "name": "Business site", - "image": "https://images.unsplash.com/photo-1557008075-7f2c5efa4cfd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2497&q=80", + "name": "BUSINESS SITE", + "info": "A simple business site for a fictional cat subscription. Where you can look at products, read articles about cats and also send in a form with details of your subscription request. For a fun flare i added a JavaScript party mode toggle and a clickable talking cat in the footer.", + "image": "/images/projects/business-site.png", "tags": [ "HTML5", "CSS3", "JavaScript" ], - "netlify": "link", - "github": "link" + "netlify": "https://carolinas-business-site.netlify.app/", + "github": "https://github.com/carro-barro/js-project-business-site" }, { - "name": "Weather app", - "image": "https://images.unsplash.com/photo-1520792532857-293bd046307a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2370&q=80", + "name": "RECIPE LIBRARY", + "info": "Using spoonaculars API I have fetched a library of recipes that displays ingredients, cooking time and meal type. You can filter and sort by different categories and search for your recipe and aslo with a button click to geta random recipe.", + "image": "/images/projects/Recipe-library.png", + "tags": [ + "HTML5", + "CSS3", + "JavaScript", + "APIs" + ], + "netlify": "https://carolinas-recipe-library.netlify.app/", + "github": "https://github.com/carro-barro/js-project-recipe-library" + }, + { + "name": "WEATHER APP", + "info": "A weather app that displays the current temperature, condition, sunrise/sunset and precipitation in Stockholm. With a weekly forecast and a meaningful message, used with SMHI's API.", + "image": "/images/projects/Weather-app.png", "tags": [ "HTML5", "CSS3", @@ -21,8 +36,20 @@ "TypeScript", "APIs" ], - "netlify": "link", - "github": "link" + "netlify": "https://weather-app-rock-3.netlify.app/", + "github": "https://github.com/Nicolinabl/js-project-weather-app" + }, + { + "name": "ACCESSIBILITY SITE", + "info": "A fictional book club webpage that is made to be accessible for disabled people. Developed with ARIA-labels, semantic HTML, JavaScript modal traps and keyboard navigation.", + "image": "/images/projects/Accesibility-site.png", + "tags": [ + "HTML5", + "CSS3", + "JavaScript" + ], + "netlify": "https://the-reading-room-accesibility-project.netlify.app/", + "github": "https://github.com/carro-barro/js-project-accessibility" } ] } \ No newline at end of file diff --git a/src/index.css b/src/index.css index 61010be6..da0b430d 100644 --- a/src/index.css +++ b/src/index.css @@ -1,4 +1,4 @@ -body { +/* body { background: pink; color: hotpink; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/src/main.jsx b/src/main.jsx index ed109d76..ebc83db0 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,12 +1,15 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' - +import { ThemeProvider } from 'styled-components' +import { theme } from './theme.jsx' import { App } from './App.jsx' import './index.css' createRoot(document.getElementById('root')).render( - + + + , ) diff --git a/src/theme.jsx b/src/theme.jsx new file mode 100644 index 00000000..87801a94 --- /dev/null +++ b/src/theme.jsx @@ -0,0 +1,13 @@ +export const theme = { + + breakpoints: { + mobile: '576px', + tablet: '768px', + desktop: '1024px', + }, + + color: { + primary: '#000', + secondary: '#FFF' + } +} \ No newline at end of file