mirror of
https://github.com/sergeyyarkov/astro-directus-example.git
synced 2026-10-11 02:08:57 +03:00
setup
This commit is contained in:
commit
5ab2e94394
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
uploads/
|
||||
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# build output
|
||||
dist/
|
||||
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@ -0,0 +1,30 @@
|
||||
# syntax=docker/dockerfile:1.0
|
||||
|
||||
ARG NODE_IMAGE=node:19-alpine3.16
|
||||
ARG NGINX_IMAGE=nginx:1.23.3-alpine
|
||||
|
||||
FROM ${NODE_IMAGE} as development
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./package.json ./
|
||||
COPY ./package-lock.json ./
|
||||
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000
|
||||
CMD [ "npm", "start" ]
|
||||
|
||||
FROM development as builder
|
||||
RUN npm run build
|
||||
|
||||
FROM ${NGINX_IMAGE} as production
|
||||
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
COPY --from=builder /app/nginx/conf.d /etc/nginx/conf.d
|
||||
COPY --from=builder /app/nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
47
README.md
Normal file
47
README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Astro Starter Kit: Minimal
|
||||
|
||||
```
|
||||
npm create astro@latest -- --template minimal
|
||||
```
|
||||
|
||||
[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
|
||||
[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```
|
||||
/
|
||||
├── public/
|
||||
├── src/
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
└── package.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||
21
astro.config.mjs
Normal file
21
astro.config.mjs
Normal file
@ -0,0 +1,21 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
/**
|
||||
* Integrations
|
||||
*/
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: 'static',
|
||||
server: {
|
||||
host: true,
|
||||
},
|
||||
integrations: [
|
||||
tailwind({
|
||||
config: {
|
||||
applyBaseStyles: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
70
docker-compose.yml
Normal file
70
docker-compose.yml
Normal file
@ -0,0 +1,70 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
target: production
|
||||
container_name: web
|
||||
volumes:
|
||||
- './nginx/conf.d:/etc/nginx/conf.d'
|
||||
- './nginx/nginx.conf:/etc/nginx/nginx.conf'
|
||||
ports:
|
||||
- '80:80'
|
||||
networks:
|
||||
- directus
|
||||
depends_on:
|
||||
- directus
|
||||
|
||||
database:
|
||||
image: postgres:15-alpine
|
||||
container_name: database
|
||||
environment:
|
||||
POSTGRES_USER: directus
|
||||
POSTGRES_PASSWORD: directus
|
||||
POSTGRES_DB: directus
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
||||
networks:
|
||||
- directus
|
||||
|
||||
cache:
|
||||
container_name: cache
|
||||
image: redis:6
|
||||
networks:
|
||||
- directus
|
||||
|
||||
directus:
|
||||
image: directus/directus:latest
|
||||
ports:
|
||||
- 8055
|
||||
volumes:
|
||||
- uploads:/directus/uploads
|
||||
depends_on:
|
||||
- cache
|
||||
- database
|
||||
networks:
|
||||
- directus
|
||||
environment:
|
||||
KEY: '255d861b-5ea1-5996-9aa3-922530ec40b1'
|
||||
SECRET: '6116487b-cda1-52c2-b5b5-c8022c45e263'
|
||||
|
||||
DB_CLIENT: 'pg'
|
||||
DB_HOST: 'database'
|
||||
DB_PORT: '5432'
|
||||
DB_DATABASE: 'directus'
|
||||
DB_USER: 'directus'
|
||||
DB_PASSWORD: 'directus'
|
||||
|
||||
CACHE_ENABLED: 'true'
|
||||
CACHE_STORE: 'redis'
|
||||
CACHE_REDIS: 'redis://cache:6379'
|
||||
|
||||
ADMIN_EMAIL: 'admin@example.com'
|
||||
ADMIN_PASSWORD: 'd1r3ctu5'
|
||||
volumes:
|
||||
db-data:
|
||||
uploads:
|
||||
networks:
|
||||
directus:
|
||||
48
nginx/conf.d/default.conf
Normal file
48
nginx/conf.d/default.conf
Normal file
@ -0,0 +1,48 @@
|
||||
client_max_body_size 10M;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name localhost;
|
||||
server_tokens off;
|
||||
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
location ~* \.(css|js|png|jpe?g|wepb|ico|gif|svg)$ {
|
||||
add_header Cache-Control "public";
|
||||
access_log off;
|
||||
expires 30d;
|
||||
}
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
error_page 404 /404.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name cms.localhost;
|
||||
server_tokens off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://directus:8055;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
}
|
||||
29
nginx/conf.d/gzip.conf
Normal file
29
nginx/conf.d/gzip.conf
Normal file
@ -0,0 +1,29 @@
|
||||
gzip on;
|
||||
gzip_disable "msie6";
|
||||
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_min_length 256;
|
||||
gzip_types
|
||||
application/atom+xml
|
||||
application/geo+json
|
||||
application/javascript
|
||||
application/x-javascript
|
||||
application/json
|
||||
application/ld+json
|
||||
application/manifest+json
|
||||
application/rdf+xml
|
||||
application/rss+xml
|
||||
application/xhtml+xml
|
||||
application/xml
|
||||
font/eot
|
||||
font/otf
|
||||
font/ttf
|
||||
image/svg+xml
|
||||
text/css
|
||||
text/javascript
|
||||
text/plain
|
||||
text/xml;
|
||||
29
nginx/nginx.conf
Normal file
29
nginx/nginx.conf
Normal file
@ -0,0 +1,29 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
9448
package-lock.json
generated
Normal file
9448
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "astro-wordpress-example",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/tailwind": "^3.0.1",
|
||||
"astro": "^2.0.16",
|
||||
"astro-icon": "^0.8.0",
|
||||
"tailwindcss": "^3.2.7"
|
||||
}
|
||||
}
|
||||
13
public/favicon.svg
Normal file
13
public/favicon.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 36 36">
|
||||
<path fill="#000" d="M22.25 4h-8.5a1 1 0 0 0-.96.73l-5.54 19.4a.5.5 0 0 0 .62.62l5.05-1.44a2 2 0 0 0 1.38-1.4l3.22-11.66a.5.5 0 0 1 .96 0l3.22 11.67a2 2 0 0 0 1.38 1.39l5.05 1.44a.5.5 0 0 0 .62-.62l-5.54-19.4a1 1 0 0 0-.96-.73Z"/>
|
||||
<path fill="url(#gradient)" d="M18 28a7.63 7.63 0 0 1-5-2c-1.4 2.1-.35 4.35.6 5.55.14.17.41.07.47-.15.44-1.8 2.93-1.22 2.93.6 0 2.28.87 3.4 1.72 3.81.34.16.59-.2.49-.56-.31-1.05-.29-2.46 1.29-3.25 3-1.5 3.17-4.83 2.5-6-.67.67-2.6 2-5 2Z"/>
|
||||
<defs>
|
||||
<linearGradient id="gradient" x1="16" x2="16" y1="32" y2="24" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#000"/>
|
||||
<stop offset="1" stop-color="#000" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<style>
|
||||
@media (prefers-color-scheme:dark){:root{filter:invert(100%)}}
|
||||
</style>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 873 B |
BIN
public/media/placeholder-social.jpg
Normal file
BIN
public/media/placeholder-social.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
3
scripts/hello.sh
Normal file
3
scripts/hello.sh
Normal file
@ -0,0 +1,3 @@
|
||||
#!bin/bash
|
||||
|
||||
echo "Hello!"
|
||||
18
src/components/BaseHead.astro
Normal file
18
src/components/BaseHead.astro
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
export interface Props {
|
||||
title?: string;
|
||||
noindex?: boolean;
|
||||
}
|
||||
|
||||
const { title = 'Blog', noindex = false } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<link rel='icon' type='image/svg+xml' href='/favicon.svg' />
|
||||
<meta name='viewport' content='width=device-width' />
|
||||
<meta name='generator' content={Astro.generator} />
|
||||
{noindex && <meta name='robots' content='noindex' />}
|
||||
<title>{title}</title>
|
||||
<slot />
|
||||
</head>
|
||||
8
src/components/Footer.astro
Normal file
8
src/components/Footer.astro
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<footer>
|
||||
<hr />
|
||||
<small>Web Blog © {year}</small>
|
||||
</footer>
|
||||
43
src/components/Header.astro
Normal file
43
src/components/Header.astro
Normal file
@ -0,0 +1,43 @@
|
||||
---
|
||||
import { Icon } from 'astro-icon';
|
||||
|
||||
const links = [
|
||||
{ href: '/', name: 'Home' },
|
||||
{ href: '/about/', name: 'About' },
|
||||
{ href: '/contact/', name: 'Contact' },
|
||||
];
|
||||
---
|
||||
|
||||
<header>
|
||||
<div>
|
||||
<div class='flex justify-between items-center'>
|
||||
<h1>Web Blog</h1>
|
||||
<span>
|
||||
<Icon name='blog' width='52' height='52' />
|
||||
</span>
|
||||
</div>
|
||||
<nav class='mt-2'>
|
||||
<ul class='flex space-x-4'>
|
||||
{
|
||||
links.map((l) => (
|
||||
<li>
|
||||
<a
|
||||
class:list={[
|
||||
'hover:underline italic',
|
||||
{ 'font-bold': Astro.url.pathname.slice(1) === l.href.slice(1) },
|
||||
]}
|
||||
href={l.href}>
|
||||
{l.name}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<hr />
|
||||
<p class='italic text-gray-700'>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque debitis nemo nulla praesentium!
|
||||
Qui praesentium quos alias neque, optio beatae.
|
||||
</p>
|
||||
</header>
|
||||
21
src/content/blog/first-post.md
Normal file
21
src/content/blog/first-post.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: 'My First Post'
|
||||
tags: ['javascript', 'web-development']
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra.'
|
||||
pubDate: 'Feb 28 2023'
|
||||
image: '/media/placeholder-social.jpg'
|
||||
---
|
||||
|
||||
# Heading 1
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra. Adipiscing enim eu turpis egestas pretium. Euismod elementum nisi quis eleifend quam adipiscing. In hac habitasse platea dictumst vestibulum. Sagittis purus sit amet volutpat. Netus et malesuada fames ac turpis egestas. Eget magna fermentum iaculis eu non diam phasellus vestibulum lorem. Varius sit amet mattis vulputate enim. Habitasse platea dictumst quisque sagittis. Integer quis auctor elit sed vulputate mi. Dictumst quisque sagittis purus sit amet.
|
||||
|
||||
## Heading 2
|
||||
|
||||
Morbi tristique senectus et netus. Id semper risus in hendrerit gravida rutrum quisque non tellus. Habitasse platea dictumst quisque sagittis purus sit amet. Tellus molestie nunc non blandit massa. Cursus vitae congue mauris rhoncus. Accumsan tortor posuere ac ut. Fringilla urna porttitor rhoncus dolor. Elit ullamcorper dignissim cras tincidunt lobortis. In cursus turpis massa tincidunt dui ut ornare lectus. Integer feugiat scelerisque varius morbi enim nunc. Bibendum neque egestas congue quisque egestas diam. Cras ornare arcu dui vivamus arcu felis bibendum. Dignissim suspendisse in est ante in nibh mauris. Sed tempus urna et pharetra pharetra massa massa ultricies mi.
|
||||
|
||||
Mollis nunc sed id semper risus in. Convallis a cras semper auctor neque. Diam sit amet nisl suscipit. Lacus viverra vitae congue eu consequat ac felis donec. Egestas integer eget aliquet nibh praesent tristique magna sit amet. Eget magna fermentum iaculis eu non diam. In vitae turpis massa sed elementum. Tristique et egestas quis ipsum suspendisse ultrices. Eget lorem dolor sed viverra ipsum. Vel turpis nunc eget lorem dolor sed viverra. Posuere ac ut consequat semper viverra nam. Laoreet suspendisse interdum consectetur libero id faucibus. Diam phasellus vestibulum lorem sed risus ultricies tristique. Rhoncus dolor purus non enim praesent elementum facilisis. Ultrices tincidunt arcu non sodales neque. Tempus egestas sed sed risus pretium quam vulputate. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus ornare. Fringilla urna porttitor rhoncus dolor purus non. Amet dictum sit amet justo donec enim.
|
||||
|
||||
Mattis ullamcorper velit sed ullamcorper morbi tincidunt. Tortor posuere ac ut consequat semper viverra. Tellus mauris a diam maecenas sed enim ut sem viverra. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Arcu ac tortor dignissim convallis aenean et tortor at. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Egestas tellus rutrum tellus pellentesque eu. Fusce ut placerat orci nulla pellentesque dignissim enim sit amet. Ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Id donec ultrices tincidunt arcu. Id cursus metus aliquam eleifend mi.
|
||||
|
||||
Tempus quam pellentesque nec nam aliquam sem. Risus at ultrices mi tempus imperdiet. Id porta nibh venenatis cras sed felis eget velit. Ipsum a arcu cursus vitae. Facilisis magna etiam tempor orci eu lobortis elementum. Tincidunt dui ut ornare lectus sit. Quisque non tellus orci ac. Blandit libero volutpat sed cras. Nec tincidunt praesent semper feugiat nibh sed pulvinar proin gravida. Egestas integer eget aliquet nibh praesent tristique magna.
|
||||
24
src/content/config.ts
Normal file
24
src/content/config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { z, defineCollection } from 'astro:content';
|
||||
|
||||
const blogCollection = defineCollection({
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
tags: z.array(z.string()),
|
||||
image: z.string().optional(),
|
||||
draft: z.boolean().optional(),
|
||||
pubDate: z
|
||||
.string()
|
||||
.or(z.date())
|
||||
.transform((val) => new Date(val)),
|
||||
updDate: z
|
||||
.string()
|
||||
.or(z.date())
|
||||
.transform((val) => new Date(val))
|
||||
.optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = {
|
||||
blog: blogCollection,
|
||||
};
|
||||
2
src/env.d.ts
vendored
Normal file
2
src/env.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/// <reference path="../.astro/types.d.ts" />
|
||||
/// <reference types="astro/client" />
|
||||
1
src/icons/blog.svg
Normal file
1
src/icons/blog.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><path fill="currentColor" d="M192 32c0 17.7 14.3 32 32 32c123.7 0 224 100.3 224 224c0 17.7 14.3 32 32 32s32-14.3 32-32C512 128.9 383.1 0 224 0c-17.7 0-32 14.3-32 32zm0 96c0 17.7 14.3 32 32 32c70.7 0 128 57.3 128 128c0 17.7 14.3 32 32 32s32-14.3 32-32c0-106-86-192-192-192c-17.7 0-32 14.3-32 32zm-96 16c0-26.5-21.5-48-48-48S0 117.5 0 144v224c0 79.5 64.5 144 144 144s144-64.5 144-144s-64.5-144-144-144h-16v96h16c26.5 0 48 21.5 48 48s-21.5 48-48 48s-48-21.5-48-48V144z"/></svg>
|
||||
|
After Width: | Height: | Size: 561 B |
27
src/layouts/PageLayout.astro
Normal file
27
src/layouts/PageLayout.astro
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
import '../styles/global.css';
|
||||
import BaseHead from '../components/BaseHead.astro';
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
|
||||
export interface Props {
|
||||
title?: string;
|
||||
lang?: string;
|
||||
noindex?: boolean;
|
||||
}
|
||||
|
||||
const { lang = 'en', title, noindex = false } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<html lang={lang}>
|
||||
<BaseHead title={title} noindex={noindex} />
|
||||
<body>
|
||||
<div class='max-w-[800px] mx-auto py-7 px-4 flex flex-col min-h-screen'>
|
||||
<Header />
|
||||
<main class='mt-10 flex-auto'>
|
||||
<slot />
|
||||
</main>
|
||||
<Footer />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
7
src/pages/404.astro
Normal file
7
src/pages/404.astro
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
import PageLayout from '../layouts/PageLayout.astro';
|
||||
---
|
||||
|
||||
<PageLayout noindex>
|
||||
<h1 class='text-3xl font-semibold text-center'>404 Not Found</h1>
|
||||
</PageLayout>
|
||||
7
src/pages/about.astro
Normal file
7
src/pages/about.astro
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
import PageLayout from '../layouts/PageLayout.astro';
|
||||
---
|
||||
|
||||
<PageLayout title={'About'}>
|
||||
<div>...</div>
|
||||
</PageLayout>
|
||||
28
src/pages/blog/[slug].astro
Normal file
28
src/pages/blog/[slug].astro
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
import { CollectionEntry, getCollection } from 'astro:content';
|
||||
import PageLayout from '../../layouts/PageLayout.astro';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('blog');
|
||||
return posts.map((post) => ({ params: { slug: post.slug }, props: { post } }));
|
||||
}
|
||||
|
||||
const { post } = Astro.props as { post: CollectionEntry<'blog'> };
|
||||
const { title, description, image, pubDate } = post.data;
|
||||
const { Content } = await post.render();
|
||||
---
|
||||
|
||||
<PageLayout title={title}>
|
||||
<div class='flex justify-between flex-wrap gap-3 items-center'>
|
||||
<h1>{title}</h1>
|
||||
<span class='italic'>
|
||||
Published: <time datetime={pubDate.toISOString()}>{pubDate.toLocaleDateString()}</time>
|
||||
</span>
|
||||
</div>
|
||||
<hr />
|
||||
<p>{description}</p>
|
||||
{image && <img class='my-5' src={image} alt={title} />}
|
||||
<div>
|
||||
<Content />
|
||||
</div>
|
||||
</PageLayout>
|
||||
7
src/pages/contact.astro
Normal file
7
src/pages/contact.astro
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
import PageLayout from '../layouts/PageLayout.astro';
|
||||
---
|
||||
|
||||
<PageLayout title={'Contact'}>
|
||||
<div>...</div>
|
||||
</PageLayout>
|
||||
37
src/pages/index.astro
Normal file
37
src/pages/index.astro
Normal file
@ -0,0 +1,37 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import PageLayout from '../layouts/PageLayout.astro';
|
||||
|
||||
const posts = await getCollection('blog', (e) => !e.data.draft);
|
||||
---
|
||||
|
||||
<PageLayout title={'Welcome to my blog'}>
|
||||
<section>
|
||||
{
|
||||
posts.map((p) => (
|
||||
<article class='border-b'>
|
||||
<a href={`/blog/${p.slug}/`}>
|
||||
<div class='lg:flex lg:items-center'>
|
||||
<div class='py-2'>
|
||||
<h2>{p.data.title}</h2>
|
||||
<p>{p.data.description}</p>
|
||||
<time class='italic text-sm' datetime={p.data.pubDate.toISOString()}>
|
||||
Published: {p.data.pubDate.toLocaleDateString()}
|
||||
</time>
|
||||
</div>
|
||||
{p.data.image && (
|
||||
<div class='lg:ml-5 flex justify-center border-t py-5 lg:py-0 lg:border-none'>
|
||||
<img
|
||||
class='w-full md:max-w-[500px] lg:max-w-[700px]'
|
||||
src={p.data.image}
|
||||
alt={p.data.title}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
</PageLayout>
|
||||
29
src/styles/global.css
Normal file
29
src/styles/global.css
Normal file
@ -0,0 +1,29 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
h1,
|
||||
h2 {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
h2 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
@apply my-2;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply my-2.5;
|
||||
}
|
||||
|
||||
img {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
8
tailwind.config.cjs
Normal file
8
tailwind.config.cjs
Normal file
@ -0,0 +1,8 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
6
tsconfig.json
Normal file
6
tsconfig.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"strictNullChecks": true
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user