Skip to content

Commit

Permalink
feat: add Code component
Browse files Browse the repository at this point in the history
  • Loading branch information
martapanc-resourcify committed Jul 30, 2023
1 parent 2405980 commit 2fe2211
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 27 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@
"react-dom": "^18.2.0",
"react-headroom": "^3.2.1",
"react-icons": "^4.10.1",
"react-syntax-highlighter": "^15.5.0",
"react-tippy": "^1.4.0",
"sanity": "^3.0.0",
"sanity-plugin-internationalized-array": "^1.7.0",
"sanity-plugin-media": "^2.2.1",
"styled-components": "^5.2.0",
"tailwind-merge": "^1.12.0"
"tailwind-merge": "^1.12.0",
"typed.js": "^2.0.16"
},
"devDependencies": {
"@commitlint/cli": "^16.3.0",
Expand All @@ -72,6 +74,7 @@
"@testing-library/react": "^13.4.0",
"@types/react": "^18.2.7",
"@types/react-headroom": "^3.2.0",
"@types/react-syntax-highlighter": "^15.5.7",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "^10.4.14",
Expand Down
2 changes: 1 addition & 1 deletion sanity/deskStructure.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const freeTimeSection = [
'tvSeries',
'videoGame',
];
const sharedSection = ['shortText', 'skillIcon'];
const sharedSection = ['codeSnippet', 'shortText', 'skillIcon'];

export const customStructure = (S) =>
S.list()
Expand Down
2 changes: 2 additions & 0 deletions sanity/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type SchemaTypeDefinition } from 'sanity';

import codeSnippet from '@/schemas/codeSnippet';
import homeContent from '@/schemas/homeContent';
import randomFact from '@/schemas/randomFact';

