Compare commits
33 Commits
front
...
edd2eec9cd
| Author | SHA1 | Date | |
|---|---|---|---|
| edd2eec9cd | |||
| 27474d9607 | |||
| bea27be461 | |||
| 11879ffd39 | |||
| 001922c5e2 | |||
| beef191051 | |||
| 7ddee3f12d | |||
| 3ec7aa43e5 | |||
| 942a287b26 | |||
| eb97ed0e4a | |||
| 916d020909 | |||
| dd41046e75 | |||
| 6b6361b25a | |||
| 0932c40127 | |||
| d58bfbb7c1 | |||
| 66b6878e50 | |||
| 7bdf422c32 | |||
| 9a259cb637 | |||
| 54072eb87d | |||
| ecf374685f | |||
| 62d58e30cd | |||
| a13b88bd32 | |||
| ea7bfc64f2 | |||
| 0e2a17a3e3 | |||
| 185cefe250 | |||
| 25ec2c7bcb | |||
| b667cde3d7 | |||
| d30af82765 | |||
| efd8510853 | |||
| e558aa6bdd | |||
| bd9210a3b5 | |||
| 1eba5623a3 | |||
| c762662231 |
@@ -4,14 +4,32 @@ http://ru.homyk.space {
|
|||||||
https://ru.homyk.space {
|
https://ru.homyk.space {
|
||||||
encode gzip
|
encode gzip
|
||||||
|
|
||||||
# --- API ---
|
|
||||||
handle /api/* {
|
handle /api/* {
|
||||||
reverse_proxy backend:{$PORT}
|
reverse_proxy backend:{$PORT}
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Frontend ---
|
handle_path /main/* {
|
||||||
root * /srv
|
@images path_regexp \.(jpg|jpeg|png|webp|gif|svg)$
|
||||||
|
header @images Cache-Control "public, max-age=604800"
|
||||||
|
|
||||||
|
forward_auth backend:{$PORT} {
|
||||||
|
uri /api/verify
|
||||||
|
copy_headers Authorization
|
||||||
|
}
|
||||||
|
root * /srv/main
|
||||||
file_server
|
file_server
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_errors {
|
||||||
|
@unauth expression {http.error.status_code} == 401
|
||||||
|
redir @unauth / 302
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
root * /srv/auth
|
||||||
|
file_server {
|
||||||
|
index login.html
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log {
|
log {
|
||||||
output file /data/logs/caddy.log {
|
output file /data/logs/caddy.log {
|
||||||
@@ -20,7 +38,7 @@ https://ru.homyk.space {
|
|||||||
roll_keep_for 72h
|
roll_keep_for 72h
|
||||||
}
|
}
|
||||||
format json
|
format json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
https://music.homyk.space {
|
https://music.homyk.space {
|
||||||
encode gzip
|
encode gzip
|
||||||
@@ -37,5 +55,5 @@ https://music.homyk.space {
|
|||||||
roll_keep_for 72h
|
roll_keep_for 72h
|
||||||
}
|
}
|
||||||
format json
|
format json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
makefile
@@ -1,12 +1,15 @@
|
|||||||
VENV=source ./.venv/bin/activate;
|
#VENV=source ./.venv/bin/activate;
|
||||||
ALEMBIC=alembic -c ./server/backend/database/alembic/alembic.ini
|
#ALEMBIC=alembic -c ./server/backend/database/alembic/alembic.ini
|
||||||
|
VENV= .venv\Scripts\activate #Windows
|
||||||
|
ALEMBIC=alembic -c server\backend\database\alembic\alembic.ini
|
||||||
.PHONY: run run_debug migrate_head migrate_down migrate_history migrate_current migrate_heads migrate_stamp migrate
|
.PHONY: run run_debug migrate_head migrate_down migrate_history migrate_current migrate_heads migrate_stamp migrate
|
||||||
run:
|
run:
|
||||||
$(VENV) python run.py --user_name admin
|
$(VENV) python run.py --user_name admin
|
||||||
run_debug:
|
run_debug:
|
||||||
$(VENV) python run.py --mode debug --user_name admin
|
$(VENV) python run.py --mode debug --user_name admin
|
||||||
migrate_head:
|
migrate_head:
|
||||||
$(VENV) $(ALEMBIC) upgrade head
|
$(VENV) $(ALEMBIC)
|
||||||
|
|
||||||
migrate_down:
|
migrate_down:
|
||||||
$(VENV) $(ALEMBIC) downgrade -1
|
$(VENV) $(ALEMBIC) downgrade -1
|
||||||
migrate_history:
|
migrate_history:
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
from fastapi import FastAPI, Depends, HTTPException,status
|
from fastapi import FastAPI, Depends, HTTPException,status, Response, Cookie
|
||||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
import server.backend.schema.pydantic as pydantic
|
import server.backend.schema.pydantic as pydantic
|
||||||
import server.backend.database.db as db
|
import server.backend.database.db as db
|
||||||
from server.backend.auth.JWT import signJWT, decodeJWT
|
from server.backend.auth.JWT import signJWT, decodeJWT
|
||||||
api = FastAPI(openapi_url="/api/openapi.json",docs_url="/api/docs", redoc_url="/api/redoc")
|
api = FastAPI(openapi_url="/api/openapi.json",docs_url="/api/docs", redoc_url="/api/redoc")
|
||||||
security = HTTPBearer()
|
security = HTTPBearer(auto_error=False)
|
||||||
|
|
||||||
async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
async def get_current_user(
|
||||||
token = credentials.credentials
|
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||||
|
token_cookie: str = Cookie(default=None)
|
||||||
|
):
|
||||||
|
token = credentials.credentials if credentials else token_cookie
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(status_code=401, detail="Not authenticated")
|
||||||
user = decodeJWT(token)
|
user = decodeJWT(token)
|
||||||
if not user:
|
if not user:
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
|
raise HTTPException(status_code=401, detail="Invalid token")
|
||||||
return user
|
return user
|
||||||
async def check_roles(user=Depends(get_current_user)):
|
async def check_roles(user=Depends(get_current_user)):
|
||||||
user_check = await db.list_user(user["user_id"])
|
user_check = await db.list_user(user["user_id"])
|
||||||
@@ -58,10 +63,29 @@ async def list_users(user=Depends(check_roles)):
|
|||||||
list_of_users = await db.list_users()
|
list_of_users = await db.list_users()
|
||||||
return list_of_users
|
return list_of_users
|
||||||
|
|
||||||
@api.post("/api/auth",response_model=pydantic.Token)
|
@api.post("/api/auth")
|
||||||
async def auth(code:pydantic.UserAccess):
|
async def auth(code: pydantic.UserAccess, response: Response):
|
||||||
login = await db.login_user(code)
|
login = await db.login_user(code)
|
||||||
if login == None:
|
if login is None:
|
||||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Forbidden")
|
raise HTTPException(status_code=401, detail="Forbidden")
|
||||||
token = signJWT(login)
|
token = signJWT(login)
|
||||||
|
response.set_cookie(
|
||||||
|
key="token",
|
||||||
|
value=token,
|
||||||
|
httponly=True,
|
||||||
|
secure=True,
|
||||||
|
samesite="strict"
|
||||||
|
)
|
||||||
return {"access_token": token, "token_type": "bearer"}
|
return {"access_token": token, "token_type": "bearer"}
|
||||||
|
@api.get("/api/verify")
|
||||||
|
async def verify(token: str = Cookie(default=None)):
|
||||||
|
if not token:
|
||||||
|
raise HTTPException(status_code=401, detail="No token")
|
||||||
|
user = decodeJWT(token)
|
||||||
|
if not user:
|
||||||
|
raise HTTPException(status_code=401, detail="Invalid token")
|
||||||
|
return {"status": "ok"}
|
||||||
|
@api.post("/api/logout")
|
||||||
|
async def logout(response: Response):
|
||||||
|
response.delete_cookie(key="token")
|
||||||
|
return {"status": "ok"}
|
||||||
1
server/frontend/auth/fonts/MurreyC/COPYRIGHT.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DoubleRus encoding by Diai; unfinished
|
||||||
BIN
server/frontend/auth/fonts/MurreyC/murreyc.eot
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.ttf
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.woff
Normal file
BIN
server/frontend/auth/fonts/MurreyC/murreyc.woff2
Normal file
BIN
server/frontend/auth/image/bg.webp
Normal file
|
After Width: | Height: | Size: 357 KiB |
BIN
server/frontend/auth/image/hamster.webp
Normal file
|
After Width: | Height: | Size: 264 KiB |
@@ -0,0 +1,126 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "MurreyC";
|
||||||
|
src: url("fonts/MurreyC/murreyc.woff2") format("woff2");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "MurreyC";
|
||||||
|
src: url("fonts/MurreyC/murreyc.woff") format("woff");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "MurreyC";
|
||||||
|
src: url("fonts/MurreyC/murreyc.eot") format("eot");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, html {
|
||||||
|
font-family: "MurreyC";
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.bg {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
|
||||||
|
background: url("image/bg.webp") center center / cover no-repeat;
|
||||||
|
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.glass-container {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
background: rgba(20,20,20,.35);
|
||||||
|
}
|
||||||
|
.login-box {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background: url('./image/hamster.webp') no-repeat 50% 50%;
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 50px;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 320px;
|
||||||
|
height: 50px;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid #000;
|
||||||
|
background-color: #ffffff;
|
||||||
|
outline: none;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 30px;
|
||||||
|
background-color: #3a1f09;
|
||||||
|
padding: 10px 15px;
|
||||||
|
border-radius: 33px;
|
||||||
|
transition:
|
||||||
|
transform .1s ease,
|
||||||
|
background-color .1s ease,
|
||||||
|
color .1s ease;
|
||||||
|
color: #e5b97e;
|
||||||
|
box-shadow: 0 4px 12px rgba(58,31,9,.3);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #f0c590;
|
||||||
|
color: #b06029;
|
||||||
|
transform: scale(1.015);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------ADAPTIVE------------------------------------- */
|
||||||
|
|
||||||
|
@media (max-width: 820px) {
|
||||||
|
.login-box {
|
||||||
|
background-size: 190%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 620px) {
|
||||||
|
.login-box {
|
||||||
|
background-size: 220%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 520px) {
|
||||||
|
.login-box {
|
||||||
|
background-size: 260%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 420px) {
|
||||||
|
.login-box {
|
||||||
|
background-size: 310%;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 320px) {
|
||||||
|
.login-box {
|
||||||
|
background-size: 420%;
|
||||||
|
background: url('./image/hamster.png') no-repeat 55% 50%;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,17 +5,25 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Login</title>
|
<title>Login</title>
|
||||||
<link rel="stylesheet" href="login.css">
|
<link rel="stylesheet" href="login.css">
|
||||||
|
<link
|
||||||
|
rel="preload"
|
||||||
|
href="fonts/MurreyC/murreyc.woff2"
|
||||||
|
as="font"
|
||||||
|
type="font/woff2"
|
||||||
|
crossorigin
|
||||||
|
>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="bg"></div>
|
||||||
<div class="glass-container">
|
<div class="glass-container">
|
||||||
<div class="login-box">
|
<div class="login-box">
|
||||||
<h2>Login</h2>
|
<h2>Введите код</h2>
|
||||||
<form id="loginForm">
|
<form id="loginForm">
|
||||||
<input type="password" id="password" name="password" required placeholder="Code">
|
<input type="password" id="password" name="password" required placeholder="Код">
|
||||||
<button type="submit">Login</button>
|
<button type="submit">Войти</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="login.js"></script>
|
<script src="login.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,39 +1,29 @@
|
|||||||
function getToken() {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
return localStorage.getItem("token") || sessionStorage.getItem("token");
|
fetch('/api/verify', { credentials: 'include' })
|
||||||
}
|
.then(r => { if (r.ok) window.location.href = '/main/'; })
|
||||||
function tokenCheck(){
|
.catch(() => {});
|
||||||
const token = getToken();
|
|
||||||
if (token) {
|
document.getElementById('loginForm').addEventListener('submit', async function(e) {
|
||||||
window.location.href = "http://localhost:5500/server/frontend/main/index.html";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
document.getElementById('loginForm').addEventListener('submit', async function (e) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const password = document.getElementById('password').value;
|
|
||||||
const userData = {
|
const code = document.getElementById('password').value;
|
||||||
password
|
|
||||||
};
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch("http://localhost:8000/api/auth", {
|
const response = await fetch('/api/auth', {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
credentials: 'include', // ← чтобы браузер принял cookie
|
||||||
},
|
body: JSON.stringify({ code })
|
||||||
body: new URLSearchParams({
|
|
||||||
password: userData.password
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const data = await response.json(); // читаем только один раз
|
const data = await response.json();
|
||||||
if (response.ok) { // сохраняем только при успехе
|
|
||||||
// в sessionstorage до перезахода в браузер(
|
|
||||||
sessionStorage.setItem("token", data.access_token);
|
|
||||||
|
|
||||||
window.location.href = 'http://localhost:5500/server/frontend/main/index.html';
|
if (response.ok) {
|
||||||
} else { //парсинг и вывод ошибок, если есть
|
window.location.href = '/main/';
|
||||||
|
} else {
|
||||||
if (Array.isArray(data.detail)) {
|
if (Array.isArray(data.detail)) {
|
||||||
const messages = data.detail.map(e => {
|
const messages = data.detail.map(e => {
|
||||||
const field = e.loc.filter(locPart => locPart !== 'body').join(' -> ');
|
const field = e.loc.filter(p => p !== 'body').join(' -> ');
|
||||||
return `${field}: ${e.msg}`;
|
return `${field}: ${e.msg}`;
|
||||||
});
|
});
|
||||||
showError(messages);
|
showError(messages);
|
||||||
@@ -46,28 +36,29 @@ document.getElementById('loginForm').addEventListener('submit', async function (
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
showError(['Connection error: ' + err.message]);
|
showError(['Connection error: ' + err.message]);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
function showError(messages){ //Добавление их на form со стилями
|
|
||||||
|
function showError(messages) {
|
||||||
let errorElem = document.getElementById('formError');
|
let errorElem = document.getElementById('formError');
|
||||||
let container = document.getElementById('glass-container');
|
if (!errorElem) {
|
||||||
if (!errorElem){
|
|
||||||
errorElem = document.createElement('div');
|
errorElem = document.createElement('div');
|
||||||
errorElem.style.transition="3s";
|
|
||||||
errorElem.id = 'formError';
|
errorElem.id = 'formError';
|
||||||
errorElem.style.color = 'red';
|
errorElem.style.cssText = `
|
||||||
errorElem.style.marginTop = '20px';
|
color: red;
|
||||||
errorElem.style.fontSize = '14px';
|
margin-top: 20px;
|
||||||
errorElem.style.fontWeight = '100';
|
margin-bottom: 20px;
|
||||||
errorElem.style.marginBottom = '20px';
|
font-size: 14px;
|
||||||
errorElem.style.lineHeight="120%";
|
font-weight: 100;
|
||||||
errorElem.style.height = 'auto';
|
line-height: 120%;
|
||||||
const form = document.getElementById('loginForm');
|
transition: 3s;
|
||||||
form.insertAdjacentElement('afterend', errorElem);
|
`;
|
||||||
};
|
document.getElementById('loginForm').insertAdjacentElement('afterend', errorElem);
|
||||||
|
}
|
||||||
errorElem.innerHTML = '';
|
errorElem.innerHTML = '';
|
||||||
messages.forEach(msg => {
|
messages.forEach(msg => {
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.style.listStyleType="none";
|
li.style.listStyleType = 'none';
|
||||||
li.textContent = msg;
|
li.textContent = msg;
|
||||||
errorElem.appendChild(li);
|
errorElem.appendChild(li);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,69 +1,55 @@
|
|||||||
function getToken() {
|
|
||||||
return localStorage.getItem("token") || sessionStorage.getItem("token");
|
|
||||||
}
|
|
||||||
function tokenCheck(){
|
|
||||||
const token = getToken();
|
|
||||||
if (!token) {
|
|
||||||
window.location.href = "http://localhost:5500/server/frontend/auth/login.html";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenCheck()
|
|
||||||
document.getElementById('logoutForm').addEventListener('submit', async function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
localStorage.removeItem("token");
|
|
||||||
sessionStorage.removeItem("token");
|
|
||||||
tokenCheck();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
const form = document.querySelector(".form-info");
|
|
||||||
|
|
||||||
form.addEventListener("submit", async (e) => {
|
// Проверка авторизации через cookie
|
||||||
|
fetch('/api/verify', { credentials: 'include' })
|
||||||
|
.then(r => { if (!r.ok) window.location.href = '/'; })
|
||||||
|
.catch(() => { window.location.href = '/'; });
|
||||||
|
|
||||||
|
// Logout — удаляем cookie на бэкенде
|
||||||
|
document.getElementById('logoutForm').addEventListener('click', async function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
await fetch('/api/logout', {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include'
|
||||||
|
});
|
||||||
|
window.location.href = '/';
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelector(".form-info").addEventListener("submit", async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// try {
|
|
||||||
// собираем данные из формы
|
|
||||||
const name = document.getElementById('ffname').value || "";
|
|
||||||
const middlename = document.getElementById('fmname').value || "";
|
|
||||||
const surname = document.getElementById('flname').value || "";
|
|
||||||
const text_field = document.getElementById('text_field')?.value || "";
|
|
||||||
const food = document.querySelector('input[name="food"]:checked')?.value || "";
|
|
||||||
const types_of_alco = Array.from(document.querySelectorAll('input[name="drink"]:checked'))
|
|
||||||
.map(el => el.value)
|
|
||||||
.join(', ');
|
|
||||||
|
|
||||||
const guestData = {
|
const guestData = {
|
||||||
name: name,
|
name: document.getElementById('ffname').value || "",
|
||||||
middlename: middlename,
|
middlename: document.getElementById('fmname').value || "",
|
||||||
surname: surname,
|
surname: document.getElementById('flname').value || "",
|
||||||
text_field: text_field,
|
text_field: document.getElementById('text_field')?.value || "",
|
||||||
activated: true,
|
activated: true,
|
||||||
types_of_food: food,
|
types_of_food: document.querySelector('input[name="food"]:checked')?.value || "",
|
||||||
types_of_alco: types_of_alco
|
types_of_alco: Array.from(document.querySelectorAll('input[name="drink"]:checked'))
|
||||||
|
.map(el => el.value)
|
||||||
|
.join(', ')
|
||||||
};
|
};
|
||||||
console.log(guestData)
|
|
||||||
|
|
||||||
// отправка на /api/update с Authorization
|
try {
|
||||||
// const updateResponse = await fetch('/api/update', {
|
const response = await fetch('/api/update', {
|
||||||
// method: 'POST',
|
method: 'POST',
|
||||||
// headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
// 'Content-Type': 'application/json',
|
credentials: 'include', // ← токен идёт через cookie
|
||||||
// 'Authorization': `Bearer ${token}`
|
body: JSON.stringify(guestData)
|
||||||
// },
|
});
|
||||||
// body: JSON.stringify(guestData)
|
|
||||||
// });
|
|
||||||
|
|
||||||
// if (!updateResponse.ok) {
|
if (!response.ok) {
|
||||||
// throw new Error('Ошибка при отправке формы');
|
const err = await response.json();
|
||||||
// }
|
throw new Error(JSON.stringify(err.detail || 'Ошибка при отправке'));
|
||||||
|
}
|
||||||
|
|
||||||
// const updateData = await updateResponse.json();
|
const data = await response.json();
|
||||||
// console.log('Форма успешно отправлена:', updateData);
|
console.log('Успешно:', data);
|
||||||
|
alert('Данные сохранены!');
|
||||||
|
|
||||||
// } catch (err) {
|
} catch (err) {
|
||||||
// console.error(err);
|
console.error(err);
|
||||||
// alert('Ошибка: ' + err.message);
|
alert('Ошибка: ' + err.message);
|
||||||
// }
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.2 MiB |
BIN
server/frontend/main/images/25.webp
Normal file
|
After Width: | Height: | Size: 323 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 288 KiB |
|
Before Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 612 KiB |
|
Before Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 221 KiB |
|
Before Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 16 KiB |
3
server/frontend/main/images/icon.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<?xml version="1.0" ?><svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css">
|
||||||
|
.st0{display:none;}
|
||||||
|
</style><g class="st0" id="grid"/><g id="icon"><path d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z"/><path d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z"/><path d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
server/frontend/main/images/maps/loft.webp
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
server/frontend/main/images/maps/zags.webp
Normal file
|
After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 362 KiB |
|
Before Width: | Height: | Size: 197 KiB |
BIN
server/frontend/main/images/people/bride.webp
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
server/frontend/main/images/people/groom.webp
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
server/frontend/main/images/photos/1.webp
Normal file
|
After Width: | Height: | Size: 689 KiB |
BIN
server/frontend/main/images/photos/10.webp
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
server/frontend/main/images/photos/2.webp
Normal file
|
After Width: | Height: | Size: 170 KiB |
BIN
server/frontend/main/images/photos/3.webp
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
server/frontend/main/images/photos/4.webp
Normal file
|
After Width: | Height: | Size: 235 KiB |
BIN
server/frontend/main/images/photos/5.webp
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
server/frontend/main/images/photos/6.webp
Normal file
|
After Width: | Height: | Size: 239 KiB |
BIN
server/frontend/main/images/photos/7.webp
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
server/frontend/main/images/photos/8.webp
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
server/frontend/main/images/photos/9.webp
Normal file
|
After Width: | Height: | Size: 234 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 525 KiB |
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
|
||||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#37BBFE"/>
|
|
||||||
<stop offset="1" stop-color="#007DBB"/>
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 920 B |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/camera.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 31 KiB |
BIN
server/frontend/main/images/time/disco-ball_18181959.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
server/frontend/main/images/time/food.webp
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
server/frontend/main/images/time/guest1.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/ring.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
server/frontend/main/images/time/wedding-dinner_11196102.webp
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 74 KiB |
@@ -7,20 +7,26 @@
|
|||||||
<title>Wedding invitation</title>
|
<title>Wedding invitation</title>
|
||||||
<link rel="stylesheet" href="reset.css">
|
<link rel="stylesheet" href="reset.css">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css" />
|
||||||
rel="stylesheet"
|
<link rel="preload" href="fonts/yourfont.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
href="https://cdn.jsdelivr.net/npm/swiper@12/swiper-bundle.min.css"
|
|
||||||
/>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div class="bg"></div>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<nav class="nav">
|
|
||||||
|
<div class="burger" id="burger">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="nav" id="nav">
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
|
<div class="items_up">
|
||||||
<!-- 1 -->
|
<!-- 1 -->
|
||||||
<li class="item">
|
<li class="item">
|
||||||
<a href="#heading" class="link">
|
<a href="#" class="link">
|
||||||
Добро пожаловать!
|
Добро пожаловать!
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -42,8 +48,10 @@
|
|||||||
Путешествие
|
Путешествие
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
</div>
|
||||||
|
<div class="items_down">
|
||||||
<!-- 5 -->
|
<!-- 5 -->
|
||||||
<li class="item">
|
<li class="item item_none">
|
||||||
<a href="#photos" class="link">
|
<a href="#photos" class="link">
|
||||||
Фотографии
|
Фотографии
|
||||||
</a>
|
</a>
|
||||||
@@ -60,6 +68,7 @@
|
|||||||
Прошу ответить
|
Прошу ответить
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
@@ -74,21 +83,25 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<h3 class="heading_date">22 августа 2026</h3>
|
<h3 class="heading_date">22 августа 2026</h3>
|
||||||
<p class="heading_text">
|
<p class="heading_text">
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iste possimus ipsa, labore repudiandae
|
Мы — та самая история, которая началась со странного сообщения и превратилась в нечто настоящее.
|
||||||
ratione placeat dolore vitae praesentium perspiciatis ipsam non illum reiciendis accusamus quae
|
В нас есть легкость и смех, который когда-то стал началом всего, любовь к простым вещам вроде
|
||||||
quo veritatis maiores quod sequi. Ipsam at consequatur quia recusandae, rem dicta autem quaerat
|
чашки чая и бесконечных разговоров обо всем на свете. Мы разные и неидеальные, но именно в этом
|
||||||
placeat?
|
— наше совпадение: нам всегда интересно друг с другом, спокойно и по-настоящему. Мы умеем
|
||||||
|
смеяться до слез, поддерживать в нужный момент и находить радость в мелочах. И, пожалуй, самое
|
||||||
|
важное — мы с самого начала почувствовали, что это надолго, и с каждым днем только убеждаемся в
|
||||||
|
этом.
|
||||||
</p>
|
</p>
|
||||||
<button class="btn_share" button>
|
<button class="btn_share" button>
|
||||||
|
<a class="btn_link" href="#answer">
|
||||||
Подтвердить участие
|
Подтвердить участие
|
||||||
|
</a>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</section>
|
||||||
<aside>
|
<aside>
|
||||||
<div class="time">
|
<div class="time">
|
||||||
<!-- отсчет до даты -->
|
<p id="demo"></p>
|
||||||
00:00:00
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
<section class="people" id="people">
|
<section class="people" id="people">
|
||||||
@@ -97,30 +110,33 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<div class="newlywed">
|
<div class="newlywed">
|
||||||
<div class="newlywed_item">
|
<div class="newlywed_item">
|
||||||
<img class="img_newlywed" src="images/people//IMG_20260107_140110_500.jpg" alt="groom">
|
<img class="img_newlywed" src="images/people/groom.webp" alt="groom" loading="lazy"
|
||||||
|
decoding="async">
|
||||||
<div class="newlywed_text">
|
<div class="newlywed_text">
|
||||||
<h3 class="newlywed_title">Жених</h3>
|
<h3 class="newlywed_title">Жених</h3>
|
||||||
<p class="newlywed_info">Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui voluptatum
|
<p class="newlywed_info">
|
||||||
odio autem, ut dolorum suscipit soluta reiciendis quam reprehenderit saepe doloribus
|
Самый лучший, милый,классный, очаровательный, крутой, забавный, любящий, удивительный,
|
||||||
asperiores
|
необычный, прелестный, веселый, смешной, умный, добрый,красивый, гениальный</p>
|
||||||
architecto? Debitis magnam, exercitationem nam temporibus eos molestias?</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="newlywed_item">
|
<div class="newlywed_item">
|
||||||
<img class="img_newlywed" src="images/people/IMG_20260107_140120_301.jpg" alt="bride">
|
<img class="img_newlywed" src="images/people/bride.webp" alt="bride" loading="lazy"
|
||||||
|
decoding="async">
|
||||||
<div class="newlywed_text">
|
<div class="newlywed_text">
|
||||||
<h3 class="newlywed_title">Невеста</h3>
|
<h3 class="newlywed_title">Невеста</h3>
|
||||||
<p class="newlywed_info">Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui voluptatum
|
<p class="newlywed_info">Я — творческий и активный человек, люблю петь, путешествовать и
|
||||||
odio autem, ut dolorum suscipit soluta reiciendis quam reprehenderit saepe doloribus
|
создавать что-то своими руками. Увлекаюсь готовкой, особенно десертами, которыми радую
|
||||||
asperiores
|
близких. Люблю веселье, тусовки, животных и жизнь без
|
||||||
architecto? Debitis magnam, exercitationem nam temporibus eos molestias?</p>
|
скуки.
|
||||||
|
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="guest_list">
|
<!-- <div class="guest_list">
|
||||||
<div class="guest_inner">
|
<div class="guest_inner">
|
||||||
<!-- 1 -->
|
<!-- 1 -->
|
||||||
<div class="guest_item">
|
<!-- <div class="guest_item">
|
||||||
<div class="guest_index">
|
<div class="guest_index">
|
||||||
Стол 1
|
Стол 1
|
||||||
</div>
|
</div>
|
||||||
@@ -147,9 +163,9 @@
|
|||||||
Lorem, ipsum.
|
Lorem, ipsum.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
<!-- 2 -->
|
<!-- 2 -->
|
||||||
<div class="guest_item">
|
<!-- <div class="guest_item">
|
||||||
<div class="guest_index">
|
<div class="guest_index">
|
||||||
Стол 1
|
Стол 1
|
||||||
</div>
|
</div>
|
||||||
@@ -176,9 +192,9 @@
|
|||||||
Lorem, ipsum.
|
Lorem, ipsum.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
<!-- 3 -->
|
<!-- 3 -->
|
||||||
<div class="guest_item">
|
<!-- <div class="guest_item">
|
||||||
<div class="guest_index">
|
<div class="guest_index">
|
||||||
Стол 1
|
Стол 1
|
||||||
</div>
|
</div>
|
||||||
@@ -205,7 +221,7 @@
|
|||||||
Lorem, ipsum.
|
Lorem, ipsum.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -220,70 +236,67 @@
|
|||||||
<!-- 1 -->
|
<!-- 1 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/ring.png" alt="ring" class="time_img">
|
<img src="images/time/guest1.webp" alt="ring" class="time_img" loading="lazy"
|
||||||
<h6 class="time_h6">10:40</h6>
|
decoding="async">
|
||||||
<p class="time_p">Церемония</p>
|
<h6 class="time_h6">10:10</h6>
|
||||||
<div class="time_comment">Начало нашего свадебного дня и самый важный момент для нас
|
<p class="time_p">Сбор гостей</p>
|
||||||
|
<div class="time_comment">Приходите заранее, чтобы спокойно встретиться и сделать
|
||||||
|
фото
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 2 -->
|
<!-- 2 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/camera.png" alt="camera" class="time_img">
|
<img src="images/time/ring.webp" alt="ring" class="time_img" loading="lazy"
|
||||||
<h6 class="time_h6">11:30</h6>
|
decoding="async">
|
||||||
<p class="time_p">Фотосессия</p>
|
<h6 class="time_h6">10:40</h6>
|
||||||
<div class="time_comment">После церемонии мы ненадолго отправимся на фотосессию,
|
<p class="time_p">Церемония</p>
|
||||||
чтобы сохранить этот день в памяти</div>
|
<div class="time_comment">Самый трогательный и важный момент дня — регистрация
|
||||||
|
нашего брака
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 3 -->
|
<!-- 3 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/wedding-dinner_11196102.png" alt="" class="time_img">
|
<img src="images/time/camera.webp" alt="camera" class="time_img" loading="lazy"
|
||||||
<h6 class="time_h6">14:00</h6>
|
decoding="async">
|
||||||
<p class="time_p">Фуршет и бармен</p>
|
<h6 class="time_h6">11:30</h6>
|
||||||
<div class="time_comment">Берем напиток, закуски и наслаждаемся началом вечера</div>
|
<p class="time_p">Фотосессия</p>
|
||||||
|
<div class="time_comment">Мы отправляемся на фотосессию, а для гостей наступит свободное время до банкета</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="time_row_down">
|
||||||
<!-- 4 -->
|
<!-- 4 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/free-icon-fireworks-7201451.png" alt="" class="time_img">
|
<img src="images/time/wedding-dinner_11196102.webp" alt="" class="time_img"
|
||||||
<h6 class="time_h6">14:30</h6>
|
loading="lazy" decoding="async">
|
||||||
<p class="time_p">Поздравления и подарки</p>
|
<h6 class="time_h6">18:30</h6>
|
||||||
<div class="time_comment">Мы будем рады теплым словам и подаркам во время фуршета
|
<p class="time_p">Сбор гостей и фуршет</p>
|
||||||
|
<div class="time_comment">Берем напиток, закуски и наслаждаемся началом вечера</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="time_line"></div>
|
|
||||||
<div class="time_row_down">
|
|
||||||
<!-- 5 -->
|
<!-- 5 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/food.png" alt="" class="time_img">
|
<img src="images/time/food.webp" alt="" class="time_img" loading="lazy"
|
||||||
<h6 class="time_h6">17:00</h6>
|
decoding="async">
|
||||||
|
<h6 class="time_h6">19:00</h6>
|
||||||
<p class="time_p">Банкет</p>
|
<p class="time_p">Банкет</p>
|
||||||
<div class="time_comment">Приглашаем вас за столы, чтобы продолжить вечер в тёплой и
|
<div class="time_comment">Приглашаем вас за столы, чтобы продолжить вечер в тёплой и
|
||||||
уютной атмосфере. Приветственный тост</div>
|
уютной атмосфере
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 6 -->
|
<!-- 6 -->
|
||||||
<div class="row_up_item">
|
<div class="row_up_item">
|
||||||
<div class="time_img_box">
|
<div class="time_img_box">
|
||||||
<img src="images/time/cake.png" alt="" class="time_img">
|
<img src="images/time/disco-ball_18181959.webp" alt="" class="time_img"
|
||||||
<h6 class="time_h6">19:00</h6>
|
loading="lazy" decoding="async">
|
||||||
<p class="time_p">Свадебный торт</p>
|
<h6 class="time_h6">22:00</h6>
|
||||||
<div class="time_comment">Самый сладкий момент вечера. Чай или кофе находятся в
|
|
||||||
велком зоне</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 7 -->
|
|
||||||
<div class="row_up_item">
|
|
||||||
<div class="time_img_box">
|
|
||||||
<img src="images/time/disco-ball_18181959.png" alt="" class="time_img">
|
|
||||||
<h6 class="time_h6">19:30</h6>
|
|
||||||
<p class="time_p">Танцы</p>
|
<p class="time_p">Танцы</p>
|
||||||
<div class="time_comment">Приглашаем вас на танцпол. Танцуйте столько, сколько
|
<div class="time_comment">Приглашаем вас на танцпол. Танцуйте столько, сколько
|
||||||
захочется</div>
|
захочется</div>
|
||||||
@@ -293,6 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="transfer" id="transfer">
|
<section class="transfer" id="transfer">
|
||||||
<h4 class="transfer_title">
|
<h4 class="transfer_title">
|
||||||
@@ -301,25 +315,34 @@
|
|||||||
<div class="transfer_inner">
|
<div class="transfer_inner">
|
||||||
<div class="transfer_map">
|
<div class="transfer_map">
|
||||||
<div class="map">
|
<div class="map">
|
||||||
<div style="position:relative;overflow:hidden; border-radius: 33px;">
|
<div class="map_div">
|
||||||
<a href="https://www.google.com/maps/place/Glavnoye+Upravleniye+Zapisi+Aktov+Grazhdanskogo+Sostoyaniya+Tverskoy+Oblasti/@56.8571039,35.901453,17z/data=!3m1!4b1!4m6!3m5!1s0x46b687a4d4edacad:0x15df9a38c874eb5d!8m2!3d56.857101!4d35.9040279!16s%2Fg%2F11ls6j2lvj?entry=ttu&g_ep=EgoyMDI2MDMxMS4wIKXMDSoASAFQAw%3D%3D"
|
<a href="https://maps.app.goo.gl/ZYTyA2qTvCpnXTdN7" target="_blank" class="map_link">
|
||||||
style="color:#eee;font-size:12px;position:absolute;top:0px;">
|
<img src="images/maps/zags.webp" alt="ЗАГС" class="map_preview" loading="lazy">
|
||||||
Главное управление записи актов гражданского состояния</a>
|
|
||||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2181.349338718406!2d35.901452977352925!3d56.85710390639812!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x46b687a4d4edacad%3A0x15df9a38c874eb5d!2sGlavnoye%20Upravleniye%20Zapisi%20Aktov%20Grazhdanskogo%20Sostoyaniya%20Tverskoy%20Oblasti!5e0!3m2!1sen!2s!4v1773428540512!5m2!1sen!2s" width="760" height="500" style="border:1px;" allowfullscreen="true" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
<div class="map_btn">
|
||||||
|
Открыть маршрут
|
||||||
</div>
|
</div>
|
||||||
<p class="map_adress">Тверь, Свободный переулок, 5</p>
|
</a>
|
||||||
|
</div>
|
||||||
|
<a href="https://maps.app.goo.gl/ZYTyA2qTvCpnXTdN7" class="map_adress" target="_blank">Тверь,
|
||||||
|
Свободный переулок, 5</a>
|
||||||
<h6 class="map_info">Начало в</h6>
|
<h6 class="map_info">Начало в</h6>
|
||||||
<h6 class="map_time">10:30</h6>
|
<h6 class="map_time">10:10</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="map">
|
<div class="map">
|
||||||
<div style="position:relative;overflow:hidden; border-radius: 33px;">
|
<div class="map_div">
|
||||||
<a href="https://www.google.com/maps/place/Loft+1870+%7C+%D0%9F%D0%BB%D0%BE%D1%89%D0%B0%D0%B4%D0%BA%D0%B0+%D0%B4%D0%BB%D1%8F+%D0%BC%D0%B5%D1%80%D0%BE%D0%BF%D1%80%D0%B8%D1%8F%D1%82%D0%B8%D0%B9+%D0%A2%D0%B2%D0%B5%D1%80%D1%8C+%7C+%D0%BA%D0%B5%D0%B9%D1%82%D0%B5%D1%80%D0%B8%D0%BD%D0%B3+%D0%BD%D0%B0+%D1%81%D0%B2%D0%B0%D0%B4%D1%8C%D0%B1%D1%83,+%D0%B1%D0%B0%D0%BD%D0%BA%D0%B5%D1%82%D0%BD%D1%8B%D0%B9+%D0%B7%D0%B0%D0%BB/@56.850656,35.8603082,17.32z/data=!3m1!5s0x46b687a53bac0dcf:0x5c270d07d710d5a!4m6!3m5!1s0x46b68764eb0c1387:0x7cb135f5414bc1e0!8m2!3d56.8508612!4d35.8650531!16s%2Fg%2F11p0wc5v7q?entry=ttu&g_ep=EgoyMDI2MDMxMS4wIKXMDSoASAFQAw%3D%3D"
|
<a href="https://maps.app.goo.gl/5WFQzNhDqmo2dBxXA" target="_blank" class="map_link">
|
||||||
style="color:#eee;font-size:12px;position:absolute;top:0px;">Лофт 1870</a>
|
<img src="images/maps/loft.webp" alt="ЗАГС" class="map_preview" loading="lazy">
|
||||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d1749.675516895515!2d35.86030818806184!3d56.850656040536194!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x46b68764eb0c1387%3A0x7cb135f5414bc1e0!2zTG9mdCAxODcwIHwg0J_Qu9C-0YnQsNC00LrQsCDQtNC70Y8g0LzQtdGA0L7Qv9GA0LjRj9GC0LjQuSDQotCy0LXRgNGMIHwg0LrQtdC50YLQtdGA0LjQvdCzINC90LAg0YHQstCw0LTRjNCx0YMsINCx0LDQvdC60LXRgtC90YvQuSDQt9Cw0Ls!5e0!3m2!1sen!2s!4v1773428705434!5m2!1sen!2s" width="760" height="500" style="border:1px;" allowfullscreen="true" loading="lazy" referrerpolicy="no-referrer-when-downgrade"></iframe>
|
|
||||||
|
<div class="map_btn">
|
||||||
|
Открыть маршрут
|
||||||
</div>
|
</div>
|
||||||
<p class="map_adress">Тверь, улица Двор Пролетарки, 16</p>
|
</a>
|
||||||
|
</div>
|
||||||
|
<a href="https://maps.app.goo.gl/5WFQzNhDqmo2dBxXA" class="map_adress" target="_blank">Тверь,
|
||||||
|
улица Двор Пролетарки, 16</a>
|
||||||
<h6 class="map_info">Начало в</h6>
|
<h6 class="map_info">Начало в</h6>
|
||||||
<h6 class="map_time">14:00</h6>
|
<h6 class="map_time">18:30</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -329,42 +352,49 @@
|
|||||||
Фотографии
|
Фотографии
|
||||||
</h4>
|
</h4>
|
||||||
<!-- Slider main container -->
|
<!-- Slider main container -->
|
||||||
<div class="swiper">
|
<div class="swiper">
|
||||||
<!-- Additional required wrapper -->
|
<!-- Additional required wrapper -->
|
||||||
<div class="swiper-wrapper">
|
<div class="swiper-wrapper">
|
||||||
<!-- Slides -->
|
<!-- Slides -->
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/1.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos//IMG_20260223_151049_713.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/2.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/3.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151049_713.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/4.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/5.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151049_713.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/6.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/7.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/8.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/9.webp" alt="photo" width="500" height="500"
|
||||||
|
loading="lazy" decoding="async">
|
||||||
</div>
|
</div>
|
||||||
<div class="swiper-slide">
|
<div class="swiper-slide">
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
<img class="swiper_img" src="images/photos/10.webp" alt="photo" width="500" height="500"
|
||||||
</div>
|
loading="lazy" decoding="async">
|
||||||
<div class="swiper-slide">
|
|
||||||
<img class="swiper_img" src="images/photos/IMG_20260223_151005_128.jpg" alt="photo">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- If we need pagination -->
|
<!-- If we need pagination -->
|
||||||
@@ -376,7 +406,7 @@
|
|||||||
|
|
||||||
<!-- If we need scrollbar -->
|
<!-- If we need scrollbar -->
|
||||||
<div class="swiper-scrollbar"></div>
|
<div class="swiper-scrollbar"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="to-do-list" id="to-do-list">
|
<section class="to-do-list" id="to-do-list">
|
||||||
<h4 class="do-list_title">
|
<h4 class="do-list_title">
|
||||||
@@ -385,31 +415,150 @@
|
|||||||
<div class="to-do-list_wrapper">
|
<div class="to-do-list_wrapper">
|
||||||
<div class="to-do-list_items">
|
<div class="to-do-list_items">
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Поздравить молодых и сказать тёплые слова
|
Поздравить молодых и сказать тёплые слова
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Вручить подарок молодожёнам
|
Вручить подарок молодожёнам
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Сделать фото и видео, чтобы потом было что выложить
|
Сделать фото и видео, чтобы потом было что выложить
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Поднять тост за любовь
|
Поднять тост за любовь
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Добраться до свадебного торта, сфотографировать его
|
Добраться до свадебного торта, сфотографировать его
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Потанцевать хотя бы один медленный танец
|
Потанцевать хотя бы один медленный танец
|
||||||
</div>
|
</div>
|
||||||
<div class="to-do-list_item">
|
<div class="to-do-list_item">
|
||||||
<img class="to-do-list_item_img" src="images/icon.png" alt="icon">
|
<svg style="enable-background:new 0 0 24 24;" version="1.1" viewBox="0 0 24 24"
|
||||||
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<g class="st0" id="grid" />
|
||||||
|
<g id="icon">
|
||||||
|
<path
|
||||||
|
d="M5.528,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199L23.899,5.275c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.166-0.535-0.124-0.7,0.099 L12.91,18.226l-6.677-7.839C6.053,10.176,5.736,10.151,5.528,10.33z" />
|
||||||
|
<path
|
||||||
|
d="M12.028,13.945l6.519-8.67c0.166-0.221,0.122-0.534-0.099-0.7c-0.222-0.167-0.535-0.12-0.7,0.099l-6.519,8.67 c-0.166,0.221-0.122,0.534,0.099,0.7c0.091,0.068,0.196,0.101,0.301,0.101C11.78,14.145,11.931,14.075,12.028,13.945z" />
|
||||||
|
<path
|
||||||
|
d="M0.176,10.33c-0.21,0.18-0.235,0.495-0.057,0.705l7.082,8.314c0.096,0.111,0.234,0.176,0.381,0.176c0.005,0,0.01,0,0.016,0 c0.151-0.005,0.293-0.078,0.384-0.199l0.967-1.285c0.166-0.221,0.122-0.534-0.099-0.7c-0.219-0.166-0.535-0.123-0.7,0.099 l-0.592,0.786l-6.677-7.839C0.7,10.176,0.385,10.151,0.176,10.33z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
Повеселиться так, чтобы этот день запомнился
|
Повеселиться так, чтобы этот день запомнился
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -427,17 +576,23 @@
|
|||||||
|
|
||||||
<!-- Левая колонка -->
|
<!-- Левая колонка -->
|
||||||
<div class="form_name">
|
<div class="form_name">
|
||||||
<label>Имя
|
<label class="label_style">Имя
|
||||||
<input type="text" name="firstName" id="ffname" required>
|
<input type="text" name="firstName" id="ffname" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>Отчество
|
<label class="label_style">Отчество
|
||||||
<input type="text" name="middleName" id="fmname" required>
|
<input type="text" name="middleName" id="fmname" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>Фамилия
|
<label class="label_style">Фамилия
|
||||||
<input type="text" name="lastName" id="flname" required>
|
<input type="text" name="lastName" id="flname" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label class="label_1">Комментарий
|
||||||
|
<textarea cols="1.5" rows="1" type="text" name="lastName" id="fename"
|
||||||
|
placeholder="Напишите здесь о ваших особых предпочтениях и аллергиях"></textarea>
|
||||||
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Средняя колонка -->
|
<!-- Средняя колонка -->
|
||||||
@@ -459,17 +614,26 @@
|
|||||||
<div class="form_drink">
|
<div class="form_drink">
|
||||||
<p class="block_title">Напитки</p>
|
<p class="block_title">Напитки</p>
|
||||||
|
|
||||||
<label class="option"><input type="checkbox" name="drink" value="champagne" id="cchampagne"> Шампанское</label>
|
<label class="option"><input type="checkbox" name="drink" value="champagne" id="cchampagne">
|
||||||
|
Шампанское</label>
|
||||||
<label class="option"><input type="checkbox" name="drink" value="wine" id="cwine"> Вино</label>
|
<label class="option"><input type="checkbox" name="drink" value="wine" id="cwine"> Вино</label>
|
||||||
<label class="option"><input type="checkbox" name="drink" value="vodka" id="cvodka"> Водка</label>
|
<label class="option"><input type="checkbox" name="drink" value="vodka" id="cvodka">
|
||||||
<label class="option"><input type="checkbox" name="drink" value="whiskey" id="cwhiskey"> Виски</label>
|
Водка</label>
|
||||||
<label class="option"><input type="checkbox" name="drink" value="tequila" id="ctequila"> Текила</label>
|
<label class="option"><input type="checkbox" name="drink" value="whiskey" id="cwhiskey">
|
||||||
|
Виски</label>
|
||||||
|
<label class="option"><input type="checkbox" name="drink" value="tequila" id="ctequila">
|
||||||
|
Текила</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<form class="form-connect">
|
||||||
<button type="submit" class="answer_btn" id="bsubmit">
|
<button type="submit" class="answer_btn" id="bsubmit">
|
||||||
Подтвердить участие
|
Подтвердить участие
|
||||||
</button>
|
</button>
|
||||||
|
<button type="logout" class="answer_btn" id="logoutForm">
|
||||||
|
Выйти
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -487,31 +651,43 @@
|
|||||||
<div class="footer_contacts">
|
<div class="footer_contacts">
|
||||||
<p class="footer_text">"С нетерпением ждем встречи!"</p>
|
<p class="footer_text">"С нетерпением ждем встречи!"</p>
|
||||||
<div class="footer_cntcts">
|
<div class="footer_cntcts">
|
||||||
<a class="footer_cnt" href="https://t.me/Alena7729" target="_blank"><?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
<a class="footer_cnt" href="https://t.me/Alena7729" target="_blank">
|
||||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none"
|
||||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
<defs>
|
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)" />
|
||||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
<path
|
||||||
<stop stop-color="#37BBFE"/>
|
d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z"
|
||||||
<stop offset="1" stop-color="#007DBB"/>
|
fill="white" />
|
||||||
</linearGradient>
|
<defs>
|
||||||
</defs>
|
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30"
|
||||||
</svg>
|
gradientUnits="userSpaceOnUse">
|
||||||
Алёна</a>
|
<stop stop-color="#37BBFE" />
|
||||||
<a class="footer_cnt" href="https://t.me/DisaTylov" target="_blank"><?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
<stop offset="1" stop-color="#007DBB" />
|
||||||
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
</linearGradient>
|
||||||
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)"/>
|
</defs>
|
||||||
<path d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z" fill="white"/>
|
</svg>
|
||||||
<defs>
|
Алёна
|
||||||
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30" gradientUnits="userSpaceOnUse">
|
</a>
|
||||||
<stop stop-color="#37BBFE"/>
|
<a class="footer_cnt" href="https://t.me/DisaTylov" target="_blank">
|
||||||
<stop offset="1" stop-color="#007DBB"/>
|
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
</linearGradient>
|
<svg width="40px" height="40px" viewBox="0 0 32 32" fill="none"
|
||||||
</defs>
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
</svg>
|
<circle cx="16" cy="16" r="14" fill="url(#paint0_linear_87_7225)" />
|
||||||
Дмитрий</a>
|
<path
|
||||||
</div>
|
d="M22.9866 10.2088C23.1112 9.40332 22.3454 8.76755 21.6292 9.082L7.36482 15.3448C6.85123 15.5703 6.8888 16.3483 7.42147 16.5179L10.3631 17.4547C10.9246 17.6335 11.5325 17.541 12.0228 17.2023L18.655 12.6203C18.855 12.4821 19.073 12.7665 18.9021 12.9426L14.1281 17.8646C13.665 18.3421 13.7569 19.1512 14.314 19.5005L19.659 22.8523C20.2585 23.2282 21.0297 22.8506 21.1418 22.1261L22.9866 10.2088Z"
|
||||||
|
fill="white" />
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_87_7225" x1="16" y1="2" x2="16" y2="30"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#37BBFE" />
|
||||||
|
<stop offset="1" stop-color="#007DBB" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
Дмитрий
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer_copy">
|
<div class="footer_copy">
|
||||||
<div class="footer_hashtag">#свадьба2026</div>
|
<div class="footer_hashtag">#свадьба2026</div>
|
||||||
|
|||||||
@@ -1,30 +1,91 @@
|
|||||||
const swiper = new Swiper('.swiper', {
|
const swiper = new Swiper('.swiper', {
|
||||||
// Optional parameters
|
|
||||||
direction: 'horizontal',
|
|
||||||
loop: true,
|
|
||||||
|
|
||||||
// Navigation arrows
|
direction: 'horizontal',
|
||||||
|
loop: false,
|
||||||
|
|
||||||
|
// Производительность
|
||||||
|
preloadImages: false,
|
||||||
|
lazy: true,
|
||||||
|
watchSlidesProgress: true,
|
||||||
|
|
||||||
|
// Слайды
|
||||||
|
slidesPerView: 3,
|
||||||
|
spaceBetween: 15,
|
||||||
|
|
||||||
|
// Анимация
|
||||||
|
speed: 700,
|
||||||
|
|
||||||
|
// Навигация
|
||||||
navigation: {
|
navigation: {
|
||||||
nextEl: '.swiper-button-next',
|
nextEl: '.swiper-button-next',
|
||||||
prevEl: '.swiper-button-prev',
|
prevEl: '.swiper-button-prev',
|
||||||
},
|
},
|
||||||
|
|
||||||
// And if we need scrollbar
|
// Скроллбар
|
||||||
scrollbar: {
|
scrollbar: {
|
||||||
el: '.swiper-scrollbar',
|
el: '.swiper-scrollbar',
|
||||||
|
hide: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
speed: 1000,
|
// Адаптив
|
||||||
breakpoints: {
|
breakpoints: {
|
||||||
740: {
|
330: {
|
||||||
slidesPerView: 1,
|
slidesPerView: 1,
|
||||||
},
|
},
|
||||||
1200: {
|
|
||||||
|
768: {
|
||||||
slidesPerView: 2,
|
slidesPerView: 2,
|
||||||
},
|
},
|
||||||
1600: {
|
|
||||||
|
1400: {
|
||||||
slidesPerView: 3,
|
slidesPerView: 3,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set the date we're counting down to
|
||||||
|
var countDownDate = new Date("Aug 22, 2026 10:40:00").getTime();
|
||||||
|
|
||||||
|
// Update the count down every 1 second
|
||||||
|
var x = setInterval(function() {
|
||||||
|
|
||||||
|
// Get today's date and time
|
||||||
|
var now = new Date().getTime();
|
||||||
|
|
||||||
|
// Find the distance between now and the count down date
|
||||||
|
var distance = countDownDate - now;
|
||||||
|
|
||||||
|
// Time calculations for days, hours, minutes and seconds
|
||||||
|
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||||
|
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||||
|
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||||
|
|
||||||
|
// Display the result in the element with id="demo"
|
||||||
|
document.getElementById("demo").innerHTML = days + "д " + hours + "ч "
|
||||||
|
+ minutes + "м " + seconds + "с ";
|
||||||
|
|
||||||
|
// If the count down is finished, write some text
|
||||||
|
if (distance < 0) {
|
||||||
|
clearInterval(x);
|
||||||
|
document.getElementById("demo").innerHTML = "EXPIRED";
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
|
const burger = document.getElementById('burger');
|
||||||
|
const nav = document.getElementById('nav');
|
||||||
|
const links = document.querySelectorAll('.menu .link');
|
||||||
|
|
||||||
|
burger.addEventListener('click', () => {
|
||||||
|
burger.classList.toggle('active');
|
||||||
|
nav.classList.toggle('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
links.forEach(link => {
|
||||||
|
link.addEventListener('click', () => {
|
||||||
|
burger.classList.remove('active');
|
||||||
|
nav.classList.remove('active');
|
||||||
|
});
|
||||||
|
});
|
||||||