diff --git a/sanity/schema.ts b/sanity/schema.ts
index 686008d..c6294d8 100644
--- a/sanity/schema.ts
+++ b/sanity/schema.ts
@@ -1,10 +1,11 @@
import { type SchemaTypeDefinition } from 'sanity';
import job from '../src/schemas/job';
+import school from '../src/schemas/school';
import shortText from '../src/schemas/shortText';
import skill from '../src/schemas/skill';
import skillIcon from '../src/schemas/skillIcon';
export const schema: { types: SchemaTypeDefinition[] } = {
- types: [job, shortText, skill, skillIcon],
+ types: [job, school, shortText, skill, skillIcon],
};
diff --git a/src/app/(public)/about/page.tsx b/src/app/(public)/about/page.tsx
index 189b960..6c88e2c 100644
--- a/src/app/(public)/about/page.tsx
+++ b/src/app/(public)/about/page.tsx
@@ -2,15 +2,18 @@ import { PortableText } from '@portabletext/react';
import Image from 'next/image';
import * as React from 'react';
+import Education from '@/components/organisms/Education/Education';
import WorkExperience from '@/components/organisms/WorkExperience/WorkExperience';
import { jobsQuery } from '@/queries/jobs';
+import { schoolsQuery } from '@/queries/schools';
import { shortTextQuery } from '@/queries/short-texts';
import { skillQuery } from '@/queries/skills';
import { sanityClient } from '../../../../sanity/lib/client';
import { Job } from '@/types/Job';
+import { School } from '@/types/School';
import { ShortText } from '@/types/ShortText';
import { Skill } from '@/types/Skill';
import { SkillIcon } from '@/types/SkillIcon';
@@ -23,19 +26,22 @@ export const metadata = {
const getData = async () => {
const jobs: Job[] = await sanityClient.fetch(jobsQuery);
+ const schools: School[] = await sanityClient.fetch(schoolsQuery);
+
const skills: Skill[] = await sanityClient.fetch(skillQuery);
const shortTexts: ShortText[] = await sanityClient.fetch(shortTextQuery);
return {
jobs,
+ schools,
shortTexts,
skills,
};
};
const AboutPage = async () => {
- const { jobs, shortTexts, skills } = await getData();
+ const { jobs, schools, shortTexts, skills } = await getData();
const softwareDevelopment: ShortText | undefined = shortTexts.find(
(item) => item.name === 'software-development'
@@ -107,6 +113,8 @@ const AboutPage = async () => {
+
+
diff --git a/src/components/organisms/Education/Education.tsx b/src/components/organisms/Education/Education.tsx
index 69e0de3..fc06918 100644
--- a/src/components/organisms/Education/Education.tsx
+++ b/src/components/organisms/Education/Education.tsx
@@ -1,14 +1,14 @@
'use client';
-// import { PortableText } from '@portabletext/react';
-// import Image from 'next/image';
+import { PortableText } from '@portabletext/react';
+import Image from 'next/image';
// import {useTheme} from "next-themes";
import * as React from 'react';
-import { Job } from '@/types/Job';
+import { School } from '@/types/School';
export interface EducationProps {
- schools: Job[];
+ schools: School[];
}
const Education = ({ schools }: EducationProps) => {
@@ -20,60 +20,67 @@ const Education = ({ schools }: EducationProps) => {
Education
- {schools[0].isCurrentJob}
+
+ {schools.map((school) => (
+
+ {/* Start School Header */}
+
+
- {/*
*/}
- {/* {jobs.map((job) => (*/}
- {/*
*/}
- {/* /!* Start Job Header *!/*/}
- {/*
*/}
- {/*
*/}
+
+
+
+
- {/*
*/}
- {/*
*/}
- {/*
*/}
- {/* {job.company} ~ {job.location}*/}
- {/*
*/}
- {/* {job.jobTitle}
*/}
- {/* */}
+
+
- {/*
*/}
- {/*
*/}
- {/* {job.startYear} – {job.isCurrentJob ? ` present` : job.endYear}*/}
- {/*
*/}
- {/* */}
- {/*
*/}
- {/*
*/}
- {/* /!* End Job Header *!/*/}
+
{school.degreeName}
+
- {/* /!* Start Job Content *!/*/}
- {/*
*/}
- {/*
*/}
+
+
+
+ {school.grade}
+
+
- {/*
*/}
- {/* {job.technologies.map((tech) => (*/}
- {/*
*/}
- {/* {tech}*/}
- {/*
*/}
- {/* ))}*/}
- {/*
*/}
- {/*
*/}
- {/* /!* End Job Content *!/*/}
- {/*
*/}
- {/* ))}*/}
- {/*
*/}
+
+
+ {school.startYear} — {school.endYear}
+
+
+
+
+
+ {/* End School Header */}
+
+ {/* Start School Content */}
+
+ {/* End School Content */}
+
+ ))}
+
);
};
diff --git a/src/components/organisms/WorkExperience/WorkExperience.tsx b/src/components/organisms/WorkExperience/WorkExperience.tsx
index 803ff4e..8b93c3e 100644
--- a/src/components/organisms/WorkExperience/WorkExperience.tsx
+++ b/src/components/organisms/WorkExperience/WorkExperience.tsx
@@ -39,16 +39,19 @@ const WorkExperience = ({ jobs }: WorkExperienceProps) => {
- {job.company} ~ {job.location}
+ {job.company} {job.location && `~`} {job.location}
{job.jobTitle}
-
- {job.startYear} –{' '}
- {job.isCurrentJob ? ` present` : job.endYear}
-
+
+ <>
+ {format(job.startDate)}
+ —
+ {job.isCurrentJob ? `present` : format(job.endDate)}
+ >
+
@@ -83,4 +86,12 @@ const WorkExperience = ({ jobs }: WorkExperienceProps) => {
);
};
+function format(inputDate: string): string {
+ const date = new Date(inputDate);
+ return Intl.DateTimeFormat('en', {
+ year: 'numeric',
+ month: 'short',
+ }).format(date);
+}
+
export default WorkExperience;
diff --git a/src/pages/api/schools.ts b/src/pages/api/schools.ts
new file mode 100644
index 0000000..dd02be7
--- /dev/null
+++ b/src/pages/api/schools.ts
@@ -0,0 +1,15 @@
+import { NextApiRequest, NextApiResponse } from 'next';
+
+import { schoolsQuery } from '@/queries/schools';
+
+import { sanityClient } from '../../../sanity/lib/client';
+
+import { School } from '@/types/School';
+
+const schoolsApi = async (req: NextApiRequest, res: NextApiResponse) => {
+ const schools: School[] = await sanityClient.fetch(schoolsQuery);
+
+ res.status(200).json(schools);
+};
+
+export default schoolsApi;
diff --git a/src/queries/jobs.ts b/src/queries/jobs.ts
index cc77a7c..3bd91cb 100644
--- a/src/queries/jobs.ts
+++ b/src/queries/jobs.ts
@@ -1,14 +1,14 @@
import { groq } from 'next-sanity';
export const jobsQuery = groq`
-*[_type == "job"] | order(endYear desc) {
+*[_type == "job"] | order(endDate desc) {
_id,
company,
"iconUrl": icon.asset->url,
location,
jobTitle,
- startYear,
- endYear,
+ startDate,
+ endDate,
isCurrentJob,
description,
technologies,
diff --git a/src/queries/schools.ts b/src/queries/schools.ts
new file mode 100644
index 0000000..38ebc16
--- /dev/null
+++ b/src/queries/schools.ts
@@ -0,0 +1,16 @@
+import { groq } from 'next-sanity';
+
+export const schoolsQuery = groq`
+*[_type == "school"] | order(endYear desc) {
+ _id,
+ name,
+ schoolName,
+ "schoolIcon": schoolIcon.asset->url,
+ "flagUrl": countryFlag.asset->url,
+ degreeName,
+ degreeUrl,
+ grade,
+ startYear,
+ endYear,
+ description,
+}`;
diff --git a/src/schemas/job.ts b/src/schemas/job.ts
index 450e38d..b55ee9a 100644
--- a/src/schemas/job.ts
+++ b/src/schemas/job.ts
@@ -31,16 +31,22 @@ export default defineType({
type: 'string',
}),
defineField({
- name: 'startYear',
- title: 'Start Year',
- type: 'number',
- initialValue: new Date().getFullYear() - 3,
+ name: 'startDate',
+ title: 'Start Date',
+ type: 'date',
+ options: {
+ dateFormat: 'MMM YYYY',
+ },
+ initialValue: 'Mar 2020',
}),
defineField({
- name: 'endYear',
+ name: 'endDate',
title: 'End Year',
- type: 'number',
- initialValue: new Date().getFullYear() - 1,
+ type: 'date',
+ options: {
+ dateFormat: 'MMM YYYY',
+ },
+ initialValue: 'Mar 2022',
}),
defineField({
name: 'isCurrentJob',
@@ -81,7 +87,7 @@ export default defineType({
{
title: 'Most Recent',
name: 'jobDateDesc',
- by: [{ field: 'endYear', direction: 'desc' }],
+ by: [{ field: 'startDate', direction: 'desc' }],
},
],
});
diff --git a/src/schemas/school.ts b/src/schemas/school.ts
new file mode 100644
index 0000000..977747c
--- /dev/null
+++ b/src/schemas/school.ts
@@ -0,0 +1,69 @@
+import { defineField, defineType } from 'sanity';
+
+export default defineType({
+ name: 'school',
+ title: 'School',
+ type: 'document',
+ fields: [
+ defineField({
+ name: 'name',
+ title: 'Name',
+ type: 'string',
+ }),
+ defineField({
+ name: 'schoolName',
+ title: 'School Name',
+ type: 'string',
+ }),
+ defineField({
+ name: 'schoolIcon',
+ title: 'School Icon',
+ type: 'image',
+ }),
+ defineField({
+ name: 'countryFlag',
+ title: 'Country Flag',
+ type: 'image',
+ }),
+ defineField({
+ name: 'degreeName',
+ title: 'Degree Name',
+ type: 'string',
+ }),
+ defineField({
+ name: 'degreeUrl',
+ title: 'Degree Url',
+ type: 'string',
+ }),
+ defineField({
+ name: 'grade',
+ title: 'Grade',
+ type: 'string',
+ }),
+ defineField({
+ name: 'startYear',
+ title: 'Start Year',
+ type: 'number',
+ initialValue: new Date().getFullYear() - 5,
+ }),
+ defineField({
+ name: 'endYear',
+ title: 'End Year',
+ type: 'number',
+ initialValue: new Date().getFullYear() - 3,
+ }),
+ defineField({
+ name: 'description',
+ title: 'Description',
+ type: 'array',
+ of: [{ type: 'block' }],
+ }),
+ ],
+ orderings: [
+ {
+ title: 'Most Recent',
+ name: 'schoolDateDesc',
+ by: [{ field: 'endYear', direction: 'desc' }],
+ },
+ ],
+});
diff --git a/src/types/Job.ts b/src/types/Job.ts
index 79a48d0..b37d680 100644
--- a/src/types/Job.ts
+++ b/src/types/Job.ts
@@ -7,8 +7,8 @@ export interface Job {
iconUrl: string;
location: string;
jobTitle: string;
- startYear: number;
- endYear: number;
+ startDate: string;
+ endDate: string;
isCurrentJob: boolean;
description: TypedObject;
mainColor: string;
diff --git a/src/types/School.ts b/src/types/School.ts
new file mode 100644
index 0000000..178719b
--- /dev/null
+++ b/src/types/School.ts
@@ -0,0 +1,15 @@
+import { TypedObject } from '@portabletext/types';
+
+export interface School {
+ _id: string;
+ name: string;
+ schoolName: string;
+ schoolIcon: string;
+ flagUrl: string;
+ degreeName: string;
+ degreeUrl: string;
+ grade: string;
+ startYear: number;
+ endYear: number;
+ description: TypedObject;
+}