search urls

This commit is contained in:
2025-05-23 13:44:49 +03:00
parent 917acc0353
commit f3ca53d907
8 changed files with 273 additions and 19 deletions

View File

@@ -14,6 +14,7 @@ djangorestframework-simplejwt = "*"
django-cors-headers = "*"
requests = "*"
pytz = "*"
requests-pkcs12 = "*"
[dev-packages]

135
backend/Pipfile.lock generated
View File

@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "94474e1990b5d4d58689cca46373a808771ba11de6b9dc4bda6cdbdd93a4bb70"
"sha256": "268a54d3447876143d9a71096db298c014bffccc4d8205ed357ead4e3bcd0a38"
},
"pipfile-spec": 6,
"requires": {
@@ -32,6 +32,79 @@
"markers": "python_version >= '3.6'",
"version": "==2025.4.26"
},
"cffi": {
"hashes": [
"sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8",
"sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2",
"sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1",
"sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15",
"sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36",
"sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824",
"sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8",
"sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36",
"sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17",
"sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf",
"sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc",
"sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3",
"sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed",
"sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702",
"sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1",
"sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8",
"sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903",
"sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6",
"sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d",
"sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b",
"sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e",
"sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be",
"sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c",
"sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683",
"sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9",
"sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c",
"sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8",
"sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1",
"sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4",
"sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655",
"sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67",
"sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595",
"sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0",
"sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65",
"sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41",
"sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6",
"sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401",
"sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6",
"sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3",
"sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16",
"sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93",
"sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e",
"sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4",
"sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964",
"sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c",
"sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576",
"sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0",
"sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3",
"sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662",
"sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3",
"sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff",
"sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5",
"sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd",
"sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f",
"sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5",
"sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14",
"sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d",
"sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9",
"sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7",
"sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382",
"sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a",
"sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e",
"sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a",
"sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4",
"sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99",
"sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
"sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
],
"markers": "python_version >= '3.8'",
"version": "==1.17.1"
},
"charset-normalizer": {
"hashes": [
"sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4",
@@ -130,6 +203,49 @@
"markers": "python_version >= '3.7'",
"version": "==3.4.2"
},
"cryptography": {
"hashes": [
"sha256:057723b79752a142efbc609e90b0dff27b0361ccbee3bd48312d70f5cdf53b78",
"sha256:05c2385b1f5c89a17df19900cfb1345115a77168f5ed44bdf6fd3de1ce5cc65b",
"sha256:08281de408e7eb71ba3cd5098709a356bfdf65eebd7ee7633c3610f0aa80d79b",
"sha256:10d68763892a7b19c22508ab57799c4423c7c8cd61d7eee4c5a6a55a46511949",
"sha256:1655d3a76e3dedb683c982a6c3a2cbfae2d08f47a48ec5a3d58db52b3d29ea6f",
"sha256:18f8084b7ca3ce1b8d38bdfe33c48116edf9a08b4d056ef4a96dceaa36d8d965",
"sha256:2cb03a944a1a412724d15a7c051d50e63a868031f26b6a312f2016965b661942",
"sha256:4142e20c29224cec63e9e32eb1e6014fb285fe39b7be66b3564ca978a3a8afe9",
"sha256:463096533acd5097f8751115bc600b0b64620c4aafcac10c6d0041e6e68f88fe",
"sha256:48caa55c528617fa6db1a9c3bf2e37ccb31b73e098ac2b71408d1f2db551dde4",
"sha256:49af56491473231159c98c2c26f1a8f3799a60e5cf0e872d00745b858ddac9d2",
"sha256:4cc31c66411e14dd70e2f384a9204a859dc25b05e1f303df0f5326691061b839",
"sha256:501de1296b2041dccf2115e3c7d4947430585601b251b140970ce255c5cfb985",
"sha256:59c0c8f043dd376bbd9d4f636223836aed50431af4c5a467ed9bf61520294627",
"sha256:614bca7c6ed0d8ad1dce683a6289afae1f880675b4090878a0136c3da16bc693",
"sha256:61a8b1bbddd9332917485b2453d1de49f142e6334ce1d97b7916d5a85d179c84",
"sha256:7429936146063bd1b2cfc54f0e04016b90ee9b1c908a7bed0800049cbace70eb",
"sha256:7c73968fbb7698a4c5d6160859db560d3aac160edde89c751edd5a8bc6560c88",
"sha256:80303ee6a02ef38c4253160446cbeb5c400c07e01d4ddbd4ff722a89b736d95a",
"sha256:965611880c3fa8e504b7458484c0697e00ae6e937279cd6734fdaa2bc954dc49",
"sha256:9a900036b42f7324df7c7ad9569eb92ba0b613cf699160dd9c2154b24fd02f8e",
"sha256:9cfd1399064b13043082c660ddd97a0358e41c8b0dc7b77c1243e013d305c344",
"sha256:a8ec324711596fbf21837d3a5db543937dd84597d364769b46e0102250023f77",
"sha256:a9727a21957d3327cf6b7eb5ffc9e4b663909a25fea158e3fcbc49d4cdd7881b",
"sha256:b19f4b28dd2ef2e6d600307fee656c00825a2980c4356a7080bd758d633c3a6f",
"sha256:b2de529027579e43b6dc1f805f467b102fb7d13c1e54c334f1403ee2b37d0059",
"sha256:c0c000c1a09f069632d8a9eb3b610ac029fcc682f1d69b758e625d6ee713f4ed",
"sha256:cdafb86eb673c3211accffbffdb3cdffa3aaafacd14819e0898d23696d18e4d3",
"sha256:d2a90ce2f0f5b695e4785ac07c19a58244092f3c85d57db6d8eb1a2b26d2aad6",
"sha256:d784d57b958ffd07e9e226d17272f9af0c41572557604ca7554214def32c26bf",
"sha256:d891942592789fa0ab71b502550bbadb12f540d7413d7d7c4cef4b02af0f5bc6",
"sha256:dc7693573f16535428183de8fd27f0ca1ca37a51baa0b41dc5ed7b3d68fe80e2",
"sha256:ddb8d01aa900b741d6b7cc585a97aff787175f160ab975e21f880e89d810781a",
"sha256:e328357b6bbf79928363dbf13f4635b7aac0306afb7e5ad24d21d0c5761c3253",
"sha256:e86c8d54cd19a13e9081898b3c24351683fd39d726ecf8e774aaa9d8d96f5f3a",
"sha256:e9e4bdcd70216b08801e267c0b563316b787f957a46e215249921f99288456f9",
"sha256:f169469d04a23282de9d0be349499cb6683b6ff1b68901210faacac9b0c24b7d"
],
"markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'",
"version": "==45.0.2"
},
"django": {
"hashes": [
"sha256:57fe1f1b59462caed092c80b3dd324fd92161b620d59a9ba9181c34746c97284",
@@ -279,6 +395,14 @@
"markers": "python_version >= '3.8'",
"version": "==2.9.10"
},
"pycparser": {
"hashes": [
"sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6",
"sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"
],
"markers": "python_version >= '3.8'",
"version": "==2.22"
},
"pyjwt": {
"hashes": [
"sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850",
@@ -313,6 +437,15 @@
"markers": "python_version >= '3.8'",
"version": "==2.32.3"
},
"requests-pkcs12": {
"hashes": [
"sha256:39d64144d9443c29fd7e9d4c33f6bcb8cda5ceedcb953030d6ea847f1889b410",
"sha256:94fbd01958f6386198be04a1cb6f2f0c86bd2d89e0bf6fe5d09cfba874f23936"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==1.25"
},
"six": {
"hashes": [
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",

View File

@@ -1,6 +1,8 @@
asgiref==3.8.1
certifi==2025.4.26
cffi==1.17.1
charset-normalizer==3.4.2
cryptography==45.0.2
Django==5.2.1
django-cors-headers==4.7.0
djangorestframework==3.16.0
@@ -8,10 +10,12 @@ djangorestframework_simplejwt==5.5.0
idna==3.10
pillow==11.2.1
psycopg2==2.9.10
pycparser==2.22
PyJWT==2.9.0
python-dotenv==1.1.0
pytz==2025.2
requests==2.32.3
requests-pkcs12==1.25
six==1.17.0
sqlparse==0.5.3
transliterate==1.10.2

View File

@@ -0,0 +1,48 @@
import React, { Suspense } from 'react'
import SearchCard from '../../components/SearchCard'
interface SearchPageProps {
params: {
category: string
route: string
}
}
// дернуть search api для from-to параметров
async function fetchSearch(category: string, from: string, to: string) {
// get search api(owner_type, from, to)
return []
}
export default async function SearchPage(props: SearchPageProps) {
const params = await props.params
const { category, route } = params
const [fromCity, toCity] = route.split('-')
const initialData = await fetchSearch(category, fromCity, toCity)
return (
<div className="container mx-auto p-4">
<h1 className="mb-4 text-2xl font-bold">
{category === 'mover' ? 'Поиск перевозчика' : 'Поиск посылки'}
</h1>
<div className="mb-4">
<p>
Маршрут: {fromCity} {toCity}
</p>
</div>
<Suspense fallback={<div>Загрузка результатов...</div>}>
{/* результаты поиска */}
<div className="space-y-4">
{initialData.map((item: any, index: number) => (
<div key={index} className="rounded-lg border p-4">
{/* Здесь будет карточка с результатом */}
<p>Результат поиска {index + 1}</p>
</div>
))}
</div>
</Suspense>
</div>
)
}

View File

@@ -0,0 +1,44 @@
import React, { Suspense } from 'react'
import SearchCard from '../components/SearchCard'
interface SearchPageProps {
params: {
category: string
}
searchParams: {
[key: string]: string | string[] | undefined
}
}
// получаем все предложения по выбранному owner_type
async function fetchSearch(category: string, query: string = '') {
// get search api(owner_type)
return []
}
export default async function SearchPage(props: SearchPageProps) {
const params = await props.params
const { category } = params
const initialData = await fetchSearch(category)
return (
<div className="container mx-auto p-4">
<h1 className="mb-4 text-2xl font-bold">
{category === 'mover' ? 'Поиск перевозчика' : 'Поиск посылки'}
</h1>
<Suspense fallback={<div>Загрузка результатов...</div>}>
{/* Здесь будет компонент с результатами поиска */}
<div className="space-y-4">
{initialData.map((item: any, index: number) => (
<div key={index} className="rounded-lg border p-4">
{/* Здесь будет карточка с результатом */}
<p>Результат поиска {index + 1}</p>
</div>
))}
</div>
</Suspense>
</div>
)
}

View File

@@ -30,7 +30,7 @@ const SearchCard = ({
}
const setMovingTypeIcon = () => {
if (type_transport === 'air') {
if (type_transport === 'avia') {
return '/images/airplane.png'
}
return '/images/car.png'

View File

@@ -9,6 +9,7 @@ import News from '@/components/News'
import { getFAQs } from '@/lib/main/fetchFAQ'
import { getNews } from '@/lib/main/fetchNews'
import { getFirstRoutes } from '@/lib/main/fetchFirstRoutes'
import Link from 'next/link'
export default async function Home() {
const faqs = await getFAQs()
@@ -55,9 +56,12 @@ export default async function Home() {
{/* форма на серч */}
<AddressSelector />
<div className="decoration-orange hover:text-orange mb-20 cursor-pointer text-lg font-normal text-[#272424] underline underline-offset-4 transition-colors">
<Link
href="search/customer"
className="decoration-orange hover:text-orange mb-20 cursor-pointer text-lg font-normal text-[#272424] underline underline-offset-4 transition-colors"
>
Я могу взять с собой посылку
</div>
</Link>
<div className="mb-8 flex flex-col items-center justify-center">
<h2 className="text-center text-4xl font-bold">Все объявления</h2>

View File

@@ -2,45 +2,65 @@
import React, { useState } from 'react'
import TextInput from './ui/TextInput'
import Button from './ui/Button'
import Link from 'next/link'
export default function AddressSelector() {
const [fromAddress, setFromAddress] = useState('')
const [toAddress, setToAddress] = useState('')
const formatAddress = (address: string) => {
return address
.toLowerCase()
.trim()
.replace(/[^a-zа-я0-9\s-]/gi, '')
.replace(/\s+/g, '-')
}
const getSearchUrl = (category: 'mover' | 'customer') => {
if (!fromAddress || !toAddress) return `/search/${category}`
const from = formatAddress(fromAddress)
const to = formatAddress(toAddress)
return `/search/${category}/${from}-${to}`
}
return (
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 w-full my-2 sm:my-4">
<div className="flex flex-col sm:flex-row sm:items-end gap-4 sm:gap-3">
<div className="w-full sm:flex-[3] min-w-0 sm:px-1">
<div className="my-2 w-full rounded-xl bg-white p-4 shadow-lg sm:my-4 sm:p-6">
<div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:gap-3">
<div className="w-full min-w-0 sm:flex-[3] sm:px-1">
<TextInput
placeholder="Минск, Беларусь"
tooltip="Укажите пункт (Город/Страна), откуда необходимо забрать посылку."
label="Забрать посылку из"
value={fromAddress}
handleChange={(e) => setFromAddress(e.target.value)}
handleChange={e => setFromAddress(e.target.value)}
name="fromAddress"
style="main"
/>
</div>
<div className="w-full sm:flex-[3] min-w-0 sm:px-1">
<div className="w-full min-w-0 sm:flex-[3] sm:px-1">
<TextInput
placeholder="Москва, Россия"
label="Доставить посылку в"
tooltip="Укажите пункт (Город/Страна), куда необходимо доставить посылку."
value={toAddress}
handleChange={(e) => setToAddress(e.target.value)}
handleChange={e => setToAddress(e.target.value)}
name="toAddress"
style="main"
/>
</div>
<Button
text="Найти перевозчика"
className="w-full sm:w-auto sm:flex-1 whitespace-nowrap bg-orange hover:bg-orange/80 text-white p-4"
/>
<Button
text="Найти посылку"
className="w-full sm:w-auto sm:flex-1 whitespace-nowrap bg-gray-100 hover:bg-gray-200 text-gray-800 p-4"
/>
<Link
href={getSearchUrl('mover')}
className="bg-orange hover:bg-orange/80 w-full rounded-2xl p-4 text-center whitespace-nowrap text-white sm:w-auto sm:flex-1"
>
Найти перевозчика
</Link>
<Link
href={getSearchUrl('customer')}
className="w-full rounded-2xl bg-gray-100 p-4 text-center whitespace-nowrap text-gray-800 hover:bg-gray-200 sm:w-auto sm:flex-1"
>
Найти посылку
</Link>
</div>
</div>
)