create post on the back

This commit is contained in:
guamss 2026-08-22 11:07:28 +02:00
parent ccbf9d84ae
commit fd18e2ae41
15 changed files with 569 additions and 47 deletions

View File

@ -3,6 +3,7 @@ import { defineConfig, fontProviders } from "astro/config";
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
output: "static",
fonts: [ fonts: [
{ {
provider: fontProviders.local(), provider: fontProviders.local(),

View File

@ -12,6 +12,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^7.1.6" "astro": "^7.1.6",
"axios": "^1.19.0"
} }
} }

232
pnpm-lock.yaml generated
View File

@ -11,6 +11,9 @@ importers:
astro: astro:
specifier: ^7.1.6 specifier: ^7.1.6
version: 7.1.6(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) version: 7.1.6(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)
axios:
specifier: ^1.19.0
version: 1.19.0
packages: packages:
@ -687,6 +690,10 @@ packages:
'@ungap/structured-clone@1.3.3': '@ungap/structured-clone@1.3.3':
resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==} resolution: {integrity: sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==}
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
am-i-vibing@0.4.0: am-i-vibing@0.4.0:
resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==} resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==}
hasBin: true hasBin: true
@ -712,6 +719,12 @@ packages:
'@astrojs/markdown-remark': '@astrojs/markdown-remark':
optional: true optional: true
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
axios@1.19.0:
resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==}
axobject-query@4.1.0: axobject-query@4.1.0:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -722,6 +735,10 @@ packages:
boolbase@1.0.0: boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
ccount@2.0.1: ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@ -743,6 +760,10 @@ packages:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'} engines: {node: '>=6'}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
comma-separated-tokens@2.0.3: comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
@ -783,9 +804,22 @@ packages:
resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
defu@6.1.7: defu@6.1.7:
resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
dequal@2.0.3: dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -824,6 +858,10 @@ packages:
resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
engines: {node: '>=4'} engines: {node: '>=4'}
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
entities@4.5.0: entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
@ -832,9 +870,25 @@ packages:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
es-module-lexer@2.3.1: es-module-lexer@2.3.1:
resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==}
es-object-atoms@1.1.2:
resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
engines: {node: '>= 0.4'}
es-set-tostringtag@2.1.0:
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
engines: {node: '>= 0.4'}
esbuild@0.28.1: esbuild@0.28.1:
resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -871,6 +925,15 @@ packages:
resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
follow-redirects@1.16.0:
resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
fontace@0.4.1: fontace@0.4.1:
resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==}
@ -878,11 +941,26 @@ packages:
resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==}
engines: {node: '>=20'} engines: {node: '>=20'}
form-data@4.0.6:
resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==}
engines: {node: '>= 6'}
fsevents@2.3.3: fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin] os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
get-tsconfig@5.0.0-beta.4: get-tsconfig@5.0.0-beta.4:
resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==}
engines: {node: '>=20.20.0'} engines: {node: '>=20.20.0'}
@ -890,9 +968,25 @@ packages:
github-slugger@2.0.0: github-slugger@2.0.0:
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
h3@1.15.11: h3@1.15.11:
resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==}
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
has-tostringtag@1.0.2:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
hasown@2.0.4:
resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
engines: {node: '>= 0.4'}
hast-util-from-html@2.0.3: hast-util-from-html@2.0.3:
resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
@ -920,6 +1014,10 @@ packages:
http-cache-semantics@4.2.0: http-cache-semantics@4.2.0:
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
iron-webcrypto@1.2.1: iron-webcrypto@1.2.1:
resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
@ -1023,6 +1121,10 @@ packages:
magicast@0.5.4: magicast@0.5.4:
resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
mdast-util-to-hast@13.2.1: mdast-util-to-hast@13.2.1:
resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
@ -1047,10 +1149,21 @@ packages:
micromark-util-types@2.0.2: micromark-util-types@2.0.2:
resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
mrmime@2.0.1: mrmime@2.0.1:
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
engines: {node: '>=10'} engines: {node: '>=10'}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
nanoid@3.3.16: nanoid@3.3.16:
resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -1139,6 +1252,10 @@ packages:
property-information@7.2.0: property-information@7.2.0:
resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
proxy-from-env@2.1.0:
resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
engines: {node: '>=10'}
radix3@1.1.2: radix3@1.1.2:
resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
@ -1921,6 +2038,12 @@ snapshots:
'@ungap/structured-clone@1.3.3': {} '@ungap/structured-clone@1.3.3': {}
agent-base@6.0.2:
dependencies:
debug: 4.4.3
transitivePeerDependencies:
- supports-color
am-i-vibing@0.4.0: am-i-vibing@0.4.0:
dependencies: dependencies:
process-ancestry: 0.1.0 process-ancestry: 0.1.0
@ -2026,12 +2149,29 @@ snapshots:
- uploadthing - uploadthing
- yaml - yaml
asynckit@0.4.0: {}
axios@1.19.0:
dependencies:
follow-redirects: 1.16.0
form-data: 4.0.6
https-proxy-agent: 5.0.1
proxy-from-env: 2.1.0
transitivePeerDependencies:
- debug
- supports-color
axobject-query@4.1.0: {} axobject-query@4.1.0: {}
bail@2.0.2: {} bail@2.0.2: {}
boolbase@1.0.0: {} boolbase@1.0.0: {}
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
ccount@2.0.1: {} ccount@2.0.1: {}
character-entities-html4@2.1.0: {} character-entities-html4@2.1.0: {}
@ -2046,6 +2186,10 @@ snapshots:
clsx@2.1.1: {} clsx@2.1.1: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
comma-separated-tokens@2.0.3: {} comma-separated-tokens@2.0.3: {}
commander@11.1.0: {} commander@11.1.0: {}
@ -2084,8 +2228,14 @@ snapshots:
dependencies: dependencies:
css-tree: 2.2.1 css-tree: 2.2.1
debug@4.4.3:
dependencies:
ms: 2.1.3
defu@6.1.7: {} defu@6.1.7: {}
delayed-stream@1.0.0: {}
dequal@2.0.3: {} dequal@2.0.3: {}
destr@2.0.5: {} destr@2.0.5: {}
@ -2120,12 +2270,33 @@ snapshots:
dset@3.1.4: {} dset@3.1.4: {}
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
entities@4.5.0: {} entities@4.5.0: {}
entities@6.0.1: {} entities@6.0.1: {}
es-define-property@1.0.1: {}
es-errors@1.3.0: {}
es-module-lexer@2.3.1: {} es-module-lexer@2.3.1: {}
es-object-atoms@1.1.2:
dependencies:
es-errors: 1.3.0
es-set-tostringtag@2.1.0:
dependencies:
es-errors: 1.3.0
get-intrinsic: 1.3.0
has-tostringtag: 1.0.2
hasown: 2.0.4
esbuild@0.28.1: esbuild@0.28.1:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.28.1 '@esbuild/aix-ppc64': 0.28.1
@ -2177,6 +2348,8 @@ snapshots:
flattie@1.1.1: {} flattie@1.1.1: {}
follow-redirects@1.16.0: {}
fontace@0.4.1: fontace@0.4.1:
dependencies: dependencies:
fontkitten: 1.0.3 fontkitten: 1.0.3
@ -2185,15 +2358,45 @@ snapshots:
dependencies: dependencies:
tiny-inflate: 1.0.3 tiny-inflate: 1.0.3
form-data@4.0.6:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
es-set-tostringtag: 2.1.0
hasown: 2.0.4
mime-types: 2.1.35
fsevents@2.3.3: fsevents@2.3.3:
optional: true optional: true
function-bind@1.1.2: {}
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
es-object-atoms: 1.1.2
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
hasown: 2.0.4
math-intrinsics: 1.1.0
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
es-object-atoms: 1.1.2
get-tsconfig@5.0.0-beta.4: get-tsconfig@5.0.0-beta.4:
dependencies: dependencies:
resolve-pkg-maps: 1.0.0 resolve-pkg-maps: 1.0.0
github-slugger@2.0.0: {} github-slugger@2.0.0: {}
gopd@1.2.0: {}
h3@1.15.11: h3@1.15.11:
dependencies: dependencies:
cookie-es: 1.2.3 cookie-es: 1.2.3
@ -2206,6 +2409,16 @@ snapshots:
ufo: 1.6.4 ufo: 1.6.4
uncrypto: 0.1.3 uncrypto: 0.1.3
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
dependencies:
has-symbols: 1.1.0
hasown@2.0.4:
dependencies:
function-bind: 1.1.2
hast-util-from-html@2.0.3: hast-util-from-html@2.0.3:
dependencies: dependencies:
'@types/hast': 3.0.5 '@types/hast': 3.0.5
@ -2262,6 +2475,13 @@ snapshots:
http-cache-semantics@4.2.0: {} http-cache-semantics@4.2.0: {}
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.4.3
transitivePeerDependencies:
- supports-color
iron-webcrypto@1.2.1: {} iron-webcrypto@1.2.1: {}
is-docker@4.0.0: {} is-docker@4.0.0: {}
@ -2335,6 +2555,8 @@ snapshots:
'@babel/types': 7.29.8 '@babel/types': 7.29.8
source-map-js: 1.2.1 source-map-js: 1.2.1
math-intrinsics@1.1.0: {}
mdast-util-to-hast@13.2.1: mdast-util-to-hast@13.2.1:
dependencies: dependencies:
'@types/hast': 3.0.5 '@types/hast': 3.0.5
@ -2368,8 +2590,16 @@ snapshots:
micromark-util-types@2.0.2: {} micromark-util-types@2.0.2: {}
mime-db@1.52.0: {}
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
mrmime@2.0.1: {} mrmime@2.0.1: {}
ms@2.1.3: {}
nanoid@3.3.16: {} nanoid@3.3.16: {}
neotraverse@1.0.1: {} neotraverse@1.0.1: {}
@ -2443,6 +2673,8 @@ snapshots:
property-information@7.2.0: {} property-information@7.2.0: {}
proxy-from-env@2.1.0: {}
radix3@1.1.2: {} radix3@1.1.2: {}
readdirp@5.0.0: {} readdirp@5.0.0: {}

