This commit is contained in:
parent
b5d2cfc18c
commit
f86697e00d
28
Dockerfile
28
Dockerfile
|
@ -1,28 +0,0 @@
|
|||
# Stage 1: Build the Astro project
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json and package-lock.json files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install
|
||||
|
||||
# Copy the rest of the application files
|
||||
COPY . .
|
||||
|
||||
# Build the Astro project
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: Serve with nginx
|
||||
FROM nginx:alpine
|
||||
|
||||
# Copy the built static files from the builder stage
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Copy custom nginx configuration file if needed
|
||||
# COPY default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Expose port 80 to the outside world
|
||||
EXPOSE 80
|
49
src/components/EmojiReactionForm.astro
Normal file
49
src/components/EmojiReactionForm.astro
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
const { entryId } = Astro.props;
|
||||
const backendHost = import.meta.env.PUBLIC_BACKEND_HOST;
|
||||
---
|
||||
|
||||
<style is:global>
|
||||
.emoji-button {
|
||||
border: none;
|
||||
@apply text-lg rounded-full p-2;
|
||||
}
|
||||
|
||||
.emoji-buttons-container {
|
||||
@apply flex flex-row gap-2;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form
|
||||
hx-post=`${backendHost}/blog/api/forms/emoji/post`
|
||||
hx-target="#reaction-buttons"
|
||||
>
|
||||
<input type="hidden" name="postId" value=`${entryId}` />
|
||||
<div
|
||||
id="reaction-buttons"
|
||||
hx-get=`${backendHost}/blog/api/forms/emoji?postId=${entryId}`
|
||||
hx-trigger="load"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<div class="emoji-buttons-container">
|
||||
<button name="emojiInput" value="👍" type="submit" class="emoji-button"
|
||||
>👍 </button
|
||||
>
|
||||
<button name="emojiInput" value="👎" type="submit" class="emoji-button"
|
||||
>👎 </button
|
||||
>
|
||||
<button name="emojiInput" value="😀" type="submit" class="emoji-button"
|
||||
>😀 </button
|
||||
>
|
||||
<button name="emojiInput" value="😑" type="submit" class="emoji-button"
|
||||
>😑 </button
|
||||
>
|
||||
<button name="emojiInput" value="🤢" type="submit" class="emoji-button"
|
||||
>🤢 </button
|
||||
>
|
||||
<button name="emojiInput" value="👀" type="submit" class="emoji-button"
|
||||
>👀 </button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
|
@ -55,14 +55,24 @@
|
|||
|
||||
<script>
|
||||
import ConwaySimulator from "../scripts/conway-simulator";
|
||||
let rows = 8;
|
||||
let cols = 24;
|
||||
let pixelSize = 4;
|
||||
let pixelSize = 6;
|
||||
let delay = 250;
|
||||
|
||||
if (screen.availWidth > 768) {
|
||||
cols = 46;
|
||||
pixelSize = 8;
|
||||
}
|
||||
|
||||
let gol = new ConwaySimulator(8, cols, pixelSize, 250);
|
||||
document.getElementById("board")?.append(gol.canvas);
|
||||
gol.start();
|
||||
let gameOfLife = new ConwaySimulator(rows, cols, pixelSize, delay);
|
||||
|
||||
const boardElement = document.getElementById("board");
|
||||
if (boardElement) {
|
||||
boardElement.append(gameOfLife.canvas);
|
||||
} else {
|
||||
console.error("Board element could not be found.");
|
||||
}
|
||||
|
||||
gameOfLife.start();
|
||||
</script>
|
||||
|
|
|
@ -8,34 +8,53 @@ interface Props {
|
|||
|
||||
const { post, componentType } = Astro.props;
|
||||
|
||||
let showTags, shortSummary, longSummary, fullText, postFooter;
|
||||
// default options for the post component
|
||||
const deafultOptions = {
|
||||
showTags: false,
|
||||
shortSummary: false,
|
||||
longSummary: false,
|
||||
fullText: false,
|
||||
postFooter: false,
|
||||
};
|
||||
|
||||
const options = { ...deafultOptions };
|
||||
// Determine which options should be applied to post
|
||||
switch (componentType) {
|
||||
case "full":
|
||||
postFooter = true;
|
||||
showTags = true;
|
||||
fullText = true;
|
||||
options.postFooter = true;
|
||||
options.showTags = true;
|
||||
options.fullText = true;
|
||||
break;
|
||||
case "long":
|
||||
longSummary = true;
|
||||
showTags = true;
|
||||
options.longSummary = true;
|
||||
options.showTags = true;
|
||||
break;
|
||||
case "short":
|
||||
shortSummary = true;
|
||||
options.shortSummary = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Options should not mutated further
|
||||
Object.freeze(options);
|
||||
|
||||
// Format datae
|
||||
const postDateFormatted = post.data.date.toLocaleDateString("tr-TR", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
|
||||
// Create post link
|
||||
const postLink = `/category/${post.data.category}/${post.slug}`;
|
||||
|
||||
// Create post content as an astro component
|
||||
const { Content } = await post.render();
|
||||
|
||||
import { Image } from "astro:assets";
|
||||
import questionMark from "@/images/questionMark.svg";
|
||||
import calendar from "@/images/calendar.svg";
|
||||
---
|
||||
|
||||
<style>
|
||||
|
@ -57,17 +76,9 @@ const { Content } = await post.render();
|
|||
>
|
||||
<div class="flex flex-row gap-2">
|
||||
{
|
||||
showTags && (
|
||||
options.showTags && (
|
||||
<div class="flex items-center gap-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="#6d6d6d"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path d="M140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180ZM128,72c-22.06,0-40,16.15-40,36v4a8,8,0,0,0,16,0v-4c0-11,10.77-20,24-20s24,9,24,20-10.77,20-24,20a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-.72c18.24-3.35,32-17.9,32-35.28C168,88.15,150.06,72,128,72Zm104,56A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" />
|
||||
</svg>
|
||||
<Image alt="question mark" src={questionMark} />
|
||||
<ul class="list-none flex pl-0 meta-list">
|
||||
{post.data.tags.map((tag) => (
|
||||
<li class="text-sm text-gray-500">{tag}</li>
|
||||
|
@ -78,26 +89,17 @@ const { Content } = await post.render();
|
|||
}
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="#6d6d6d"
|
||||
viewBox="0 0 256 256"
|
||||
><path
|
||||
d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-68-76a12,12,0,1,1-12-12A12,12,0,0,1,140,132Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,184,132ZM96,172a12,12,0,1,1-12-12A12,12,0,0,1,96,172Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,140,172Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,184,172Z"
|
||||
></path></svg
|
||||
>
|
||||
<Image alt="calendar" src={calendar} />
|
||||
<ul class="list-none flex pl-0 meta-list">
|
||||
<p class="text-sm text-gray-500">{postDateFormatted}</p>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{shortSummary && <p class="post-summary">{post.data.summary}</p>}
|
||||
{options.shortSummary && <p class="post-summary">{post.data.summary}</p>}
|
||||
|
||||
{
|
||||
longSummary && (
|
||||
options.longSummary && (
|
||||
<>
|
||||
<p class="post-long-summary">
|
||||
{post.body.slice(0, 500).replace(/(<([^>]+)>)/gi, "")}
|
||||
|
@ -114,11 +116,15 @@ const { Content } = await post.render();
|
|||
)
|
||||
}
|
||||
{
|
||||
fullText && (
|
||||
options.fullText && (
|
||||
<div class="text-lg">
|
||||
<Content />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{postFooter && <p class="text-gray-600 text-sm">{postDateFormatted}</p>}
|
||||
{
|
||||
options.postFooter && (
|
||||
<p class="text-gray-600 text-sm">{postDateFormatted}</p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
|
10
src/images/calendar.svg
Normal file
10
src/images/calendar.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="#6d6d6d"
|
||||
viewBox="0 0 256 256"
|
||||
><path
|
||||
d="M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM72,48v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80H48V48ZM208,208H48V96H208V208Zm-68-76a12,12,0,1,1-12-12A12,12,0,0,1,140,132Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,184,132ZM96,172a12,12,0,1,1-12-12A12,12,0,0,1,96,172Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,140,172Zm44,0a12,12,0,1,1-12-12A12,12,0,0,1,184,172Z"
|
||||
></path></svg
|
||||
>
|
After Width: | Height: | Size: 610 B |
9
src/images/questionMark.svg
Normal file
9
src/images/questionMark.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="#6d6d6d"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path d="M140,180a12,12,0,1,1-12-12A12,12,0,0,1,140,180ZM128,72c-22.06,0-40,16.15-40,36v4a8,8,0,0,0,16,0v-4c0-11,10.77-20,24-20s24,9,24,20-10.77,20-24,20a8,8,0,0,0-8,8v8a8,8,0,0,0,16,0v-.72c18.24-3.35,32-17.9,32-35.28C168,88.15,150.06,72,128,72Zm104,56A104,104,0,1,1,128,24,104.11,104.11,0,0,1,232,128Zm-16,0a88,88,0,1,0-88,88A88.1,88.1,0,0,0,216,128Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 489 B |
|
@ -5,6 +5,7 @@ import Footer from "@/components/Footer.astro";
|
|||
import Header from "@/components/Header.astro";
|
||||
import Layout from "@/layouts/Layout.astro";
|
||||
import Post from "@/components/Post.astro";
|
||||
import EmojiReactionForm from "@/components/EmojiReactionForm.astro";
|
||||
|
||||
const { entry } = Astro.props;
|
||||
|
||||
|
@ -15,38 +16,11 @@ export async function getStaticPaths() {
|
|||
props: { entry },
|
||||
}));
|
||||
}
|
||||
|
||||
const backendHost = import.meta.env.PUBLIC_BACKEND_HOST;
|
||||
---
|
||||
|
||||
<style>
|
||||
.emoji-label {
|
||||
@apply cursor-pointer bg-zinc-200 p-1 rounded-full;
|
||||
}
|
||||
.emoji-input {
|
||||
display: none;
|
||||
}
|
||||
.emoji-input:checked + .emoji-label {
|
||||
@apply cursor-pointer bg-zinc-200 p-1 rounded-full outline outline-1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<Layout title="log101">
|
||||
<Header />
|
||||
<Post post={entry} componentType="full" />
|
||||
|
||||
<form
|
||||
hx-post=`${backendHost}/blog/api/forms/emoji/post`
|
||||
hx-target="#reaction-buttons"
|
||||
>
|
||||
<input type="hidden" name="postId" value=`${entry.id}` />
|
||||
<div
|
||||
id="reaction-buttons"
|
||||
hx-get=`${backendHost}/blog/api/forms/emoji?postId=${entry.id}`
|
||||
hx-trigger="load"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<EmojiReactionForm postId={entry.id} />
|
||||
<Footer />
|
||||
</Layout>
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
const cells = ['30', '20', '51', '01', '62', '63', '03', '64', '54', '44', '34', '24', '14']
|
||||
const cells = [
|
||||
"30",
|
||||
"20",
|
||||
"51",
|
||||
"01",
|
||||
"62",
|
||||
"63",
|
||||
"03",
|
||||
"64",
|
||||
"54",
|
||||
"44",
|
||||
"34",
|
||||
"24",
|
||||
"14",
|
||||
];
|
||||
|
||||
export const heavyWeightSpaceshipCell = (x, y) => {
|
||||
const coor = `${x}${y}`
|
||||
return cells.includes(coor)
|
||||
}
|
||||
const coordinates = `${x}${y}`;
|
||||
return cells.includes(coordinates);
|
||||
};
|
||||
|
|
|
@ -18,15 +18,6 @@ body {
|
|||
background-color: #f5fffa;
|
||||
}
|
||||
|
||||
.emoji-button {
|
||||
border: none;
|
||||
@apply text-lg rounded-full p-2;
|
||||
}
|
||||
|
||||
.emoji-buttons-container {
|
||||
@apply flex flex-row gap-2;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.posts {
|
||||
@apply flex flex-col gap-10 md:gap-8;
|
||||
|
|
Loading…
Reference in New Issue
Block a user