Init, Main page design choices

This commit is contained in:
Matthieu Morin 2023-11-06 11:02:38 +01:00
commit 0a41b3e6ac
29 changed files with 3427 additions and 0 deletions

13
.eslintignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

30
.eslintrc.cjs Normal file
View File

@ -0,0 +1,30 @@
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
extraFileExtensions: ['.svelte']
},
env: {
browser: true,
es2017: true,
node: true
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
}
]
};

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

1
.npmrc Normal file
View File

@ -0,0 +1 @@
engine-strict=true

13
.prettierignore Normal file
View File

@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

9
.prettierrc Normal file
View File

@ -0,0 +1,9 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}

117
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,117 @@
{
"prettier.documentSelectors": [
"**/*.svelte"
],
"tailwindCSS.classAttributes": [
"class",
"accent",
"active",
"aspectRatio",
"background",
"badge",
"bgBackdrop",
"bgDark",
"bgDrawer",
"bgLight",
"blur",
"border",
"button",
"buttonAction",
"buttonBack",
"buttonClasses",
"buttonComplete",
"buttonDismiss",
"buttonNeutral",
"buttonNext",
"buttonPositive",
"buttonTextCancel",
"buttonTextConfirm",
"buttonTextFirst",
"buttonTextLast",
"buttonTextNext",
"buttonTextPrevious",
"buttonTextSubmit",
"caretClosed",
"caretOpen",
"chips",
"color",
"controlSeparator",
"controlVariant",
"cursor",
"display",
"element",
"fill",
"fillDark",
"fillLight",
"flex",
"gap",
"gridColumns",
"height",
"hover",
"inactive",
"indent",
"justify",
"meter",
"padding",
"position",
"regionAnchor",
"regionBackdrop",
"regionBody",
"regionCaption",
"regionCaret",
"regionCell",
"regionChildren",
"regionChipList",
"regionChipWrapper",
"regionCone",
"regionContent",
"regionControl",
"regionDefault",
"regionDrawer",
"regionFoot",
"regionFootCell",
"regionFooter",
"regionHead",
"regionHeadCell",
"regionHeader",
"regionIcon",
"regionInput",
"regionInterface",
"regionInterfaceText",
"regionLabel",
"regionLead",
"regionLegend",
"regionList",
"regionListItem",
"regionNavigation",
"regionPage",
"regionPanel",
"regionRowHeadline",
"regionRowMain",
"regionSummary",
"regionSymbol",
"regionTab",
"regionTrail",
"ring",
"rounded",
"select",
"shadow",
"slotDefault",
"slotFooter",
"slotHeader",
"slotLead",
"slotMessage",
"slotMeta",
"slotPageContent",
"slotPageFooter",
"slotPageHeader",
"slotSidebarLeft",
"slotSidebarRight",
"slotTrail",
"spacing",
"text",
"track",
"width",
"zIndex"
]
}

38
README.md Normal file
View File

@ -0,0 +1,38 @@
# create-svelte
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
## Building
To create a production version of your app:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.

48
package.json Normal file
View File

@ -0,0 +1,48 @@
{
"name": "cosmeticstudio",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test": "npm run test:integration && npm run test:unit",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write .",
"test:integration": "playwright test",
"test:unit": "vitest"
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.20.4",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.30.0",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.10.1",
"svelte": "^4.0.5",
"svelte-check": "^3.4.3",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.2",
"vitest": "^0.32.2",
"postcss": "8.4.31",
"autoprefixer": "10.4.16",
"tailwindcss": "3.3.3",
"@skeletonlabs/skeleton": "2.3.0",
"@skeletonlabs/tw-plugin": "0.2.2",
"vite-plugin-tailwind-purgecss": "0.1.3",
"@tailwindcss/typography": "0.5.10",
"@tailwindcss/forms": "0.5.6",
"@types/node": "20.8.8"
},
"type": "module",
"dependencies": {
"@floating-ui/dom": "1.5.3"
}
}

12
playwright.config.ts Normal file
View File

@ -0,0 +1,12 @@
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};
export default config;

2757
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

6
postcss.config.cjs Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

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

@ -0,0 +1,9 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Locals {}
// interface PageData {}
// interface Error {}
// interface Platform {}
}

19
src/app.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width" />
%sveltekit.head%
<link
rel="preload"
href="%sveltekit.assets%/fonts/Quicksand.ttf"
as="font"
type="font/ttf"
crossorigin
/>
</head>
<body data-sveltekit-preload-data="hover" data-theme="modern">
<div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
</body>
</html>

16
src/app.postcss Normal file
View File

@ -0,0 +1,16 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind variants;
html,
body {
@apply h-full overflow-hidden;
}
/* modern theme */
@font-face {
font-family: 'Quicksand';
src: url('/fonts/Quicksand.ttf');
font-display: swap;
}

