create header

This commit is contained in:
2025-05-12 17:23:05 +03:00
parent e74731b789
commit a5ffa7ae13
22 changed files with 576 additions and 24 deletions

80
Pipfile Normal file
View File

@@ -0,0 +1,80 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
aiohappyeyeballs = "==2.4.3"
aiohttp = "==3.11.7"
aiosignal = "==1.3.1"
asgiref = "==3.8.1"
async-timeout = "==5.0.1"
attrs = "==24.2.0"
autobahn = "==24.4.2"
automat = "==24.8.1"
certifi = "==2024.8.30"
cffi = "==1.17.1"
channels = "==4.0.0"
channels-redis = "==4.1.0"
charset-normalizer = "==3.4.0"
constantly = "==23.10.4"
cryptography = "==43.0.3"
daphne = "==4.0.0"
defusedxml = "==0.7.1"
django = "==4.2.2"
django-allauth = "==0.60.0"
django-ckeditor = "==6.5.1"
django-colorfield = "==0.11.0"
django-js-asset = "==2.2.0"
django-modeltranslation = "==0.18.10"
django-rosetta = "==0.10.0"
django-webpush = "==0.3.6"
frozenlist = "==1.5.0"
geographiclib = "==2.0"
geopy = "==2.4.1"
h3 = "==3.7.7"
http-ece = "==1.2.1"
hyperlink = "==21.0.0"
idna = "==3.10"
incremental = "==24.7.2"
msgpack = "==1.1.0"
multidict = "==6.1.0"
numpy = "==2.0.2"
oauthlib = "==3.2.2"
osm2geojson = "==0.2.5"
overpass = "==0.7.2"
pillow = "==9.5.0"
polib = "==1.2.0"
propcache = "==0.2.0"
psycopg2-binary = "==2.9.6"
py-vapid = "==1.9.2"
pyasn1 = "==0.6.1"
pyasn1-modules = "==0.4.1"
pycparser = "==2.22"
pyjwt = "==2.10.0"
pyopenssl = "==24.2.1"
python3-openid = "==3.2.0"
pytz = "==2024.1"
pywebpush = "==2.0.3"
redis = "==5.2.0"
requests = "==2.32.3"
requests-oauthlib = "==2.0.0"
requests-pkcs12 = "==1.24"
service-identity = "==24.2.0"
shapely = "==2.0.6"
six = "==1.16.0"
sqlparse = "==0.5.2"
timezonefinder = "==6.5.2"
tomli = "==2.1.0"
twisted = "==24.10.0"
txaio = "==23.1.1"
typing-extensions = "==4.12.2"
urllib3 = "==2.2.3"
yarl = "==1.18.0"
"zope.interface" = "==7.1.1"
[dev-packages]
[requires]
python_version = "3.12"
python_full_version = "3.12.5"

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.1 on 2025-05-12 13:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('RoutesApp', '0013_alter_route_cargo_type'),
]
operations = [
migrations.AlterField(
model_name='route',
name='cargo_type',
field=models.CharField(choices=[('letter', 'Письмо\\Документы'), ('package', 'Посылка (до 30кг)'), ('passenger', 'Попутчик'), ('parcel', 'Бандероль (до 5кг)'), ('cargo', 'Груз (свыше 30 кг)')], default='letter', verbose_name='Могу перевезти'),
),
]

View File

@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
from django.urls import reverse_lazy
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -57,7 +58,7 @@ ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
# LOGIN_URL = '/profile/login/'
from django.urls import reverse_lazy
LOGIN_URL = reverse_lazy('login_profile')
LOGOUT_REDIRECT_URL = '/profile/login/'
@@ -204,9 +205,9 @@ CHANNEL_LAYERS = {
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'twbDBv2',
'USER': 'test_user',
'PASSWORD': 'test_db_pass',
'NAME': 'tripwithbonus',
'USER': 'twbuser',
'PASSWORD': 'twbuser',
'HOST': '127.0.0.1',
'PORT': '5432',
}

41
frontend/.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

36
frontend/README.md Normal file
View File

@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.

BIN
frontend/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

27
frontend/app/globals.css Normal file
View File