38
src/api/axios.ts Normal file
View File

@ -0,0 +1,38 @@
import axios, { AxiosError, create } from "axios";
import type { PostOut } from "../models/post";
const api = axios.create({
baseURL: "http://localhost:8000",
});
export function handleApiError(error: unknown): never {
if (error instanceof AxiosError) {
const errorMessage =
error.response?.data?.message ||
error.response?.data ||
error.message ||
"Erreur de l'API";
console.error(errorMessage.detail, "error");
} else {
console.error("Une erreur inattendue s'est produite", error);
}
throw error;
}
export const postService = {
async sendIllustration(illustration: File) {
const formData = new FormData();
formData.append("file", illustration);
return api
.post(`/posts/illustrations/upload/`, formData)
.catch(handleApiError);
},
async sendDocumentImages(images: File[]) {
const formData = new FormData();
images.forEach((image) => formData.append("files", image));
return api.post(`/posts/images/upload/`, formData).catch(handleApiError);
},
async sendPost(post: PostOut) {
return api.post(`/posts/`, post).catch(handleApiError);
},
};

View File

@ -6,7 +6,7 @@ const { id, title, description, pubDate, updatedDate, illustration } =
--- ---
<article> <article>
<img src="https://www.w3schools.com/CSS/img_lights.jpg" /> <img src={illustration.src} />
<a href={`/posts/${id}`}><h1>{title}</h1></a> <a href={`/posts/${id}`}><h1>{title}</h1></a>
<time datetime={pubDate.toISOString()}> <time datetime={pubDate.toISOString()}>
{ {

View File

@ -9,6 +9,7 @@ const blog = defineCollection({
title: z.string(), title: z.string(),
description: z.string(), description: z.string(),
pubDate: z.coerce.date(), pubDate: z.coerce.date(),
tags: z.array(z.string()),
updatedDate: z.coerce.date().optional(), updatedDate: z.coerce.date().optional(),
illustration: z.optional(image()), illustration: z.optional(image()),
}), }),

