mirror of
https://github.com/morten-olsen/morten-olsen.github.io.git
synced 2026-02-08 01:46:28 +01:00
init
This commit is contained in:
13
src/data/data.articles.ts
Normal file
13
src/data/data.articles.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
class Articles {
|
||||
public find = () => getCollection('articles');
|
||||
public get = async (slug: string) => {
|
||||
const collection = await this.find();
|
||||
return collection.find((entry) => entry.slug === slug);
|
||||
};
|
||||
}
|
||||
|
||||
type Article = Exclude<Awaited<ReturnType<Articles['get']>>, undefined>;
|
||||
|
||||
export { Articles, type Article };
|
||||
13
src/data/data.references.ts
Normal file
13
src/data/data.references.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
class References {
|
||||
public find = () => getCollection('references');
|
||||
public get = async (slug: string) => {
|
||||
const collection = await this.find();
|
||||
return collection.find((entry) => entry.slug === slug);
|
||||
};
|
||||
}
|
||||
|
||||
type Reference = Exclude<Awaited<ReturnType<References['get']>>, undefined>;
|
||||
|
||||
export { References, type Reference };
|
||||
5
src/data/data.site.ts
Normal file
5
src/data/data.site.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
const site = {
|
||||
theme: '#30E130',
|
||||
};
|
||||
|
||||
export { site };
|
||||
13
src/data/data.skills.ts
Normal file
13
src/data/data.skills.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
class Skills {
|
||||
public find = () => getCollection('skills');
|
||||
public get = async (slug: string) => {
|
||||
const collection = await this.find();
|
||||
return collection.find((entry) => entry.slug === slug);
|
||||
};
|
||||
}
|
||||
|
||||
type Skill = Exclude<Awaited<ReturnType<Skills['get']>>, undefined>;
|
||||
|
||||
export { Skills, type Skill };
|
||||
25
src/data/data.ts
Normal file
25
src/data/data.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { profile } from '../content/profile/profile.js';
|
||||
import { type Article, Articles } from './data.articles.js';
|
||||
import { References } from './data.references.ts';
|
||||
import { site } from './data.site.ts';
|
||||
import { Skills } from './data.skills.ts';
|
||||
import { getJsonLDResume, getJsonResume } from './data.utils.js';
|
||||
import { Work, type WorkItem } from './data.work.js';
|
||||
|
||||
class Data {
|
||||
public articles = new Articles();
|
||||
public work = new Work();
|
||||
public references = new References();
|
||||
public skills = new Skills();
|
||||
public profile = profile;
|
||||
public site = site;
|
||||
|
||||
public getJsonResume = getJsonResume.bind(null, this);
|
||||
public getJsonLDResume = getJsonLDResume.bind(null, this);
|
||||
}
|
||||
|
||||
const data = new Data();
|
||||
|
||||
type Profile = typeof profile;
|
||||
export type { Article, Profile, WorkItem };
|
||||
export { data, Data };
|
||||
89
src/data/data.utils.ts
Normal file
89
src/data/data.utils.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { ResumeSchema } from '@/types/resume-schema.js';
|
||||
|
||||
import type { Article, Data } from './data';
|
||||
|
||||
const getJsonResume = async (data: Data) => {
|
||||
const profile = data.profile;
|
||||
const resume = {
|
||||
basics: profile.basics,
|
||||
} satisfies ResumeSchema;
|
||||
|
||||
return resume;
|
||||
};
|
||||
|
||||
const getArticleJsonLD = async (data: Data, article: Article) => {
|
||||
const jsonld = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BlogPosting',
|
||||
headline: article.data.title,
|
||||
image: article.data.heroImage.src,
|
||||
datePublished: article.data.pubDate.toISOString(),
|
||||
keywords: article.data.tags,
|
||||
inLanguage: 'en-US',
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: data.profile.basics.name,
|
||||
url: data.profile.basics.url,
|
||||
},
|
||||
};
|
||||
return jsonld;
|
||||
};
|
||||
|
||||
const getJsonLDResume = async (data: Data) => {
|
||||
const work = await data.work.find();
|
||||
const currentWork = work.find((w) => !w.data.endDate);
|
||||
const otherWork = work.filter((w) => w !== currentWork);
|
||||
|
||||
const jsonld = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Person',
|
||||
id: '#me',
|
||||
name: data.profile.basics.name,
|
||||
email: data.profile.basics.email,
|
||||
image: data.profile.basics.image,
|
||||
url: data.profile.basics.url,
|
||||
jobTitle: currentWork?.data.position,
|
||||
contactPoint: data.profile.basics.profiles.map((profile) => ({
|
||||
'@type': 'ContactPoint',
|
||||
contactType: profile.network.toLowerCase(),
|
||||
identifier: profile.username,
|
||||
url: profile.url,
|
||||
})),
|
||||
address: {
|
||||
'@type': 'PostalAddress',
|
||||
addressLocality: data.profile.basics.location.city,
|
||||
addressRegion: data.profile.basics.location.region,
|
||||
addressCountry: data.profile.basics.location.countryCode,
|
||||
},
|
||||
sameAs: data.profile.basics.profiles.map((profile) => profile.url),
|
||||
hasOccupation: currentWork && {
|
||||
'@type': 'EmployeeRole',
|
||||
roleName: currentWork.data.position,
|
||||
startDate: currentWork.data.startDate.toISOString(),
|
||||
},
|
||||
worksFor: currentWork && {
|
||||
'@type': 'Organization',
|
||||
name: currentWork?.data.name,
|
||||
sameAs: currentWork?.data.url,
|
||||
},
|
||||
alumniOf: otherWork.map((w) => ({
|
||||
'@type': 'Organization',
|
||||
name: w.data.name,
|
||||
sameAs: w.data.url,
|
||||
employee: {
|
||||
'@type': 'Person',
|
||||
hasOccupation: {
|
||||
'@type': 'EmployeeRole',
|
||||
roleName: w.data.position,
|
||||
startDate: w.data.startDate.toISOString(),
|
||||
endDate: w.data.endDate?.toISOString(),
|
||||
},
|
||||
sameAs: '#me',
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
return jsonld;
|
||||
};
|
||||
|
||||
export { getJsonResume, getJsonLDResume, getArticleJsonLD };
|
||||
12
src/data/data.work.ts
Normal file
12
src/data/data.work.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { getCollection } from 'astro:content';
|
||||
|
||||
class Work {
|
||||
public find = () => getCollection('work');
|
||||
public get = async (slug: string) => {
|
||||
const collection = await this.find();
|
||||
return collection.find((entry) => entry.slug === slug);
|
||||
};
|
||||
}
|
||||
|
||||
type WorkItem = Exclude<Awaited<ReturnType<Work['get']>>, undefined>;
|
||||
export { Work, type WorkItem };
|
||||
Reference in New Issue
Block a user