@@ -0,0 +1,27 @@
@import 'tailwindcss';
:root {
--background: #eeebeb;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-orange: #ff613a;
}
@media (prefers-color-scheme: light) {
:root {
--background: #eeebeb;
--foreground: #171717;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

37
frontend/app/layout.tsx Normal file
View File

@@ -0,0 +1,37 @@
import type { Metadata } from 'next'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'
import Header from '@/components/Header'
const geistSans = Geist({
variable: '--font-geist-sans',
subsets: ['latin'],
})
const geistMono = Geist_Mono({
variable: '--font-geist-mono',
subsets: ['latin'],
})
export const metadata: Metadata = {
title: 'Отправка посылок в любую точку мира | TripWB',
description:
'Международная отправка посылок ✓ Отправка посылки в любую точку планеты ✓ Приемлемая цена отправки посылки ✓ Доставка в кратчайшие сроки ➡️ Обращайтесь к нам',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
<body className="min-h-screen">
<main className="min-h-screen">
<Header />
{children}
</main>
</body>
</html>
)
}

7
frontend/app/page.tsx Normal file
View File

@@ -0,0 +1,7 @@
export default function Home() {
return (
<div>
<h1>Main page</h1>
</div>
)
}

View File

View File

@@ -0,0 +1,65 @@
import React from 'react'
import Image from 'next/image'
import Link from 'next/link'
import Burger from './ui/Burger'
import LangSwitcher from './LangSwitcher'
import Button from './ui/Button'
const Header = () => {
return (
<div className="flex justify-between items-center px-6 py-8 w-[95%] mx-auto">
<div className="flex items-center justify-center space-x-10">
<Image
src="/images/logo.png"
alt="logo"
width={50}
height={50}
priority
/>
{/* Desktop Burger */}
<div className="hidden md:block">
<Burger />
</div>
<Link
href="/"
className="text-base font-medium px-4 hover:underline hidden md:block"
>
Могу взять посылку
</Link>
</div>
<div className="flex items-center justify-center space-x-10">
<LangSwitcher />
<Button text="Разместить объявление" className="hidden md:block" />
{/* Auth Block - Desktop */}
<div className="hidden md:block text-base font-medium">
<Link href="/register" className="hover:underline">
Регистрация
</Link>
<span> / </span>
<Link href="/login" className="hover:underline">
Войти
</Link>
</div>
{/* Mobile Controls */}
<div className="flex items-center space-x-4 md:hidden">
{/* Mobile Burger */}
{/* Mobile Auth */}
<Link href="/login">
<Image
src="/images/userlogo.png"
alt="user"
width={24}
height={24}
/>
</Link>
<Burger />
</div>
</div>
</div>
)
}
export default Header

View File

@@ -0,0 +1,31 @@
'use client'
import React, { useState } from 'react'
const LangSwitcher = () => {
const [selectedLang, setSelectedLang] = useState('ru')
return (
<div className="flex items-center space-x-2">
<button
onClick={() => setSelectedLang('ru')}
className={`${
selectedLang === 'ru' ? 'text-orange' : 'text-gray-500'
} cursor-pointer`}
>
RU
</button>
<span className="text-gray-500">/</span>
<button
onClick={() => setSelectedLang('en')}
className={`${
selectedLang === 'en' ? 'text-orange' : 'text-gray-500'
} cursor-pointer`}
>
EN
</button>
</div>
)
}
export default LangSwitcher

View File

@@ -0,0 +1,82 @@
'use client'
import React, { useState } from 'react'
import Link from 'next/link'
import Button from './Button'
const Burger = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<button
onClick={() => setIsOpen(!isOpen)}
className="relative z-50 w-8 h-8 flex flex-col justify-center items-center"
>
<div className="relative w-8 h-8">
<span
className={`absolute h-0.5 bg-orange transition-all duration-300 ease-in-out ${
isOpen ? 'w-8 rotate-45 top-4' : 'w-8 top-2'
}`}
></span>
<span
className={`absolute h-0.5 bg-orange transition-all duration-300 ease-in-out ${
isOpen ? 'w-0 opacity-0 top-4' : 'w-8 top-4'
}`}
></span>
<span
className={`absolute h-0.5 bg-orange transition-all duration-300 ease-in-out ${
isOpen ? 'w-8 -rotate-45 top-4' : 'w-8 top-6'
}`}
></span>
</div>
</button>
{/* меню */}
<div
className={`fixed left-0 w-full bg-[#eeebeb] shadow-lg transition-all duration-300 ease-in-out origin-top ${
isOpen
? 'top-[80px] h-[calc(100vh-80px)] opacity-100 scale-y-100'
: 'top-[80px] h-0 opacity-0 scale-y-0'
} ${isOpen ? 'pointer-events-auto' : 'pointer-events-none'}`}
>
<div
className={`flex flex-col items-center pt-12 space-y-8 transition-all duration-300 ${
isOpen ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-4'
}`}
>
<Link
href="/"
className="text-xl hover:text-orange transition-colors duration-200"
onClick={() => setIsOpen(false)}
>
Ссылка 1
</Link>
<Link
href="/search"
className="text-xl hover:text-orange transition-colors duration-200"
onClick={() => setIsOpen(false)}
>
Ссылка 2
</Link>
<Link
href="/about"
className="text-xl hover:text-orange transition-colors duration-200"
onClick={() => setIsOpen(false)}
>
Ссылка 3
</Link>
<Link
href="/"
className="text-xl hover:text-orange transition-colors duration-200"
onClick={() => setIsOpen(false)}
>
Могу взять посылку
</Link>
<Button text="Разместить объявление" />
</div>
</div>
</>
)
}
export default Burger