View File

@ -3,9 +3,7 @@ title: "Analyse approfondie de Goodbye Eri"
pubDate: 2024-11-30 pubDate: 2024-11-30
description: 'Dans ce post j''analyse le one shot "Goodbye, Eri" écrit par Tatsuki Fujimoto. J''y aborde beaucoup d''aspects du manga comme la mémoire humaine, la spontanéité des uns qui vient en opposition avec l''hypocrisie des autres et plein d''autres thèmes ! Disclaimer : Tout comme mon post sur "Persona 3 Reload - Episode Aigis", je spoil l''intégralité de l''oeuvre.' description: 'Dans ce post j''analyse le one shot "Goodbye, Eri" écrit par Tatsuki Fujimoto. J''y aborde beaucoup d''aspects du manga comme la mémoire humaine, la spontanéité des uns qui vient en opposition avec l''hypocrisie des autres et plein d''autres thèmes ! Disclaimer : Tout comme mon post sur "Persona 3 Reload - Episode Aigis", je spoil l''intégralité de l''oeuvre.'
author: "Guams" author: "Guams"
image: illustration: "image.png"
url: "https://docs.astro.build/assets/rose.webp"
alt: "The Astro logo on a dark background with a pink glow."
tags: ["Manga"] tags: ["Manga"]
--- ---