7
src/index.test.ts Normal file
View File

@ -0,0 +1,7 @@
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});

View File

View File

@ -0,0 +1,3 @@
export async function getInstagramPosts() {
}

View File

@ -0,0 +1,41 @@
<script lang="ts">;
const benefits: string[] = [
'Profi služba',
'Certifikovaný personál',
'XYZ',
];
</script>
<section class="container mx-auto flex flex-col items-center px-8 py-36 sm:flex-row-reverse sm:px-12">
<div class="mb-8 w-full sm:mb-0 sm:w-1/2 sm:pl-4 md:pl-16">
<img
alt="Hanging out with friends"
class="rounded-lg sm:rounded-br-[80px] sm:rounded-tl-[120px]"
src="/images/hero.webp"
/>
</div>
<div class="mr-4 w-full text-center sm:w-1/2 sm:text-left">
<h1 class="mb-6 text-3xl font-bold leading-tight dark:text-slate-50 md:text-4xl">
WTF is this?
</h1>
<p class="mb-2 leading-relaxed text-slate-700 dark:text-slate-400">
description lorem ipsum
</p>
<ul class="mb-8 flex flex-col items-center space-y-1 dark:text-slate-400 sm:items-start">
{#each benefits as benefit}
<li class="flex items-end">
<span>{benefit}</span>
</li>
{/each}
</ul>
<div class="flex flex-col space-y-3 md:flex-row md:space-x-2 md:space-y-0">
<button class="rounded-lg border-0 bg-slate-900 px-6 py-3 text-base text-white shadow-lg shadow-slate-300 transition hover:bg-orange-300 hover:text-slate-900 hover:shadow-orange-300 dark:bg-orange-300 dark:text-black dark:shadow-sm dark:shadow-orange-300 dark:hover:bg-orange-400 sm:py-2">
Open menu
</button>
<button class="rounded-lg border-0 bg-white px-6 py-3 text-base text-slate-900 shadow-lg shadow-slate-100 transition hover:bg-orange-300 hover:text-slate-900 hover:shadow-orange-300 dark:bg-slate-700 dark:text-slate-300 dark:shadow-sm dark:shadow-slate-800 dark:hover:bg-slate-600 sm:py-2">
Explore services
</button>
</div>
</div>
</section>

View File

1
src/lib/index.ts Normal file
View File

@ -0,0 +1 @@
// place files you want to import through the `$lib` alias in this folder.

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

@ -0,0 +1,87 @@
<script lang="ts">
import '../app.postcss';
import { AppShell, AppBar, LightSwitch } from '@skeletonlabs/skeleton';
import { page } from '$app/stores';
// Floating UI for Popups
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
import { storePopup } from '@skeletonlabs/skeleton';
storePopup.set({ computePosition, autoUpdate, flip, shift, offset, arrow });
// Components
import Logo from '$lib/components/Logo.svelte';
import Cookies from '$lib/components/Cookies.svelte';
// SEO Meta tags
const metaDefaults = {
title: 'BeautySalon',
description: 'BeautySalon Popis.',
image: 'https://user-images.githubusercontent.com/1509726/212382766-f29b9c9a-82e3-44c2-b911-b17a9197e5b9.jpg'
};
const meta = {
title: metaDefaults.title,
description: metaDefaults.description,
image: metaDefaults.image,
// Article
article: { publishTime: '', modifiedTime: '', author: '' },
// Twitter
twitter: {
title: metaDefaults.title,
description: metaDefaults.description,
image: metaDefaults.image
}
};
// Scroll heading into view
function scrollHeadingIntoView(): void {
if (!window.location.hash) return;
const elemTarget: HTMLElement | null = document.querySelector(window.location.hash);
if (elemTarget) elemTarget.scrollIntoView({ behavior: 'smooth' });
};
</script>
<!-- SEO Meta tags -->
<svelte:head>
<title>{meta.title}</title>
<!-- Meta Tags -->
<meta name="title" content={meta.title} />
<meta name="description" content={meta.description} />
<meta name="keywords" content="krása, kosmetika, permanentní makeup, revitalizace pleti, oprava pleti, salón, kosmetička, kosmetický salón, Písek, obočí, vytrhání, natočení řas, řasy" />
<meta name="theme-color" content="#242c46" />
<meta name="author" content="Klára Morinová" />
<!-- Open Graph - https://ogp.me/ -->
<meta property="og:site_name" content="BeautySalon" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.beautysalon.cz{$page.url.pathname}" />
<meta property="og:locale" content="cs_CZ" />
<meta property="og:title" content={meta.title} />
<meta property="og:description" content={meta.description} />
<meta property="og:image" content={meta.image} />
<meta property="og:image:secure_url" content={meta.image} />
<meta property="og:image:type" content="image/jpg" />
<meta property="og:image:width" content="1707" />
<meta property="og:image:height" content="1233" />
<!-- Open Graph: Twitter -->
<meta name="twitter:title" content={meta.twitter.title} />
<meta name="twitter:description" content={meta.twitter.description} />
<meta name="twitter:image" content={meta.twitter.image} />
</svelte:head>
<!-- App Shell -->
<AppShell>
<svelte:fragment slot="header">
<!-- App Bar -->
<AppBar>
<svelte:fragment slot="lead">
<Logo/>
<strong class="text-xl uppercase">BeautySalon</strong>
</svelte:fragment>
<svelte:fragment slot="trail">
<LightSwitch/>
</svelte:fragment>
</AppBar>
</svelte:fragment>
<!-- Page Route Content -->
<slot />
</AppShell>

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

@ -0,0 +1,82 @@
<script lang="ts">
import HeroSection from "$lib/components/hero/HeroSection.svelte";
</script>
<HeroSection />
<!-- YOU CAN DELETE EVERYTHING IN THIS PAGE -->
<div class="container h-full mx-auto flex justify-center items-center">
<div class="space-y-10 text-center flex flex-col items-center">
<h2 class="h1">Vítej v nejvíc super salónu.</h2>
<!-- Animated Logo -->
<figure>
<section class="img-bg" />
<svg
class="fill-token -scale-x-[100%]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 200 200"
>
<path
fill-rule="evenodd"
d="M98.77 50.95c25.1 0 46.54 8.7 61.86 23a41.34 41.34 0 0 0 5.19-1.93c4.35-2.02 10.06-6.17 17.13-12.43-1.15 10.91-2.38 18.93-3.7 24.04-.7 2.75-1.8 6.08-3.3 10a80.04 80.04 0 0 1 8.42 23.33c6.04 30.3-4.3 43.7-28.33 51.18.18.9.32 1.87.42 2.9.86 8.87-3.62 23.19-9 23.19-3.54 0-5.84-4.93-8.3-12.13-.78 8.34-4.58 17.9-8.98 17.9-4.73 0-7.25-8.84-10.93-20.13a214 214 0 0 1-.64 2.93l-.16.71-.16.71-.17.71c-1.84 7.58-4.46 15.07-8.5 15.07-5.06 0-2.29-15.9-10.8-22.63-43.14 2.36-79.43-13.6-79.43-59.62 0-8.48 2-16.76 5.69-24.45a93.72 93.72 0 0 1-1.77-3.68c-2.87-6.32-6.3-15.88-10.31-28.7 10.26 7.66 18.12 12.22 23.6 13.68.5.14 1.02.26 1.57.36 14.36-14.44 35.88-24.01 60.6-24.01Zm-9.99 62.3c-14.57 0-26.39 11.45-26.39 25.58 0 14.14 11.82 25.6 26.39 25.6s26.39-11.46 26.39-25.6c0-13.99-11.58-25.35-25.95-25.58Zm37.45 31.95c-4.4 0-6.73 9.4-6.73 13.62 0 3.3 1.1 5.12 2.9 5.45 4.39.4 3.05-5.97 5.23-5.97 1.06 0 2.2 1.35 3.34 2.73l.34.42c1.25 1.52 2.5 2.93 3.64 2.49 2.7-1.61 1.67-5.12.74-7.88-3.3-6.96-5.05-10.86-9.46-10.86Zm-36.85-28.45c12.57 0 22.76 9.78 22.76 21.85 0 12.07-10.2 21.85-22.76 21.85-.77 0-1.53-.04-2.29-.11 11.5-1.1 20.46-10.42 20.46-21.74 0-11.32-8.97-20.63-20.46-21.74.76-.07 1.52-.1 2.3-.1Zm65.54-5c-10.04 0-18.18 10.06-18.18 22.47 0 12.4 8.14 22.47 18.18 22.47s18.18-10.06 18.18-22.47c0-12.41-8.14-22.48-18.18-22.48Zm.6 3.62c8.38 0 15.16 8.4 15.16 18.74 0 10.35-6.78 18.74-15.16 18.74-.77 0-1.54-.07-2.28-.21 7.3-1.36 12.89-9.14 12.89-18.53 0-9.4-5.6-17.17-12.89-18.53.74-.14 1.5-.2 2.28-.2Zm3.34-72.27.12.07c.58.38.75 1.16.37 1.74l-2.99 4.6c-.35.55-1.05.73-1.61.44l-.12-.07a1.26 1.26 0 0 1-.37-1.74l2.98-4.6a1.26 1.26 0 0 1 1.62-.44ZM39.66 42l.08.1 2.76 3.93a1.26 1.26 0 0 1-2.06 1.45l-2.76-3.94A1.26 1.26 0 0 1 39.66 42Zm63.28-42 2.85 24.13 10.62-11.94.28 29.72-2.1-.47a77.8 77.8 0 0 0-16.72-2.04c-4.96 0-9.61.67-13.96 2l-2.34.73L83.5 4.96l9.72 18.37L102.94 0Zm-1.87 13.39-7.5 17.96-7.3-13.8-1.03 19.93.22-.06a51.56 51.56 0 0 1 12.1-1.45h.31c4.58 0 9.58.54 15 1.61l.35.07-.15-16.54-9.79 11-2.21-18.72Zm38.86 19.23c.67.2 1.05.89.86 1.56l-.38 1.32c-.17.62-.8 1-1.42.89l-.13-.03a1.26 1.26 0 0 1-.86-1.56l.38-1.32c.19-.66.88-1.05 1.55-.86ZM63.95 31.1l.05.12.7 2.17a1.26 1.26 0 0 1-2.34.9l-.04-.12-.71-2.17a1.26 1.26 0 0 1 2.34-.9Z"
/>
</svg>
</figure>
<!-- / -->
<div class="flex justify-center space-x-2">
<a
class="btn variant-filled"
href="https://skeleton.dev/"
target="_blank"
rel="noreferrer"
>
O mně
</a>
</div>
<div class="space-y-2">
<p>Objednejte se</p>
<p><code class="code">/src/routes/+layout.svelte</code></p>
<p><code class="code">/src/routes/+page.svelte</code></p>
</div>
</div>
</div>
<section class="h-screen !twteam1">
<!-- Calendly inline widget begin -->
<div class="calendly-inline-widget min-h-[700px] min-w-[320px]" data-url="https://calendly.com/beautyclaire" ></div>
<script type="text/javascript" src="https://assets.calendly.com/assets/external/widget.js" async></script>
<!-- Calendly inline widget end -->
</section>
<style lang="postcss">
figure {
@apply flex relative flex-col;
}
figure svg,
.img-bg {
@apply w-64 h-64 md:w-80 md:h-80;
}
.img-bg {
@apply absolute z-[-1] rounded-full blur-[50px] transition-all;
animation: pulse 5s cubic-bezier(0, 0, 0, 0.5) infinite,
glow 5s linear infinite;
}
@keyframes glow {
0% {
@apply bg-primary-400/50;
}
33% {
@apply bg-secondary-400/50;
}
66% {
@apply bg-tertiary-400/50;
}
100% {
@apply bg-primary-400/50;
}
}
@keyframes pulse {
50% {
transform: scale(1.5);
}
}
</style>

BIN
static/fonts/Quicksand.ttf Normal file

Binary file not shown.

27
svelte.config.js Normal file
View File

@ -0,0 +1,27 @@
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: [
vitePreprocess({
style: {
css: {
postcss: join(__dirname, 'postcss.config.cjs')
}
}
})
],
kit: {
adapter: adapter()
// https://kit.svelte.dev/docs/configuration#alias
}
};
export default config;