Expand All @@ -18,6 +19,7 @@ import videoGame from '../src/schemas/videoGame';
export const schema: { types: SchemaTypeDefinition[] } = {
types: [
book,
codeSnippet,
homeContent,
job,
language,
Expand Down
34 changes: 19 additions & 15 deletions src/app/(public)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,34 @@ import Intro from '@/components/organisms/home/Intro';
import Summary from '@/components/organisms/home/Summary';
import Seo from '@/components/Seo';

// import {homeContentQuery} from '@/queries/homeContent';
//
// import {sanityClient} from '../../../sanity/lib/client';
//
// import {HomeContent} from '@/types/HomeContent';

// const getData = async () => {
// const homeData: HomeContent[] = await sanityClient.fetch(homeContentQuery);
//
// return {
// homeContent: homeData[0],
// };
// };
import { codeSnippetsQuery } from '@/queries/codeSnippets';

import { sanityClient } from '../../../sanity/lib/client';

import { CodeSnippet } from '@/types/CodeSnippet';

const getData = async () => {
// const homeData: HomeContent[] = await sanityClient.fetch(homeContentQuery);
const codeSnippets: CodeSnippet[] = await sanityClient.fetch(
codeSnippetsQuery
);

return {
codeSnippets,
// homeContent: homeData[0],
};
};

const HomePage = async () => {
// const {homeContent} = await getData();
const { codeSnippets } = await getData();

return (
<main className='min-h-main'>
<Seo templateTitle='Home' />

<section className='dark:bg-dark bg-white'>
<div className='layout relative flex flex-col py-16 md:py-24'>
<Intro />
<Intro codeSnippets={codeSnippets} />

<Summary />
</div>
Expand Down
80 changes: 77 additions & 3 deletions src/components/organisms/home/Code.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,81 @@
import React from 'react';
'use client';

const Code = () => {
return <div className='h-20 w-full pb-12 md:w-2/3'>Code display</div>;
import { useTheme } from 'next-themes';
import React, { useEffect, useState } from 'react';
import SyntaxHighlighter from 'react-syntax-highlighter';
import {
atomOneLight,
darcula,
} from 'react-syntax-highlighter/dist/cjs/styles/hljs';
import Typed, { TypedOptions } from 'typed.js';

import { CodeSnippet } from '@/types/CodeSnippet';

export interface CodeSnippetsProps {
codeSnippets: CodeSnippet[];
}

const Code = ({ codeSnippets }: CodeSnippetsProps) => {
const [loading, setLoading] = useState(true);

const { theme } = useTheme();

const ideStyle = theme === 'dark' ? darcula : atomOneLight;

useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 2000);
}, []);

useEffect(() => {
if (!loading) {
const typedStringsElement = document.getElementById('typed-strings');
const typedElement = document.getElementById('typed');

if (typedStringsElement && typedElement) {
const typedOptions: TypedOptions = {
stringsElement: '#typed-strings',
typeSpeed: 40,
backSpeed: 10,
backDelay: 5000,
loop: true,
loopCount: 0,
smartBackspace: true,
showCursor: true,
cursorChar: '_',
};

const typed = new Typed(typedElement, typedOptions);

// Clean up the Typed.js instance when the component unmounts
return () => {
typed.destroy();
};
}
}
}, [loading]);

return (
<div className='me-4 h-72 w-full rounded border-double bg-slate-200 px-4 pb-12 pt-6 dark:bg-slate-800 md:w-2/3'>
<div id='typed-strings'>
{loading ? <span className='cursor-blink'>_</span> : null}
{!loading &&
codeSnippets.map((snippet) => (
<SyntaxHighlighter
className='text-xs md:text-base'
key={snippet._id}
language={snippet.language}
style={ideStyle}
wrapLongLines={true}
>
{snippet.code}
</SyntaxHighlighter>
))}
</div>
<span id='typed'></span>
</div>
);
};

export default Code;
10 changes: 6 additions & 4 deletions src/components/organisms/home/Intro.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react';

import Code from '@/components/organisms/home/Code';
import { shuffleArray } from '@/lib/helper';

import Code, { CodeSnippetsProps } from '@/components/organisms/home/Code';
import Photo from '@/components/organisms/home/Photo';

const Intro = () => {
const Intro = ({ codeSnippets }: CodeSnippetsProps) => {
return (
<div className='mb-12 flex h-96 flex-col pb-12'>
<div className='mb-12 flex h-fit flex-col pb-12 md:h-96'>
<h1 className='pb-4 text-5xl antialiased'>Hey there, I'm Marta 👋🏻</h1>

<div className='mt-8 flex flex-col md:flex-row'>
<Code />
<Code codeSnippets={shuffleArray(codeSnippets)} />

<Photo />
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/organisms/home/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from 'react';
const Summary = () => {
return (
<>
<p className='pb-4 text-base antialiased'>
<div className='pb-4 text-base antialiased'>
I'm a software engineer based in Turin, Italy, and I am currently
working at
<a
Expand All @@ -21,7 +21,7 @@ const Summary = () => {
/>
</a>
.
</p>
</div>

<p className='pb-4 text-base antialiased'>
I hold a MSc in Advanced Computer Science from the University of
Expand Down
19 changes: 19 additions & 0 deletions src/pages/api/code-snippets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { NextApiRequest, NextApiResponse } from 'next';

import { codeSnippetsQuery } from '@/queries/codeSnippets';

import { sanityClient } from '../../../sanity/lib/client';

import { CodeSnippet } from '@/types/CodeSnippet';

const codeSnippetsApi = async (req: NextApiRequest, res: NextApiResponse) => {
const codeSnippets: CodeSnippet[] = await sanityClient.fetch(
codeSnippetsQuery
);

res.status(200).json({
codeSnippets,
});
};

export default codeSnippetsApi;
9 changes: 9 additions & 0 deletions src/queries/codeSnippets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { groq } from 'next-sanity';

export const codeSnippetsQuery = groq`
*[_type == "codeSnippet"] {
_id,
title,
"code": code.code,
"language": code.language,
}`;
19 changes: 19 additions & 0 deletions src/schemas/codeSnippet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineField, defineType } from 'sanity';

export default defineType({
name: 'codeSnippet',
title: 'Code Snippet',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
}),
defineField({
name: 'code',
title: 'Code Snippet',
type: 'code',
}),
],
});
10 changes: 10 additions & 0 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,14 @@
.quiz-radio-button {
color: white;
}

.cursor-blink {
animation: blinker 1s steps(2) infinite;
}

@keyframes blinker {
0% {
opacity: 0;
}
}
}
6 changes: 6 additions & 0 deletions src/types/CodeSnippet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface CodeSnippet {
_id: string;
title: string;
code: string;
language: string;
}
Loading

0 comments on commit 2fe2211

Please sign in to comment.