View File

@ -3,9 +3,7 @@ title: "Analyse de Fire Punch"
pubDate: 2025-07-29 pubDate: 2025-07-29
description: "Voici mon analyse concernant Fire Punch, j'aborde pas mal d'aspects du manga comme la place importante qu'ont la religion et le cinéma !" description: "Voici mon analyse concernant Fire Punch, j'aborde pas mal d'aspects du manga comme la place importante qu'ont la religion et le cinéma !"
author: "Guams" author: "Guams"
image: illustration: "image.png"
url: "https://docs.astro.build/assets/rose.webp"
alt: "The Astro logo on a dark background with a pink glow."
tags: ["Manga"] tags: ["Manga"]
--- ---

View File

@ -3,9 +3,7 @@ title: "Analyse de P3R - Épisode Aigis"
pubDate: 2024-10-21 pubDate: 2024-10-21
description: "Dans ce post j'analyse Persona 3 Reload - Épisode Aigis, on a plutôt une analyse de la philosophie ainsi que la mentalité des personnages ici. Disclaimer : JE SPOIL ABSOLUMENT TOUT LE DLC" description: "Dans ce post j'analyse Persona 3 Reload - Épisode Aigis, on a plutôt une analyse de la philosophie ainsi que la mentalité des personnages ici. Disclaimer : JE SPOIL ABSOLUMENT TOUT LE DLC"
author: "Guams" author: "Guams"
image: illustration: "image.png"
url: "https://docs.astro.build/assets/rose.webp"
alt: "The Astro logo on a dark background with a pink glow."
tags: ["Jeux vidéos"] tags: ["Jeux vidéos"]
--- ---
@ -23,41 +21,51 @@ Voici ma remise en contexte non exhaustive, la fin est un peu brutale car je pr
Comme dit plus haut, on a dès le début de l'œuvre une Aigis remplie dincertitude quant à sa raison d'être. Manquant de volonté de vivre, elle a demandé à Mitsuru si cela était possible de la ramener au labo, cest un peu une manière de mettre fin à ses jours. On peut dailleurs comprendre un peu mieux sa tristesse avec lOST “Disconected”, voici deux paragraphes provenant de celle-ci : Comme dit plus haut, on a dès le début de l'œuvre une Aigis remplie dincertitude quant à sa raison d'être. Manquant de volonté de vivre, elle a demandé à Mitsuru si cela était possible de la ramener au labo, cest un peu une manière de mettre fin à ses jours. On peut dailleurs comprendre un peu mieux sa tristesse avec lOST “Disconected”, voici deux paragraphes provenant de celle-ci :
Paragraphe n°1 <br>
“Feeling empty <u>Paragraphe n°1</u>
Spending days and nights of silence _"Feeling empty_
'Cause no words can explain how I feel _Spending days and nights of silence_
In my mind, and heart _'Cause no words can explain how I feel_
Oh, I don't know what I am but I miss myself _In my mind, and heart_
'Cause she's not here anymore _Oh, I don't know what I am but I miss myself_
How can I move on? Please tell me” _'Cause she's not here anymore_
Paragraphe n°2 _How can I move on? Please tell me"_
“It feels like my heart is suffocating <br>
How do you make amends when you're gone from me? <u>Paragraphe n°2</u>
Even though with a win _"It feels like my heart is suffocating_
How come I feel so lost? _How do you make amends when you're gone from me?_
Nothing makes sense to me _Even though with a win_
I'm so numb, so lost without you” _How come I feel so lost?_
_Nothing makes sense to me_
_I'm so numb, so lost without you"_
<br>
Dans cette OST Aigis parle à la première personne, on voit ici une certaine détresse quant à son état mental. On peut considérer ça comme une sérieuse dépression, elle ne dort plus, le cœur serré, plus rien na de sens sans Makoto. Il y a aussi deux vers très intéressants dans le paragraphe n°1 sont : Dans cette OST Aigis parle à la première personne, on voit ici une certaine détresse quant à son état mental. On peut considérer ça comme une sérieuse dépression, elle ne dort plus, le cœur serré, plus rien na de sens sans Makoto. Il y a aussi deux vers très intéressants dans le paragraphe n°1 sont :
“Oh, I don't know what I am but I miss myself <br>
'Cause she's not here anymore” "_Oh, I don't know what I am but I miss myself_
_'Cause she's not here anymore”_
<br>
Ici Aigis fait directement référence à Métis qui est en réalité partie intégrante delle, mais par manque de volonté elle sest elle-même dénigrée (ce qui a mené à larrêt du temps). Métis qui représente son humanité et sa volonté de vivre, c'est aussi pour ça que quand Aigis refuse de vivre Métis sest mise à pleurer, car elle refuse que Aigis meure, cela voudrait dire quelle se retrouverait à nouveau seule. Ici Aigis fait directement référence à Métis qui est en réalité partie intégrante delle, mais par manque de volonté elle sest elle-même dénigrée (ce qui a mené à larrêt du temps). Métis qui représente son humanité et sa volonté de vivre, c'est aussi pour ça que quand Aigis refuse de vivre Métis sest mise à pleurer, car elle refuse que Aigis meure, cela voudrait dire quelle se retrouverait à nouveau seule.
@ -77,24 +85,26 @@ Ensuite je vais parler des différentes batailles didéaux, dans cette partie
Une fois toutes les portes ouvertes Métis révèle que la solution pour sortir de cette boucle temporelle, il faut forger la clé et chacun des membres de la SEES en possède une partie. Cette clé servira soit à revenir au présent, soit à revenir dans le passé et pour la forger, il faut soit un accord collectif soit une soumission de lautre à notre idée par un combat. On a alors plusieurs camps qui se forment : Une fois toutes les portes ouvertes Métis révèle que la solution pour sortir de cette boucle temporelle, il faut forger la clé et chacun des membres de la SEES en possède une partie. Cette clé servira soit à revenir au présent, soit à revenir dans le passé et pour la forger, il faut soit un accord collectif soit une soumission de lautre à notre idée par un combat. On a alors plusieurs camps qui se forment :
Aegis - Aegis
Métis - Métis
Fuuka - Fuuka
Le second : Le second :
Amada - Amada
Sanada - Sanada
Le troisième : Le troisième :
Junpei - Junpei
Koromaru - Koromaru
Le dernier : Le dernier :
Mitsuru - Mitsuru
Yukari - Yukari
<br>
Dans le premier camp cest léquipe des indécis, Aegis par manque de volonté, Métis pour protéger Aegis et Fuuka uniquement pas indécision. Dans le premier camp cest léquipe des indécis, Aegis par manque de volonté, Métis pour protéger Aegis et Fuuka uniquement pas indécision.
@ -108,23 +118,27 @@ On a donc deux idées qui se confrontent ici (sans compter les indécis), de l
Yukari narrive visiblement pas à accepter sa défaite, dailleurs, parce quaprès avoir soumis le reste de l'équipe, elle fond en larmes en exprimant à quel point son père lui manque, ce qui appuie lusure psychologique de certains membres de léquipe quant à leurs traumatismes. Sans trop de rapport, je trouve important de préciser que dans lOST “Dont” la chanteuse nous décrit le point de vue dun membre de la SEES qui se bat pour sa vision des choses : Yukari narrive visiblement pas à accepter sa défaite, dailleurs, parce quaprès avoir soumis le reste de l'équipe, elle fond en larmes en exprimant à quel point son père lui manque, ce qui appuie lusure psychologique de certains membres de léquipe quant à leurs traumatismes. Sans trop de rapport, je trouve important de préciser que dans lOST “Dont” la chanteuse nous décrit le point de vue dun membre de la SEES qui se bat pour sa vision des choses :
“Do not make me <br>
Already lost my keys _"Do not make me_
To the door wide shut _Already lost my keys_
Only have one wish _To the door wide shut_
Now it's never gonna come true _Only have one wish_
Trapped in time _Now it's never gonna come true_
Forever in remorse _Trapped in time_
How could I ever be _Forever in remorse_
In peace when nothing else matters to me” _How could I ever be_
_In peace when nothing else matters to me”_
<br>
Métis a par la suite convaincu Aegis de continuer de vivre, car Métis est en réalité la partie que Aegis a refusé daccepter (son humanité, son envie de vivre). Après être redevenue lucide, Aegis a pris la décision de revenir dans le présent, or pour cela il faut franchir une dernière porte… Métis a par la suite convaincu Aegis de continuer de vivre, car Métis est en réalité la partie que Aegis a refusé daccepter (son humanité, son envie de vivre). Après être redevenue lucide, Aegis a pris la décision de revenir dans le présent, or pour cela il faut franchir une dernière porte…