View File

@@ -0,0 +1,22 @@
import React from 'react'
interface ButtonProps {
onClick?: () => void
className?: string
text?: string
type?: 'button'
}
const Button = ({ onClick, className, text, type }: ButtonProps) => {
return (
<button
onClick={onClick}
className={`${className} text-base font-medium px-4 py-3 text-white bg-orange rounded-2xl cursor-pointer`}
type={type}
>
<span>{text}</span>
</button>
)
}
export default Button

View File

@@ -0,0 +1,16 @@
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
export default eslintConfig;

7
frontend/next.config.ts Normal file
View File

@@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;

View File

@@ -0,0 +1,5 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};
export default config;

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

27
frontend/tsconfig.json Normal file
View File

@@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

View File

@@ -1,20 +0,0 @@
Django==4.2.2
django-ckeditor==6.5.1
psycopg2-binary==2.9.6
requests
Pillow==9.5.0
django-modeltranslation==0.18.10
overpass
geopy
channels==4.0.0
daphne==4.0.0
channels-redis==4.1.0
django-colorfield
django-webpush==0.3.6
django-allauth==0.60.0
pytz==2024.1
requests-pkcs12==1.24
#django-tz-detect==0.4.0
django-rosetta==0.10.0
timezonefinder==6.5.2

70
requirements.txt Normal file
View File

@@ -0,0 +1,70 @@
aiohappyeyeballs==2.6.1
aiohttp==3.11.18
aiosignal==1.3.2
asgiref==3.8.1
async-timeout==5.0.1
attrs==25.3.0
autobahn==24.4.2
Automat==25.4.16
certifi==2025.4.26
cffi==1.17.1
channels==4.2.2
channels_redis==4.2.1
charset-normalizer==3.4.2
constantly==23.10.4
cryptography==44.0.3
daphne==4.1.2
defusedxml==0.7.1
Django==5.2.1
django-allauth==65.8.0
django-ckeditor==6.7.2
django-colorfield==0.14.0
django-js-asset==3.1.2
django-modeltranslation==0.19.14
django-rosetta==0.10.2
django-webpush==0.3.6
frozenlist==1.6.0
geographiclib==2.0
geojson==3.2.0
geopy==2.4.1
h3==4.2.2
http_ece==1.2.1
hyperlink==21.0.0
idna==3.10
incremental==24.7.2
msgpack==1.1.0
multidict==6.4.3
numpy==2.2.5
oauthlib==3.2.2
osm2geojson==0.2.6
overpass==0.7
pillow==11.2.1
polib==1.2.0
propcache==0.3.1
psycopg2-binary==2.9.10
py-vapid==1.9.2
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
PyJWT==2.10.1
pyOpenSSL==25.0.0
python3-openid==3.2.0
pytz==2025.2
pywebpush==2.0.3
redis==6.0.0
requests==2.32.3
requests-oauthlib==2.0.0
requests-pkcs12==1.25
service-identity==24.2.0
setuptools==80.4.0
shapely==2.1.0
six==1.17.0
sqlparse==0.5.3
timezonefinder==6.5.9
tomli==2.2.1
Twisted==24.11.0
txaio==23.1.1
typing_extensions==4.13.2
urllib3==2.4.0
yarl==1.20.0
zope.interface==7.2