27
tailwind.config.ts Normal file
View File

@ -0,0 +1,27 @@
import { join } from 'path'
import type { Config } from 'tailwindcss'
import forms from '@tailwindcss/forms';
import typography from '@tailwindcss/typography';
import { skeleton } from '@skeletonlabs/tw-plugin'
export default {
darkMode: 'class',
content: ['./src/**/*.{html,js,svelte,ts}', join(require.resolve('@skeletonlabs/skeleton'), '../**/*.{html,js,svelte,ts}')],
theme: {
extend: {},
},
plugins: [
forms,
typography,
skeleton({
themes: {
preset: [
{
name: 'modern',
enhancements: true,
},
],
},
}),
],
} satisfies Config;

6
tests/test.ts Normal file
View File

@ -0,0 +1,6 @@
import { expect, test } from '@playwright/test';
test('index page has expected h1', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible();
});

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
//
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
// from the referenced tsconfig.json - TypeScript does not merge them in
}

31
vite.config.ts Normal file
View File

@ -0,0 +1,31 @@
import { purgeCss } from 'vite-plugin-tailwind-purgecss';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
server: {
host: 'localhost',
port: 5174,
},
plugins: [
sveltekit(),
purgeCss({
safelist: {
// any selectors that begin with "hljs-" will not be purged
greedy: [/^hljs-/],
},
}),],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
},
resolve: {
alias: {
$lib: path.resolve(__dirname, 'src', 'lib'),
$root: path.resolve(__dirname),
$src: path.resolve(__dirname, 'src'),
$routes: path.resolve(__dirname, 'src', 'routes')
}
}
});