This commit is contained in:
yyasha 2023-11-10 13:58:42 +03:00
parent 07972a2e86
commit a5f0bcb522
29 changed files with 2729 additions and 0 deletions

1
.npmrc Normal file
View File

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

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.

2210
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"name": "recipes-front",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test": "playwright test"
},
"devDependencies": {
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.20.4",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"svelte": "^4.0.5",
"tailwindcss": "^3.3.5",
"vite": "^4.4.2"
},
"type": "module",
"dependencies": {
"axios": "^1.6.0"
}
}

11
playwright.config.js Normal file
View File

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

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

3
src/app.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

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>

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

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

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

@ -0,0 +1,15 @@
<script>
import "../app.css";
import Header from "./Header.svelte";
import Footer from "./Footer.svelte";
</script>
<Header/>
<slot />
<!-- <Footer/> -->
<style>
</style>

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

@ -0,0 +1,33 @@
<script>
import axios from 'axios';
let serverurl = 'http://127.0.0.1:3000';
let recipes_p = axios.get(serverurl+"/recipes?page=59");
recipes_p.then(function (response) {
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
</script>
<div class="bg-white">
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl lg:px-8">
<h2 class="sr-only">Products</h2>
<div class="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
{#await recipes_p}
waiting...
{:then data}
{#each data.data.recipes as recipe (recipe.id)}
<a href="/recipe/{recipe.id}" class="group transition duration-300 hover:scale-110">
<div class="aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-lg bg-gray-200 xl:aspect-h-8 xl:aspect-w-7">
<img src="{serverurl}/recipe_image?filename={recipe.img}" alt="{recipe.title}" class="h-full w-full object-cover object-center transition duration-700 group-hover:opacity-90">
</div>
<h3 class="mt-3 text-base text-gray-700">{recipe.ctime} / {recipe.cal}</h3>
<p class="mt-0 text-lg font-medium text-gray-900">{recipe.title}</p>
</a>
{/each}
{/await}
</div>
</div>
</div>

6
src/routes/Footer.svelte Normal file
View File

@ -0,0 +1,6 @@
<footer class="bg-white">
<hr>
<nav class="mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8" aria-label="Global">
<p>Copyright © <a href="/">always delicious</a> 2023</p>
</nav>
</footer>

68
src/routes/Header.svelte Normal file
View File

@ -0,0 +1,68 @@
<!-- <script>
import logo from '$lib/assets/logo1.png';
</script> -->
<header class="bg-slate-50">
<nav class="mx-auto flex max-w-7xl items-center justify-between p-6 lg:px-8" aria-label="Global">
<div class="flex lg:flex-1">
<a href="/" class="-m-1.5 p-1.5">
<span class="sr-only">Your Company</span>
<img class="h-10 w-auto" src="/logo1.png" alt="">
</a>
</div>
<div class="flex lg:hidden">
<button type="button" class="-m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700">
<span class="sr-only">Open main menu</span>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
</div>
<div class="hidden lg:flex lg:gap-x-12">
<a href="/" class="text-sm font-semibold leading-6 text-gray-900">Все рецепты</a>
<a href="/categories" class="text-sm font-semibold leading-6 text-gray-900">Категории</a>
<a href="/donate" class="text-sm font-semibold leading-6 text-gray-900">Поддержать сайт</a>
</div>
<div class="hidden lg:flex lg:flex-1 lg:justify-end">
</div>
</nav>
<!-- Mobile menu, show/hide based on menu open state. -->
<div class="lg:hidden" role="dialog" aria-modal="true">
<!-- Background backdrop, show/hide based on slide-over state. -->
<div class="fixed inset-0 z-10"></div>
<div class="fixed inset-y-0 right-0 z-10 w-full overflow-y-auto bg-white px-6 py-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div class="flex items-center justify-between">
<a href="#" class="-m-1.5 p-1.5">
<span class="sr-only">Your Company</span>
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600" alt="">
</a>
<button type="button" class="-m-2.5 rounded-md p-2.5 text-gray-700">
<span class="sr-only">Close menu</span>
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="mt-6 flow-root">
<div class="-my-6 divide-y divide-gray-500/10">
<div class="space-y-2 py-6">
<a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Features</a>
<a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Marketplace</a>
<a href="#" class="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50">Company</a>
</div>
</div>
</div>
</div>
</div>
</header>
<!-- todo:
категории
закрытие и открытие меню для телефона
мобильная вёрстка
дозагрузка страниц на главной странице
донат
поиск
-->

View File

@ -0,0 +1,2 @@
<h1>About</h1>
asd

View File

@ -0,0 +1,27 @@
<script>
let category_list = ["Завтраки", "Коктейли", "Закуски", "Салаты", "Соусы", "Десерты", "Выпечка", "Основные блюда", "Супы"]
let serverurl = 'http://127.0.0.1:3000';
</script>
<div class="bg-white">
<div class="mx-auto max-w-2xl px-4 py-16 sm:px-6 sm:py-24 lg:max-w-7xl lg:px-8">
<h2 class="sr-only">Products</h2>
<div class="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
{#each category_list as category}
<a href="/categories/{category}" class="relative group transition duration-300 hover:scale-110">
<div class="aspect-h-1 aspect-w-1 w-full h-full overflow-hidden rounded-lg bg-gray-200 xl:aspect-h-8 xl:aspect-w-7">
<img src="{serverurl}/recipe_image?filename=1b0dc44c-5dc3-4a74-9bb8-1a079999caa9.jpg" alt="{category}" class="brightness-30 h-full w-full object-cover object-center transition duration-700 group-hover:brightness-50">
<p class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-lg font-bold text-slate-200 group-hover:text-white duration-700">{category}</p>
</div>
</a>
{/each}
</div>
</div>
</div>
<style>
.brightness-30 {
--tw-brightness: brightness(.3);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
</style>

View File

@ -0,0 +1,9 @@
<script>
import { page } from '$app/stores';
console.log($page.params.category)
</script>
<div>
hello, {$page.params.category}
</div>

View File

@ -0,0 +1,227 @@
<script>
import { page } from '$app/stores';
import axios from 'axios';
// create request
let serverurl = 'http://127.0.0.1:3000';
let recipe_p = axios.get(serverurl+"/recipe?r_id="+$page.params.recipeid)
recipe_p.then(function (response) {
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
</script>
<div class="mx-20 px-4 py-8">
<!-- await -->
{#await recipe_p}
<div class="text-center flex items-center justify-center h-screen">
<div role="status">
<svg aria-hidden="true" class="inline w-8 h-8 mr-2 text-gray-200 animate-spin dark:text-gray-200 fill-blue-600" viewBox="0 0 100 101" fill="none">
<path d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z" fill="currentColor"/>
<path d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z" fill="currentFill"/>
</svg>
<span class="sr-only">Loading...</span>
</div>
</div>
{:then data}
<div>
<!-- time / cals / protions -->
<div id="info" class="mt-4 flex">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p><b>Время приготовления:</b> {data.data.recipe.ctime}</p>
<p>|</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.429 9.75L2.25 12l4.179 2.25m0-4.5l5.571 3 5.571-3m-11.142 0L2.25 7.5 12 2.25l9.75 5.25-4.179 2.25m0 0L21.75 12l-4.179 2.25m0 0l4.179 2.25L12 21.75 2.25 16.5l4.179-2.25m11.142 0l-5.571 3-5.571-3" />
</svg>
<p><b>Количество порций:</b> {data.data.recipe.snum}</p>
<p>|</p>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v17.25m0 0c-1.472 0-2.882.265-4.185.75M12 20.25c1.472 0 2.882.265 4.185.75M18.75 4.97A48.416 48.416 0 0012 4.5c-2.291 0-4.545.16-6.75.47m13.5 0c1.01.143 2.01.317 3 .52m-3-.52l2.62 10.726c.122.499-.106 1.028-.589 1.202a5.988 5.988 0 01-2.031.352 5.988 5.988 0 01-2.031-.352c-.483-.174-.711-.703-.59-1.202L18.75 4.971zm-16.5.52c.99-.203 1.99-.377 3-.52m0 0l2.62 10.726c.122.499-.106 1.028-.589 1.202a5.989 5.989 0 01-2.031.352 5.989 5.989 0 01-2.031-.352c-.483-.174-.711-.703-.59-1.202L5.25 4.971z" />
</svg>
<p><b>Калорийность:</b> {data.data.recipe.cal}</p>
</div>
<div id="tags" class="mt-8">
<!-- <h5><b>Tags:</b></h5> -->
{#each data.data.recipe.categories as category}
<a href="#" class="text-gray-50 text-center">{category}</a>
{/each}
</div>
<!-- title -->
<h1 class="pt-8 pb-5 text-3xl font-bold font-title">
{data.data.recipe.title}
</h1>
<div class="desc_container">
<!-- image -->
<div class="mainimg">
<img class="rounded-lg h-full w-auto" alt={data.data.recipe.title} src="{serverurl}/recipe_image?filename={data.data.recipe.img}" />
</div>
<!-- description -->
<div class="recipedesc">
{data.data.recipe.desc}
</div>
</div>
<div class="recipe_container">
<!-- ingredients -->
<div id="ingredients">
<!-- ing -->
{#each data.data.recipe.ingredients as ingredients}
<div>
<b><h5>{ingredients.Title}</h5></b>
<ul>
{#each ingredients.Ingredients as ingredient}
<li>{ingredient}</li>
{/each}
</ul>
</div>
{/each}
</div>
<!-- steps -->
<div id="steps">
<b><h5>Как приготовить {data.data.recipe.title.toLowerCase()}</h5></b>
<ol class="list-outside list-decimal list-image-none">
{#each data.data.recipe.recipe_steps as step}
<li class="relative">{step}</li>
{/each}
</ol>
</div>
</div>
<!-- advices -->
{#if data.data.recipe.advices !== undefined}
<div id="advices">
<b><h5>Советы</h5></b>
<ul>
{#each data.data.recipe.advices as advice}
<li>{advice}</li>
{/each}
</ul>
</div>
{/if}
</div>
{/await}
</div>
<style>
.font-title {
font-family: 'AlegreyaSansSC', sans-serif;
font-size: 2.4em;
}
@font-face {
font-family: 'AlegreyaSansSC';
font-style: normal;
font-weight: 800;
src: url('/fonts/Alegreyasansscextrabold.ttf');
}
@font-face {
font-family: 'RobotoRegular';
font-style: normal;
font-weight: 400;
src: url('/fonts/Roboto-Regular.ttf');
}
p, li {
font-family: 'RobotoRegular', sans-serif;
}
h5 {
font-family: 'AlegreyaSansSC', sans-serif;
font-size: 1.4em;
margin-bottom: 1vh;
}
.desc_container {
display: flex;
flex-direction: row;
align-items: center;
font-size: 1.3em;
/* gap: 14px; */
}
.mainimg {
flex: 1 1;
border: dashed blue 1px;
}
.mainimg img {
max-height: 100%;
max-width: 100%;
}
.recipedesc {
flex: 1;
box-sizing: border-box;
padding: 0px 20px 0px 20px;
}
#info svg {
margin-right: 10px;
}
#info p {
margin-right: 10px;
}
#tags {
align-items: flex-start;
}
#tags a {
min-width: 3em;
border-radius: 13px;
font-size: 0.9em;
padding: 3px 10px 4px 10px;
/* margin-bottom: 10px; */
display: inline-block;
margin-right: 6px;
background-color: #64aa34;
}
.recipe_container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
box-sizing: border-box;
gap: 5vw;
/* align-content: space-between; */
/* justify-content: space-between; */
padding-top: 5vh;
}
.recipe_container #ingredients {
flex: 1;
display: flex;
gap: 5vw;
/* align-content: center; */
/* align-items: flex-start; */
/* justify-content: center; */
}
.recipe_container #ingredients div {
flex: 1;
/* max-width: 50%; */
}
.recipe_container #steps {
flex: 1;
}
#steps ol {
padding: 0;
margin-left: 20px;
}
#steps li {
margin-bottom: 10px;
padding-left: 1vw;
/* padding-left: 4.5rem; */
}
#advices {
padding-top: 5vh;
}
</style>

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Binary file not shown.

BIN
static/fonts/Roboto.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
static/logo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
static/logo2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
static/logo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

14
svelte.config.js Normal file
View File

@ -0,0 +1,14 @@
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
},
preprocess: vitePreprocess()
};
export default config;

9
tailwind.config.js Normal file
View File

@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {},
},
plugins: [],
}

6
tests/test.js 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();
});

6
vite.config.js Normal file
View File

@ -0,0 +1,6 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [sveltekit()]
});