diff --git a/apps/back/src/api/apidocs.rs b/apps/back/src/api/apidocs.rs
index 4b00135..97b540f 100644
--- a/apps/back/src/api/apidocs.rs
+++ b/apps/back/src/api/apidocs.rs
@@ -12,7 +12,7 @@ use super::home::get_home;
use markdown_struct::{
blog_timeline::BlogTimeline,
content_struct::{Page, PageShort},
- doc_header::{DocHeader, DocHeaderLink, DocHeaderSpec},
+ doc_header::{DocHeader, DocHeaderLink, DocHeaderSpec, DocHeaderWritter},
doc_sidebar::DocCategory,
};
use utoipa::OpenApi;
@@ -38,6 +38,7 @@ use utoipa::OpenApi;
DocHeader,
DocHeaderSpec,
DocHeaderLink,
+ DocHeaderWritter,
BlogTimeline,
HomeUrl,
HomeHistoryUrl,
diff --git a/apps/front/components.d.ts b/apps/front/components.d.ts
index 325e5ec..799e3da 100644
--- a/apps/front/components.d.ts
+++ b/apps/front/components.d.ts
@@ -7,8 +7,10 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
+ Avatar: typeof import('primevue/avatar')['default']
Card: typeof import('primevue/card')['default']
Checkbox: typeof import('primevue/checkbox')['default']
+ Chip: typeof import('primevue/chip')['default']
Panel: typeof import('primevue/panel')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
diff --git a/apps/front/src/component/Doc/DocSidebar.vue b/apps/front/src/component/Doc/DocSidebar.vue
index 680e982..a7bdb39 100644
--- a/apps/front/src/component/Doc/DocSidebar.vue
+++ b/apps/front/src/component/Doc/DocSidebar.vue
@@ -2,11 +2,17 @@
import { useRoute } from 'vue-router';
import { useDocStore } from '../../stores/doc';
import DocSidebarItem from './DocSidebarItem.vue';
+import { ref, watch } from 'vue';
const route = useRoute();
const docStore = useDocStore();
+let path = ref(Array.isArray(route.params.page) ? route.params.page : [route.params.page]);
-let path = Array.isArray(route.params.page) ? route.params.page : [route.params.page];
+watch(() => route.params.page, (newValue, oldValue) => {
+ if (newValue !== oldValue) {
+ path.value = Array.isArray(newValue) ? newValue : [newValue];
+ }
+});
diff --git a/apps/front/src/component/Page/PageMetadata.vue b/apps/front/src/component/Page/PageMetadata.vue
index d2dac56..f63a932 100644
--- a/apps/front/src/component/Page/PageMetadata.vue
+++ b/apps/front/src/component/Page/PageMetadata.vue
@@ -1,14 +1,61 @@
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/apps/front/src/component/Page/PageTechnoChip.vue b/apps/front/src/component/Page/PageTechnoChip.vue
new file mode 100644
index 0000000..90b4941
--- /dev/null
+++ b/apps/front/src/component/Page/PageTechnoChip.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/front/src/markdown/detectLink.ts b/apps/front/src/markdown/detectLink.ts
new file mode 100644
index 0000000..fa6388c
--- /dev/null
+++ b/apps/front/src/markdown/detectLink.ts
@@ -0,0 +1,29 @@
+export type Link = {
+ url: string;
+ text: string;
+};
+
+export const detectLink = (text: string) => {
+ const textUrlArray = [];
+ const urlMdRegex = /\[(\?'text'[^\]]+)\]\((\?'url'[^)]+)\)/g;
+ while (urlMdRegex.exec(text)) {
+ textUrlArray.push({
+ text: RegExp.$1,
+ url: RegExp.$2,
+ });
+ }
+ const urlMdRegex2 = /<(\?'text'[^\]]+)>/g;
+ // eslint-disable-next-line no-constant-condition
+ while (true) {
+ const matched = urlMdRegex2.exec(text);
+ if (!matched) break;
+ textUrlArray.push({
+ text: matched[1],
+ url: matched[1],
+ });
+ const splitText = text.split(`<${matched[1]}>`);
+ textUrlArray.push(splitText[0]);
+
+ text = splitText.slice(1).join('');
+ }
+};
diff --git a/apps/front/src/markdown/detectTextSpec.ts b/apps/front/src/markdown/detectTextSpec.ts
new file mode 100644
index 0000000..105c212
--- /dev/null
+++ b/apps/front/src/markdown/detectTextSpec.ts
@@ -0,0 +1,31 @@
+export type TextSpec = {
+ start: number;
+ stop: number;
+ isLink: boolean;
+ url?: string;
+ isBold: boolean;
+ isItalic: boolean;
+ isCode: boolean;
+};
+
+export const detectTextSpec = (text: string) => {
+ const textUrlArray = [];
+ const urlMdRegex = /\[(\?'text'[^\]]+)\]\((\?'url'[^)]+)\)/g;
+ while (urlMdRegex.exec(text)) {
+ textUrlArray.push({
+ text: RegExp.$1,
+ url: RegExp.$2,
+ });
+ }
+ const urlMdRegex2 = /<(\?'text'[^\]]+)>/g;
+ // eslint-disable-next-line no-constant-condition
+ while (true) {
+ text.search(urlMdRegex2);
+ const matched = urlMdRegex2.exec(text);
+ if (!matched) break;
+ const splitText = text.split(`<${matched[1]}>`);
+ textUrlArray;
+
+ text = splitText.slice(1).join('');
+ }
+};
diff --git a/apps/front/src/markdown/index.ts b/apps/front/src/markdown/index.ts
index 81e76d8..b2acd96 100644
--- a/apps/front/src/markdown/index.ts
+++ b/apps/front/src/markdown/index.ts
@@ -86,6 +86,5 @@ export const transformContent = (content: string): TitleBlock[] => {
titleBlocks[titleBlocks.length - 1].appendBlock(block);
}
});
- console.log(titleBlocks);
return titleBlocks;
};
diff --git a/apps/front/src/stores/doc.ts b/apps/front/src/stores/doc.ts
index db0ed8f..5c64937 100644
--- a/apps/front/src/stores/doc.ts
+++ b/apps/front/src/stores/doc.ts
@@ -1,4 +1,4 @@
-import { DocCategory, getDocSidebar } from '@portfolio/api-client';
+import { DocCategory, getDocSidebar, PageShort } from '@portfolio/api-client';
import { defineStore } from 'pinia';
export interface DocState {
@@ -57,5 +57,24 @@ export const useDocStore = defineStore({
}
return;
},
+ technoExists(techno: string): PageShort | undefined {
+ if (!this.docContent) return;
+ return this.technoExistsRecursive(techno, this.docContent);
+ },
+ technoExistsRecursive(
+ techno: string,
+ category: DocCategory,
+ ): PageShort | undefined {
+ for (const page of category.pages) {
+ if (page.name.toLowerCase() === techno.toLowerCase()) {
+ return page;
+ }
+ }
+ for (const subCategory of category.sub_categories) {
+ const found = this.technoExistsRecursive(techno, subCategory);
+ if (found) return found;
+ }
+ return;
+ },
},
});
diff --git a/apps/front/tsconfig.json b/apps/front/tsconfig.json
index e7b4430..c7f95da 100644
--- a/apps/front/tsconfig.json
+++ b/apps/front/tsconfig.json
@@ -18,6 +18,5 @@
"path": "./tsconfig.spec.json"
}
],
- "extends": "../../tsconfig.base.json",
- "composite": true
+ "extends": "../../tsconfig.base.json"
}
diff --git a/libs/back/markdown_struct/src/blog_timeline.rs b/libs/back/markdown_struct/src/blog_timeline.rs
index 3930eb4..30a0861 100644
--- a/libs/back/markdown_struct/src/blog_timeline.rs
+++ b/libs/back/markdown_struct/src/blog_timeline.rs
@@ -74,6 +74,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: vec![],
@@ -118,6 +119,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: vec![],
@@ -141,6 +143,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: vec![],
diff --git a/libs/back/markdown_struct/src/content_struct.rs b/libs/back/markdown_struct/src/content_struct.rs
index 0b3df92..65f610d 100644
--- a/libs/back/markdown_struct/src/content_struct.rs
+++ b/libs/back/markdown_struct/src/content_struct.rs
@@ -78,6 +78,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: vec![],
diff --git a/libs/back/markdown_struct/src/doc_header.rs b/libs/back/markdown_struct/src/doc_header.rs
index c966c6c..8f8a198 100644
--- a/libs/back/markdown_struct/src/doc_header.rs
+++ b/libs/back/markdown_struct/src/doc_header.rs
@@ -30,6 +30,10 @@ fn empty_doc_header_spec() -> DocHeaderSpec {
}
}
+fn default_doc_header_writter() -> DocHeaderWritter {
+ Default::default()
+}
+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, ToSchema)]
pub struct DocHeaderSpec {
#[serde(default = "false_default")]
@@ -56,11 +60,30 @@ pub struct DocHeaderLink {
pub url: String,
}
+#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, ToSchema)]
+pub struct DocHeaderWritter {
+ pub name: String,
+ pub url: String,
+ pub avatar: String,
+}
+
+impl Default for DocHeaderWritter {
+ fn default() -> Self {
+ DocHeaderWritter {
+ name: "Maxime".to_string(),
+ url: "https://maxleriche.net".to_string(),
+ avatar: "https://avatars.githubusercontent.com/u/24699592?s=80".to_string(),
+ }
+ }
+}
+
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, ToSchema)]
pub struct DocHeader {
pub title: String,
pub date: DateTime,
pub description: Option,
+ #[serde(default = "default_doc_header_writter")]
+ pub writter: DocHeaderWritter,
#[serde(default = "default_weight")]
pub weight: i32,
#[serde(default = "empty_doc_header_spec")]
@@ -79,6 +102,11 @@ impl Default for DocHeader {
title: "".to_string(),
date: Utc::now(),
description: None,
+ writter: DocHeaderWritter {
+ name: "".to_string(),
+ url: "".to_string(),
+ avatar: "".to_string(),
+ },
weight: 0,
spec: DocHeaderSpec::default(),
tags: Vec::new(),
@@ -294,9 +322,11 @@ THIS IS A TEST
let schema_header_spec = DocHeaderSpec::schema();
let schema_header_link = DocHeaderLink::schema();
let schema_header = DocHeader::schema();
+ let schema_writter = DocHeaderWritter::schema();
assert_eq!(schema_header_spec.0, "DocHeaderSpec");
assert_eq!(schema_header_link.0, "DocHeaderLink");
assert_eq!(schema_header.0, "DocHeader");
+ assert_eq!(schema_writter.0, "DocHeaderWritter");
}
}
diff --git a/libs/back/markdown_struct/src/doc_sidebar.rs b/libs/back/markdown_struct/src/doc_sidebar.rs
index d4f4fb4..cbfca05 100644
--- a/libs/back/markdown_struct/src/doc_sidebar.rs
+++ b/libs/back/markdown_struct/src/doc_sidebar.rs
@@ -85,6 +85,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: vec![],
diff --git a/libs/back/markdown_struct/src/page_database.rs b/libs/back/markdown_struct/src/page_database.rs
index 9a10b55..8080285 100644
--- a/libs/back/markdown_struct/src/page_database.rs
+++ b/libs/back/markdown_struct/src/page_database.rs
@@ -101,6 +101,7 @@ mod tests {
.unwrap()
.into(),
description: None,
+ writter: Default::default(),
weight: 0,
spec: Default::default(),
tags: Vec::new(),
diff --git a/libs/front/api-client/src/api/schemas.gen.ts b/libs/front/api-client/src/api/schemas.gen.ts
index 11c1ee6..9502860 100644
--- a/libs/front/api-client/src/api/schemas.gen.ts
+++ b/libs/front/api-client/src/api/schemas.gen.ts
@@ -77,6 +77,9 @@ export const $DocHeader = {
weight: {
type: 'integer',
format: 'int32'
+ },
+ writter: {
+ '$ref': '#/components/schemas/DocHeaderWritter'
}
}
} as const;
@@ -109,6 +112,22 @@ export const $DocHeaderSpec = {
}
} as const;
+export const $DocHeaderWritter = {
+ type: 'object',
+ required: ['name', 'url', 'avatar'],
+ properties: {
+ avatar: {
+ type: 'string'
+ },
+ name: {
+ type: 'string'
+ },
+ url: {
+ type: 'string'
+ }
+ }
+} as const;
+
export const $HomeContent = {
type: 'object',
required: ['name', 'presentation', 'coverTitle', 'cvUrl', 'url', 'history'],
diff --git a/libs/front/api-client/src/api/types.gen.ts b/libs/front/api-client/src/api/types.gen.ts
index ad9fe07..a7d7c52 100644
--- a/libs/front/api-client/src/api/types.gen.ts
+++ b/libs/front/api-client/src/api/types.gen.ts
@@ -22,6 +22,7 @@ export type DocHeader = {
techno?: Array<(string)>;
title: string;
weight?: number;
+ writter?: DocHeaderWritter;
};
export type DocHeaderLink = {
@@ -35,6 +36,12 @@ export type DocHeaderSpec = {
project?: boolean;
};
+export type DocHeaderWritter = {
+ avatar: string;
+ name: string;
+ url: string;
+};
+
export type HomeContent = {
coverTitle: Array<(string)>;
cvUrl: string;
diff --git a/swagger.json b/swagger.json
index 13e143c..e133bf4 100644
--- a/swagger.json
+++ b/swagger.json
@@ -241,6 +241,9 @@
"weight": {
"type": "integer",
"format": "int32"
+ },
+ "writter": {
+ "$ref": "#/components/schemas/DocHeaderWritter"
}
}
},
@@ -273,6 +276,25 @@
}
}
},
+ "DocHeaderWritter": {
+ "type": "object",
+ "required": [
+ "name",
+ "url",
+ "avatar"
+ ],
+ "properties": {
+ "avatar": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ }
+ }
+ },
"HomeContent": {
"type": "object",
"required": [