first commit

This commit is contained in:
2024-05-29 22:29:18 +02:00
commit 5058d7ae26
27 changed files with 4528 additions and 0 deletions

11
src/app.css Normal file
View File

@@ -0,0 +1,11 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
.section-wrapper {
@apply max-w-4xl mx-auto
}
html {
scroll-behavior: smooth;
}

13
src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
}
export {};

12
src/app.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

8
src/hooks.server.js Normal file
View File

@@ -0,0 +1,8 @@
import { env } from '$lib';
import { redirect } from '@sveltejs/kit';
/** @type {import('@sveltejs/kit').Handle} */
export async function handle({ event, resolve }) {
if(new URL(event.request.url).host === env.sites_host) redirect(302, env.youpage)
return resolve(event);
}

5
src/lib/env.js Normal file
View File

@@ -0,0 +1,5 @@
export const env = {
api_url: "http://localhost:3000",
youpage: "http://localhost:3002",
sites_host: "127.0.0.1.nip.io:3001"
}

2
src/lib/index.js Normal file
View File

@@ -0,0 +1,2 @@
// place files you want to import through the `$lib` alias in this folder.
export * from "./env";

22
src/lib/ui/header.svelte Normal file
View File

@@ -0,0 +1,22 @@
<script>
export let title;
export let subtitle;
export let titleClasses = "";
export let subtitleClasses = "";
</script>
<div class="mt-44 mb-20 bg-white text-center w-full">
<div class="section-wrapper">
{#if title}
<h1 class="text-7xl/none mb-5 font-bold {titleClasses}">
{title}
</h1>
{/if}
{#if subtitle}
<p class="text-2xl/normal max-w-2xl mx-auto text-gray-700 {subtitleClasses}">
{subtitle}
</p>
{/if}
</div>
</div>

View File

@@ -0,0 +1,16 @@
import { redirect } from "@sveltejs/kit";
import { env } from "$lib";
/** @type {import("./$types").LayoutServerLoad} */
export async function load(event) {
let res = await event.fetch(env.api_url + "/blog");
if (!res.ok) {
redirect(302, env.youpage);
}
let blog_info = await res.json();
return {
blog: blog_info
}
}

50
src/routes/+layout.svelte Normal file
View File

@@ -0,0 +1,50 @@
<script>
import "../app.css";
export let data;
</script>
<div
class="py-5 px-24 w-full fixed h-min top-0 flex flex-row justify-between bg-white drop-shadow-md"
>
<div>
<a href="/" class="font-bold text-2xl">{data.blog.site.name}</a>
</div>
<div>
<a
href="#subscribe-form"
class="px-8 py-3 bg-gray-900 text-white rounded-lg font-semibold ml-auto"
>Subscribe</a
>
</div>
</div>
<slot></slot>
<div class="bg-white py-16 text-center" id="subscribe-form">
<div class="max-w-lg mx-auto">
<h3 class="text-3xl font-bold mb-3">Our newsletter</h3>
<p class="text-base/7 mb-8">
A bi-weekly newsletter of design inspiration, resources and anything
related to career development.
</p>
<div
class="max-w-[400px] whitespace-nowrap flex justify-around mx-auto"
>
<input
type="text"
placeholder="Email address"
class="py-3 px-5 flex-grow border-l border-y border-solid border-gray-300 h-[50px] rounded-l-lg"
/>
<button
class="px-8 py-3 bg-gray-900 text-white font-semibold rounded-r-lg h-[50px]"
>Subscribe</button
>
</div>
</div>
</div>
<div class="h-24 flex items-center justify-center border-t border-gray-200">
<span>Copyright {new Date().getFullYear()} - Omer Sabic</span>
</div>
<style></style>

45
src/routes/+page.svelte Normal file
View File

@@ -0,0 +1,45 @@
<script>
import Header from "$lib/ui/header.svelte";
export let data;
let { blog } = data;
</script>
<div>
<Header
title={blog?.site.title}
subtitle={blog?.site.subtitle}
/>
<div class="bg-gray-100 py-20">
<div class="section-wrapper">
<h2 class="text-2xl mb-8 font-bold">Latest articles</h2>
<div class="flex flex-col gap-5">
{#each blog?.articles || [] as article}
<a href="/{article.seo_slug}">
<div
class="bg-white rounded-3xl px-8 py-8 flex flex-row sm:flex-col"
>
<div>
<span
class="text-sm text-gray-400 font-normal mb-8"
>{new Date(
article.created_at,
).toLocaleDateString("en-de", {
day: "2-digit",
month: "long",
year: "numeric",
})}</span
>
<h3 class="text-2xl font-semibold">
{article.title}
</h3>
</div>
</div>
</a>
{/each}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1 @@
export const ssr = false;

View File

@@ -0,0 +1,47 @@
<script>
import { env } from "$lib";
import Header from "$lib/ui/header.svelte";
import { onMount } from "svelte";
import { page } from "$app/stores";
import "./md-style.css";
import SvelteMarkdown from "svelte-markdown";
/**
* @type {any}
*/
let article;
onMount(async () => {
article = (
await fetch(
env.api_url + "/blog/article?slug=" + $page.params.slug,
).then((x) => {
return x.json();
})
).article;
});
export let data;
$: console.log(article);
</script>
<div>
<Header
title={article?.title}
titleClasses="text-4xl/none"
subtitle={new Date(article?.created_at).toLocaleDateString("en-de", {
day: "2-digit",
month: "long",
year: "numeric",
})}
subtitleClasses="text-sm font-bold"
></Header>
<div class="mt-12">
<div class="max-w-2xl mx-auto">
<div class="markdown-body">
<SvelteMarkdown source={article?.content} options={{breaks: true, gfm: true}} />
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,156 @@
/* Base styles for the markdown container */
.markdown-body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
line-height: 1.6;
color: #333;
background-color: #fff;
padding: 20px;
max-width: 800px;
margin: auto;
}
/* Headings */
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 {
margin-top: 1em;
margin-bottom: 0.5em;
font-weight: bold;
line-height: 1.25;
}
.markdown-body h1 {
font-size: 2em;
}
.markdown-body h2 {
font-size: 1.75em;
}
.markdown-body h3 {
font-size: 1.5em;
}
.markdown-body h4 {
font-size: 1.25em;
}
.markdown-body h5 {
font-size: 1em;
}
.markdown-body h6 {
font-size: 0.875em;
color: #6a737d;
}
/* Paragraphs */
.markdown-body p {
margin: 0 0 1em;
}
/* Links */
.markdown-body a {
color: #0366d6;
text-decoration: none;
}
.markdown-body a:hover {
text-decoration: underline;
}
/* Lists */
.markdown-body ul, .markdown-body ol {
padding-left: 2em;
margin-top: 0;
margin-bottom: 1em;
}
.markdown-body ul ul, .markdown-body ol ol, .markdown-body ul ol, .markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}
.markdown-body li {
margin-bottom: 0.5em;
}
/* Blockquotes */
.markdown-body blockquote {
padding: 0 1em;
color: #6a737d;
border-left: 0.25em solid #dfe2e5;
margin: 0 0 1em;
}
/* Code */
.markdown-body code {
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 85%;
background-color: rgba(27,31,35,0.05);
border-radius: 3px;
padding: 0.2em 0.4em;
}
.markdown-body pre {
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 85%;
background-color: #f6f8fa;
border-radius: 3px;
padding: 1em;
overflow: auto;
line-height: 1.45;
margin: 0 0 1em;
}
.markdown-body pre code {
background-color: transparent;
padding: 0;
}
/* Horizontal Rule */
.markdown-body hr {
border: 0;
border-top: 1px solid #e1e4e8;
height: 0;
margin: 1em 0;
}
/* Tables */
.markdown-body table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin-bottom: 1em;
}
.markdown-body th, .markdown-body td {
border: 1px solid #dfe2e5;
padding: 0.6em 1em;
}
.markdown-body th {
background-color: #f6f8fa;
font-weight: bold;
}
.markdown-body td {
background-color: #fff;
}
/* Images */
.markdown-body img {
max-width: 100%;
height: auto;
}
/* Inline HTML */
.markdown-body details {
background-color: #f6f8fa;
border: 1px solid #dfe2e5;
border-radius: 3px;
padding: 0.5em 1em;
}
.markdown-body summary {
cursor: pointer;
font-weight: bold;
}