View File

10
src/models/post.ts Normal file
View File

@ -0,0 +1,10 @@
export class PostOut {
content: string = "";
illustration_image: string = "";
document_images: Map<string, string> = new Map();
}
export class PostIn {
id: number = 0;
content: string = "";
}

154
src/pages/post-create.astro Normal file
View File

@ -0,0 +1,154 @@
---
import { postService } from "../api/axios";
import Layout from "../layouts/Layout.astro";
import { PostOut } from "../models/post";
import "../styles/post-create.css";
export const prerender = false;
if (Astro.request.method === "POST") {
try {
const data = await Astro.request.formData();
const postToSend: PostOut = new PostOut();
const mdFile = data.get("markdownInput");
const illustration = data.get("illustrationInput");
const documentImages = data
.getAll("documentImagesInput")
.filter((entry) => entry instanceof File);
if (illustration instanceof File && illustration.size > 0) {
await postService.sendIllustration(illustration).then((res) => {
postToSend.illustration_image = res.data;
});
}
await postService.sendDocumentImages(documentImages).then((res) => {
postToSend.document_images = new Map(Object.entries(res.data));
});
if (mdFile instanceof File) {
await mdFile.text().then((txt) => (postToSend.content = txt));
await postService
.sendPost(postToSend)
.then((res) => console.log(res.data));
}
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
}
---
<Layout>
<form method="POST" enctype="multipart/form-data">
<u>Consigne</u>
<p>le markdown doit contenir cette entête :</p>
<pre>
---
<span class="green">title</span>: <span class="blue">"titre"</span>
<span class="green">pubDate</span>: <span class="blue">YYYY-MM-DD</span>
<span class="green">description</span>: <span class="blue">'description du post'</span>
<span class="green">author</span>: <span class="blue">"author"</span>
<span class="green">illustration</span>: <span class="blue">"image.png"</span>
<span class="green">tags</span>: [<span class="blue">"Manga"</span>, <span class="blue">"Anime"</span>]
---
</pre>
<label for="markdownInput">
<span id="mdMessage">Ajouter un fichier markdown</span>
<span id="mdFilename"></span>
</label>
<input
id="markdownInput"
type="file"
name="markdownInput"
accept=".md"
required
/>
<label for="illustrationInput" id="illustrationLabel">
Ajouter l'image d'illustration du document
</label>
<input
id="illustrationInput"
type="file"
name="illustrationInput"
accept="image/*"
required
/>
<label for="documentImagesInput" id="documentImagesLabel">
Ajouter les images du document
</label>
<input
id="documentImagesInput"
type="file"
name="documentImagesInput"
accept="image/*"
multiple
required
/>
<button type="submit">Créer le post</button>
</form>
</Layout>
<script>
const mdInput = document.querySelector<HTMLInputElement>("#markdownInput");
const mdMessage = document.querySelector<HTMLElement>("#mdMessage");
const mdFilename = document.querySelector<HTMLElement>("#mdFilename");
mdInput?.addEventListener("change", (event) => {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (file && mdMessage && mdFilename) {
mdMessage.style.display = "none";
mdFilename.textContent = file.name;
} else if (mdMessage && mdFilename) {
mdMessage.style.display = "inline";
mdFilename.textContent = "";
}
});
const illustrationInput =
document.querySelector<HTMLInputElement>("#illustrationInput");
const illustrationLabel =
document.querySelector<HTMLElement>("#illustrationLabel");
illustrationInput?.addEventListener("change", (event) => {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (illustrationLabel) {
illustrationLabel.textContent = file
? file.name
: "Ajouter l'image d'illustration du document";
}
});
const documentImagesInput = document.querySelector<HTMLInputElement>(
"#documentImagesInput",
);
const documentImagesLabel = document.querySelector<HTMLElement>(
"#documentImagesLabel",
);
documentImagesInput?.addEventListener("change", (event) => {
const target = event.target as HTMLInputElement;
const files = target.files;
if (documentImagesLabel && files) {
if (files.length === 1) {
documentImagesLabel.textContent = files[0].name;
} else if (files.length > 1) {
documentImagesLabel.textContent = `${files.length} images sélectionnées`;
} else {
documentImagesLabel.textContent = "Ajouter les images du document";
}
}
});
</script>

View File

@ -18,6 +18,14 @@ const { Content } = await render(post);
<Layout> <Layout>
<main> <main>
<div>
<h1>{post.data.title}</h1>
<h2>{post.data.tags}</h2>
<img
src={post.data.illustration?.src}
alt={post.data?.illustration?.src}
/>
</div>
<Content /> <Content />
</main> </main>
</Layout> </Layout>

View File

@ -0,0 +1,41 @@
@import "global.css";
form {
display: flex;
flex-direction: column;
align-items: stretch;
> pre {
padding: 1rem;
margin: 2rem;
background-color: #121314;
color: #bbbebf;
border-radius: 4px;
> span.green {
color: #7ee787;
}
> span.blue {
color: #a5d6ff;
}
}
> input#markdownInput,
input#documentImagesInput,
input#illustrationInput {
display: none;
}
> label {
margin: 1rem;
padding: 2rem;
border: 2px dashed var(--primary-dark-border-color);
&:hover {
cursor: pointer;
transition: 0.3s;
background-color: var(--secondary-dark-background-color);
}
}
}

View File

@ -2,15 +2,41 @@
main { main {
padding: 2rem; padding: 2rem;
> div {
text-align: center;
> h1 {
font-size: 56px;
font-weight: 400;
}
> h2 {
font-weight: 400;
font-style: italic;
}
> img {
object-fit: cover;
border-radius: 8px;
width: 100%;
height: 24rem;
margin: 4rem 0;
}
}
> h1 { > h1 {
font-size: 56px; font-size: 56px;
font-weight: 400; font-weight: 400;
} }
> p { > p {
font-size: 19px; font-size: 19px;
word-break: break-word;
text-align: justify;
text-justify: inter-word;
> img { > img {
margin: auto; display: block;
margin: 1rem auto;
} }
} }
} }