Document interfaces that describes cv data (#168)
Co-authored-by: Szymon Kin <68154191+hoolek77@users.noreply.github.com>
This commit is contained in:
parent
5ed3ad4fa3
commit
8d0cd278eb
19 changed files with 518 additions and 21 deletions
Binary file not shown.
|
Before Width: | Height: | Size: 62 KiB |
BIN
src/assets/favorites/books/book-2.jpg
Normal file
BIN
src/assets/favorites/books/book-2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
|
|
@ -10,7 +10,7 @@ const config = {
|
|||
now: 'now',
|
||||
},
|
||||
},
|
||||
seo: {
|
||||
meta: {
|
||||
title: 'Mark Freeman - Senior React Developer',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales ac dui at vestibulum. In condimentum metus id dui tincidunt, in blandit mi vehicula.',
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const favoritesSectionData = {
|
|||
url: 'https://www.goodreads.com/book/show/4099.The_Pragmatic_Programmer',
|
||||
},
|
||||
{
|
||||
image: 'https://m.media-amazon.com/images/I/61aFldsgAmL._SY344_BO1,204,203,200_QL70_ML2_.jpg',
|
||||
image: import('@/assets/favorites/books/book-2.jpg'),
|
||||
title: 'Domain-Driven Design: Tackling Complexity in the Heart of Software',
|
||||
author: 'Eric Evans',
|
||||
url: 'https://www.goodreads.com/book/show/179133.Domain_Driven_Design',
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
import type { Locale } from 'date-fns';
|
||||
|
||||
export interface I18nConfig {
|
||||
/**
|
||||
* Language code used for date formatting, translations, and value of the page `lang` attribute.
|
||||
*/
|
||||
locale: Locale;
|
||||
|
||||
/**
|
||||
* Date format used when displaying date ranges in some sections.
|
||||
*/
|
||||
dateFormat: string;
|
||||
|
||||
/**
|
||||
* List of translations used in the application.
|
||||
*/
|
||||
translations: {
|
||||
/**
|
||||
* Used in date ranges to represent the current date.
|
||||
*/
|
||||
now: string;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
55
src/types/config/meta-config.types.ts
Normal file
55
src/types/config/meta-config.types.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
export interface MetaConfig {
|
||||
/**
|
||||
* [WEB] Page title.
|
||||
*
|
||||
* Displayed as browser tab title and in search results.
|
||||
* It's recommended to keep it between 30 and 60 characters.
|
||||
*
|
||||
* @see https://www.screamingfrog.co.uk/learn-seo/page-title
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] Page description.
|
||||
*
|
||||
* Displayed under the title in search results.
|
||||
* It's recommended to keep it between 70 and 155 characters.
|
||||
*
|
||||
* @see https://www.screamingfrog.co.uk/learn-seo/meta-description
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* [WEB] URL or path to the page's favicon.
|
||||
*
|
||||
* Specified icon will be displayed next to the page title in browser tab.
|
||||
*/
|
||||
favicon: string;
|
||||
|
||||
/**
|
||||
* [WEB] Title used in open graph links.
|
||||
*
|
||||
* If not specified, the title property will be used.
|
||||
*
|
||||
* @see https://ahrefs.com/blog/open-graph-meta-tags
|
||||
*/
|
||||
ogTitle?: string;
|
||||
|
||||
/**
|
||||
* [WEB] Description used in open graph links.
|
||||
*
|
||||
* If not specified, the description property will be used.
|
||||
*
|
||||
* @see https://ahrefs.com/blog/open-graph-meta-tags
|
||||
*/
|
||||
ogDescription?: string;
|
||||
|
||||
/**
|
||||
* [WEB] Image used in open graph links.
|
||||
*
|
||||
* It's recommended to keep it between 30 and 60 characters.
|
||||
*
|
||||
* @see https://ahrefs.com/blog/open-graph-meta-tags
|
||||
*/
|
||||
ogImage?: string;
|
||||
}
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
export interface PdfConfig {
|
||||
/**
|
||||
* [PDF] Displays footer with specified content on each PDF page.
|
||||
*
|
||||
* You can use it to add the data processing clause.
|
||||
*/
|
||||
footer?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
export interface SeoConfig {
|
||||
title: string;
|
||||
description: string;
|
||||
favicon: string;
|
||||
ogTitle?: string;
|
||||
ogDescription?: string;
|
||||
ogImage?: string;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import type { I18nConfig } from './config/i18n-config.types';
|
||||
import type { PdfConfig } from './config/pdf-config.types';
|
||||
import type { SeoConfig } from './config/seo-config.types';
|
||||
import type { MetaConfig } from './config/meta-config.types';
|
||||
import type { EducationSection } from './sections/education-section.types';
|
||||
import type { ExperienceSection } from './sections/experience-section.types';
|
||||
import type { FavoritesSection } from './sections/favorites-section.types';
|
||||
|
|
@ -10,22 +10,70 @@ import type { SkillsSection } from './sections/skills-section.types';
|
|||
import type { TestimonialsSection } from './sections/testimonials-section.types';
|
||||
|
||||
export interface Config {
|
||||
seo: SeoConfig;
|
||||
/**
|
||||
* [WEB] Page metadata used for SEO and social media sharing.
|
||||
*/
|
||||
meta: MetaConfig;
|
||||
|
||||
/**
|
||||
* Language and date display configuration.
|
||||
*/
|
||||
i18n: I18nConfig;
|
||||
|
||||
/**
|
||||
* [PDF] Configuration of the pdf generation.
|
||||
*/
|
||||
pdf?: PdfConfig;
|
||||
}
|
||||
|
||||
export interface Sections {
|
||||
/**
|
||||
* Basic information about you.
|
||||
*/
|
||||
main: MainSection;
|
||||
|
||||
/**
|
||||
* Grouped lists of your skills.
|
||||
*/
|
||||
skills: SkillsSection;
|
||||
|
||||
/**
|
||||
* Your employment history.
|
||||
*/
|
||||
experience: ExperienceSection;
|
||||
|
||||
/**
|
||||
* Your projects and initiatives.
|
||||
*/
|
||||
portfolio: PortfolioSection;
|
||||
|
||||
/**
|
||||
* Your education degrees and certifications.
|
||||
*/
|
||||
education: EducationSection;
|
||||
|
||||
/**
|
||||
* [WEB] Recommendations from your previous employers and people you worked with.
|
||||
*/
|
||||
testimonials: TestimonialsSection;
|
||||
|
||||
/**
|
||||
* [WEB] List of sources you use to gain knowledge and inspiration.
|
||||
*/
|
||||
favorites: FavoritesSection;
|
||||
}
|
||||
|
||||
/**
|
||||
* All data used to generate the cv.
|
||||
*/
|
||||
export interface Data {
|
||||
/**
|
||||
* Global configuration of the web and pdf versions of the cv.
|
||||
*/
|
||||
config: Config;
|
||||
|
||||
/**
|
||||
* Configurations for the particular sections of the cv.
|
||||
*/
|
||||
sections: Sections;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,35 @@
|
|||
import type { DateRange, Description, LinkButton, Section } from '../shared';
|
||||
|
||||
export interface Diploma {
|
||||
/**
|
||||
* Name of the certificate or the degree you got.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* Name of the institution that issued the certificate or degree.
|
||||
*/
|
||||
institution: string;
|
||||
|
||||
/**
|
||||
* Date range when you were studying in the institution.
|
||||
*/
|
||||
dates: DateRange;
|
||||
|
||||
/**
|
||||
* A short overview of your studies. You can write it as a paragraph (string) or as a list of bullet points (string[]).
|
||||
*/
|
||||
description: Description;
|
||||
|
||||
/**
|
||||
* [WEB] Links related to your studies (e.g. course/university website, link to realized project).
|
||||
*/
|
||||
links: LinkButton[];
|
||||
}
|
||||
|
||||
export interface EducationSection extends Section {
|
||||
/**
|
||||
* List of your diplomas, certificates, .etc. Start with the most recent one.
|
||||
*/
|
||||
diplomas: Diploma[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,41 @@
|
|||
import type { DateRange, Description, LinkButton, Section, TagsList } from '../shared';
|
||||
|
||||
export interface Job {
|
||||
/**
|
||||
* Your position in the company.
|
||||
*/
|
||||
role: string;
|
||||
|
||||
/**
|
||||
* Name of the company.
|
||||
*/
|
||||
company: string;
|
||||
|
||||
/**
|
||||
* Date range when you were working in the company.
|
||||
*/
|
||||
dates: DateRange;
|
||||
|
||||
/**
|
||||
* A short overview of your job. You can write it as a paragraph (string) or as a list of bullet points (string[]).
|
||||
*/
|
||||
description: Description;
|
||||
|
||||
/**
|
||||
* Any information that you want to highlight.
|
||||
* We recommend to describe the technologies used in the project.
|
||||
*/
|
||||
tagsList: TagsList;
|
||||
|
||||
/**
|
||||
* [WEB] Links related to your job (e.g. production app, company's website, project website).
|
||||
*/
|
||||
links: LinkButton[];
|
||||
}
|
||||
|
||||
export interface ExperienceSection extends Section {
|
||||
/**
|
||||
* List of your jobs in a chronological order. Start with the most recent one.
|
||||
*/
|
||||
jobs: Job[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,129 @@
|
|||
import type { Photo, Section } from '../shared';
|
||||
|
||||
export interface Book {
|
||||
/**
|
||||
* [WEB] Book title.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] Book cover.
|
||||
*
|
||||
* **Ratio**: 3:4
|
||||
*
|
||||
* **Display size**: 300x400px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* [WEB] Full name of the book author.
|
||||
*/
|
||||
author: string;
|
||||
|
||||
/**
|
||||
* [WEB] Website to buy the book or read more about it.
|
||||
*/
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Person {
|
||||
/**
|
||||
* [WEB] Full name of the person.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* [WEB] Photo of the person.
|
||||
*
|
||||
* **Ratio**: 1:1
|
||||
*
|
||||
* **Display size**: 200x200px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* [WEB] Main website related to the person.
|
||||
*/
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export interface Video {
|
||||
/**
|
||||
* [WEB] Title of the video.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] Thumbnail of the video.
|
||||
*
|
||||
* **Ratio**: 16:9
|
||||
*
|
||||
* **Display size**: 448x252px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* [WEB] Link to the video.
|
||||
*/
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Media {
|
||||
/**
|
||||
* [WEB] Title of the media.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] Type of the media (e.g. podcast, blog, newsletter, YouTube channel, .etc).
|
||||
*/
|
||||
type: string;
|
||||
|
||||
/**
|
||||
* [WEB] Logo of the media.
|
||||
*
|
||||
* **Ratio**: 1:1
|
||||
*
|
||||
* **Display size**: 200x200px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* [WEB] URL to the main website related to the media.
|
||||
*/
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface SubSection<Data = unknown> {
|
||||
/**
|
||||
* [WEB] Title that will be displayed above the list of items.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] List of items to display within the subsection.
|
||||
*/
|
||||
data: Data[];
|
||||
}
|
||||
|
||||
export interface FavoritesSection extends Section {
|
||||
/**
|
||||
* [WEB] List of your favorite books.
|
||||
*/
|
||||
books?: SubSection<Book>;
|
||||
|
||||
/**
|
||||
* [WEB] List of the people that inspire you.
|
||||
*/
|
||||
people?: SubSection<Person>;
|
||||
|
||||
/**
|
||||
* [WEB] List of the videos you learned the most from.
|
||||
*/
|
||||
videos?: SubSection<Video>;
|
||||
|
||||
/**
|
||||
* [WEB] List of other media types that helps you to growth in your field.
|
||||
*/
|
||||
medias?: SubSection<Media>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,58 @@
|
|||
import type { DownloadButton, Photo, LabelledValue, LinkButton, Section, Tag } from '../shared';
|
||||
|
||||
export interface MainSection extends Section {
|
||||
/**
|
||||
* Your image.
|
||||
*
|
||||
* **Ratio**: 1:1
|
||||
*
|
||||
* **Display size**: 208x208px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* Your name.
|
||||
*/
|
||||
fullName: string;
|
||||
|
||||
/**
|
||||
* Your current role.
|
||||
*/
|
||||
role: string;
|
||||
|
||||
/**
|
||||
* Label-value pairs with some key details about you.
|
||||
*
|
||||
* E.g. phone, email, location, expected salary.
|
||||
*/
|
||||
details: LabelledValue[];
|
||||
|
||||
/**
|
||||
* [PDF] Labeled-value pairs that will be used in the PDF version of your resume.
|
||||
*
|
||||
* You can use it to add your social media profiles as those listed under the `links` property aren't used in the PDF.
|
||||
*
|
||||
* If not provided, the `details` will be used instead.
|
||||
*/
|
||||
pdfDetails?: LabelledValue[];
|
||||
|
||||
/**
|
||||
* A short overview of you and your experience.
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* [WEB] Any information that you want to highlight.
|
||||
*/
|
||||
tags: Tag[];
|
||||
|
||||
/**
|
||||
* [WEB] A button that will be used to download your resume.
|
||||
*/
|
||||
action: DownloadButton;
|
||||
|
||||
/**
|
||||
* [WEB] Your social media profiles.
|
||||
*/
|
||||
links: LinkButton[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,59 @@
|
|||
import type { DateRange, Photo, LabelledValue, LinkButton, Section, TagsList, Description } from '../shared';
|
||||
|
||||
export interface Project {
|
||||
/**
|
||||
* Name of the project.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* [WEB] Logo of the project.
|
||||
*
|
||||
* **Ratio**: 1:1
|
||||
*
|
||||
* **Display size**: 120x120px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* Date range when you were working on the project.
|
||||
*/
|
||||
dates: DateRange;
|
||||
|
||||
/**
|
||||
* Label-value pairs with some key details about the project.
|
||||
*/
|
||||
details: LabelledValue[];
|
||||
|
||||
/**
|
||||
* [PDF] Labeled-value pairs that will be used in the PDF version of your resume.
|
||||
*
|
||||
* You can use it to add some links related to your project as those listed under the `links` property aren't used in the PDF.
|
||||
*
|
||||
* If not provided, the `details` will be used instead.
|
||||
*/
|
||||
pdfDetails?: LabelledValue[];
|
||||
|
||||
/**
|
||||
* A short overview of the project. You can write it as a paragraph (string) or as a list of bullet points (string[]).
|
||||
*/
|
||||
description: Description;
|
||||
|
||||
/**
|
||||
* Any information that you want to highlight.
|
||||
* We recommend to describe the technologies used in the project.
|
||||
*/
|
||||
tagsList: TagsList;
|
||||
|
||||
/**
|
||||
* [WEB] Links related to your project (e.g. GitHub repository, live demo, mockups).
|
||||
*/
|
||||
links: LinkButton[];
|
||||
}
|
||||
|
||||
export interface PortfolioSection extends Section {
|
||||
/**
|
||||
* List of your projects in a chronological order. Start with the most recent one.
|
||||
*/
|
||||
projects: Project[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,30 @@ export interface Skill extends Tag {}
|
|||
export type SkillLevel = 1 | 2 | 3 | 4 | 5;
|
||||
|
||||
export interface LevelledSkill extends Skill {
|
||||
/**
|
||||
* Your level of skill proficiency in a 1-5 scale.
|
||||
*/
|
||||
level: SkillLevel;
|
||||
}
|
||||
|
||||
export interface SkillSet {
|
||||
/**
|
||||
* Title that will be displayed above the list of skills.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* List of skills with or without levels.
|
||||
*
|
||||
* If you want to displays skills with levels, we recommend to also provide the `description` property.
|
||||
* This way anyone viewing your resume will know what is the meaning of each level.
|
||||
*/
|
||||
skills: Skill[] | LevelledSkill[];
|
||||
}
|
||||
|
||||
export interface SkillsSection extends Section {
|
||||
/**
|
||||
* Grouped lists of your skills.
|
||||
*/
|
||||
skillSets: SkillSet[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,39 @@
|
|||
import type { Photo, LinkButton, Section } from '../shared';
|
||||
|
||||
export interface Testimonial {
|
||||
/**
|
||||
* [WEB] Photo of the testimonial author.
|
||||
*
|
||||
* **Ratio**: 1:1
|
||||
*
|
||||
* **Display size**: 56x56px
|
||||
*/
|
||||
image: Photo;
|
||||
|
||||
/**
|
||||
* [WEB] Full name of the testimonial author.
|
||||
*/
|
||||
author: string;
|
||||
|
||||
/**
|
||||
* [WEB] Your relation to the testimonial author (e.g. supervisor, colleague, subordinate).
|
||||
*/
|
||||
relation: string;
|
||||
|
||||
/**
|
||||
* [WEB] Content of the testimonial.
|
||||
*/
|
||||
content: string;
|
||||
|
||||
/**
|
||||
* [WEB] Social media (e.g. LinkedIn profile, website) of the testimonial author.
|
||||
*/
|
||||
links: LinkButton[];
|
||||
}
|
||||
|
||||
export interface TestimonialsSection extends Section {
|
||||
/**
|
||||
* [WEB] List of your testimonials in a chronological order. Start with the most recent one.
|
||||
*/
|
||||
testimonials: Testimonial[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +1,162 @@
|
|||
import type { CircleFlags, Fa6Brands, Fa6Solid, Ri, SimpleIcons } from 'iconify-icon-names';
|
||||
|
||||
/**
|
||||
* Name of the icon from the iconify library.
|
||||
*
|
||||
* @see https://icon-sets.iconify.design
|
||||
*/
|
||||
export type IconName = Fa6Brands | Fa6Solid | SimpleIcons | CircleFlags | Ri;
|
||||
|
||||
/**
|
||||
* - Dynamic import of the image from `src/assets` folder. Recommended as it enables image optimization.
|
||||
* - Path to the image placed in the `public` folder.
|
||||
* - URL of the image stored online.
|
||||
*/
|
||||
export type Photo = Promise<{ default: ImageMetadata }> | string;
|
||||
|
||||
/**
|
||||
* Two date objects representing some time period.
|
||||
*
|
||||
* If the second date is `null`, it means that the period is still ongoing.
|
||||
* In such case, the translation from `config.i18n.translations.now` will be used.
|
||||
*/
|
||||
export type DateRange = [from: Date, to: Date | null];
|
||||
|
||||
/**
|
||||
* If a string is provided, it will be displayed as a single justified paragraph.
|
||||
* If an array of strings is provided it will be displayed as a list.
|
||||
*/
|
||||
export type Description = string | string[];
|
||||
|
||||
export interface SectionConfig {
|
||||
/**
|
||||
* Name displayed as a section header (except for the main section).
|
||||
*
|
||||
* [WEB] Content of the tooltip displayed when someone hovers over the section in the sidebar.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* [WEB] URL hash used to navigate to the section.
|
||||
*/
|
||||
slug: string;
|
||||
|
||||
/**
|
||||
* [WEB] Icon used in sidebar navigation to represent the section.
|
||||
*/
|
||||
icon: IconName;
|
||||
|
||||
/**
|
||||
* Should section be displayed on the page.
|
||||
*/
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
export interface Section {
|
||||
/**
|
||||
* Base information about the section.
|
||||
*/
|
||||
config: SectionConfig;
|
||||
}
|
||||
|
||||
export interface LabelledValue {
|
||||
/**
|
||||
* Bolder text displayed on the left side of the value.
|
||||
*/
|
||||
label: string;
|
||||
|
||||
/**
|
||||
* Text displayed on the right side.
|
||||
* If a list of strings provided, they will be separated by a comma.
|
||||
*/
|
||||
value: string | string[];
|
||||
|
||||
/**
|
||||
* URL that will be opened in a new tab, when the value is clicked.
|
||||
*/
|
||||
url?: string;
|
||||
|
||||
/**
|
||||
* [PDF] When labelled value is displayed in a grid, it will span the whole row.
|
||||
*/
|
||||
fullRow?: boolean;
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
/**
|
||||
* Text displayed within the tag.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* [WEB] Icon displayed next to the tag text.
|
||||
*/
|
||||
icon?: IconName;
|
||||
|
||||
/**
|
||||
* [WEB] Color of the icon. By default, the color is inherited from the text.
|
||||
*/
|
||||
iconColor?: string;
|
||||
|
||||
/**
|
||||
* [WEB] URL that will be opened in a new tab, when the tag is clicked.
|
||||
*/
|
||||
url?: string;
|
||||
|
||||
/**
|
||||
* [WEB] Text displayed in the tooltip when someone hovers over the tag.
|
||||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface TagsList {
|
||||
/**
|
||||
* [PDF] Text displayed before the list of tags.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* Tags to be displayed within the list.
|
||||
* [WEB] Tags are displayed as gray blocks. All tag properties are used.
|
||||
* [PDF] Tags are displayed comma separated list. Only the `name` property are used.
|
||||
*/
|
||||
tags: Tag[];
|
||||
}
|
||||
|
||||
export interface DownloadButton {
|
||||
/**
|
||||
* [WEB] Text displayed within the download button.
|
||||
*/
|
||||
label: string;
|
||||
|
||||
/**
|
||||
* [WEB] URL or path to the CV file.
|
||||
*/
|
||||
url: string;
|
||||
|
||||
/**
|
||||
* [WEB] Name of the file that will be downloaded.
|
||||
*
|
||||
* If not specified, the original file name will be used and file will open in a PDF viewer in some browsers.
|
||||
*
|
||||
* If specified, the file will be downloaded immediately (without preview) in all browsers.
|
||||
*/
|
||||
downloadedFileName?: string;
|
||||
}
|
||||
|
||||
export interface LinkButton {
|
||||
/**
|
||||
* [WEB] Name displayed in the tooltip when someone hovers over the button.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* [WEB] Icon displayed within the button.
|
||||
*/
|
||||
icon: IconName;
|
||||
|
||||
/**
|
||||
* [WEB] URL that will be opened in a new tab, when the button is clicked.
|
||||
*/
|
||||
url: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
import type { Data } from '@/types/data';
|
||||
import Analytics from '@/web/analytics/analytics.astro';
|
||||
|
||||
export interface Props extends Pick<Data['config'], 'seo' | 'i18n'> {}
|
||||
export interface Props extends Pick<Data['config'], 'meta' | 'i18n'> {}
|
||||
|
||||
const { seo, i18n } = Astro.props;
|
||||
const { meta, i18n } = Astro.props;
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
|
@ -13,12 +13,12 @@ const { seo, i18n } = Astro.props;
|
|||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>{seo.title}</title>
|
||||
<meta name="description" content={seo.description} />
|
||||
<link rel="icon" type="image/svg+xml" href={seo.favicon} />
|
||||
<meta property="og:title" content={seo.ogTitle ?? seo.title} />
|
||||
<meta property="og:description" content={seo.ogDescription ?? seo.description} />
|
||||
{seo.ogImage && <meta property="og:image" content={seo.ogImage} />}
|
||||
<title>{meta.title}</title>
|
||||
<meta name="description" content={meta.description} />
|
||||
<link rel="icon" type="image/svg+xml" href={meta.favicon} />
|
||||
<meta property="og:title" content={meta.ogTitle ?? meta.title} />
|
||||
<meta property="og:description" content={meta.ogDescription ?? meta.description} />
|
||||
{meta.ogImage && <meta property="og:image" content={meta.ogImage} />}
|
||||
<script is:inline>
|
||||
const theme = (() => {
|
||||
if (typeof localStorage !== 'undefined' && localStorage.getItem('theme')) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import { isServer } from './env';
|
|||
const getInitialHash = () => {
|
||||
if (isServer) return '';
|
||||
|
||||
return window.location.hash || `#${sections.main.config.slug}`;
|
||||
const firstVisibleSection = Object.values(sections).find((section) => section.config.visible);
|
||||
|
||||
if (!firstVisibleSection) return '';
|
||||
|
||||
return window.location.hash || `#${firstVisibleSection.config.slug}`;
|
||||
};
|
||||
|
||||
const createHashState = () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue