Compare commits
3 Commits
4f5e56f855
...
82018cea2c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82018cea2c | ||
|
|
5bc7d1d901 | ||
|
|
dba36ae458 |
3
.env.example
Normal file
3
.env.example
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TAYLOR_API_ENDPOINT=
|
||||||
|
TAYLOR_API_TOKEN=
|
||||||
|
TAYLOR_MEDIA_URL=
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -34,7 +34,7 @@ yarn-error.log*
|
|||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
# env files (can opt-in for committing if needed)
|
# env files (can opt-in for committing if needed)
|
||||||
.env*
|
.env
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"embla-carousel-autoplay": "^8.6.0",
|
"embla-carousel-autoplay": "^8.6.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
|
"json-to-graphql-query": "^2.3.0",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
"lucide-react": "^0.501.0",
|
"lucide-react": "^0.501.0",
|
||||||
"next": "15.3.1",
|
"next": "15.3.1",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
@ -52,7 +54,8 @@
|
|||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"@types/eslint-config-prettier": "^6.11.3",
|
"@types/eslint-config-prettier": "^6.11.3",
|
||||||
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
||||||
"@types/node": "^20",
|
"@types/lodash": "^4.17.16",
|
||||||
|
"@types/node": "^20.17.30",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"@typescript-eslint/parser": "^8.30.1",
|
"@typescript-eslint/parser": "^8.30.1",
|
||||||
|
|||||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@ -62,6 +62,12 @@ importers:
|
|||||||
embla-carousel-react:
|
embla-carousel-react:
|
||||||
specifier: ^8.6.0
|
specifier: ^8.6.0
|
||||||
version: 8.6.0(react@19.1.0)
|
version: 8.6.0(react@19.1.0)
|
||||||
|
json-to-graphql-query:
|
||||||
|
specifier: ^2.3.0
|
||||||
|
version: 2.3.0
|
||||||
|
lodash:
|
||||||
|
specifier: ^4.17.21
|
||||||
|
version: 4.17.21
|
||||||
lucide-react:
|
lucide-react:
|
||||||
specifier: ^0.501.0
|
specifier: ^0.501.0
|
||||||
version: 0.501.0(react@19.1.0)
|
version: 0.501.0(react@19.1.0)
|
||||||
@ -129,8 +135,11 @@ importers:
|
|||||||
'@types/eslint-plugin-tailwindcss':
|
'@types/eslint-plugin-tailwindcss':
|
||||||
specifier: ^3.17.0
|
specifier: ^3.17.0
|
||||||
version: 3.17.0
|
version: 3.17.0
|
||||||
|
'@types/lodash':
|
||||||
|
specifier: ^4.17.16
|
||||||
|
version: 4.17.16
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20
|
specifier: ^20.17.30
|
||||||
version: 20.17.30
|
version: 20.17.30
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^19
|
specifier: ^19
|
||||||
@ -1080,6 +1089,9 @@ packages:
|
|||||||
'@types/json5@0.0.29':
|
'@types/json5@0.0.29':
|
||||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||||
|
|
||||||
|
'@types/lodash@4.17.16':
|
||||||
|
resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==}
|
||||||
|
|
||||||
'@types/node@20.17.30':
|
'@types/node@20.17.30':
|
||||||
resolution: {integrity: sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==}
|
resolution: {integrity: sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==}
|
||||||
|
|
||||||
@ -1949,6 +1961,9 @@ packages:
|
|||||||
json-stable-stringify-without-jsonify@1.0.1:
|
json-stable-stringify-without-jsonify@1.0.1:
|
||||||
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
|
||||||
|
|
||||||
|
json-to-graphql-query@2.3.0:
|
||||||
|
resolution: {integrity: sha512-khZtaLLQ0HllFec+t89ZWduUZ0rmne/OpRm/39hyZUWDHNx9Yk4DgQzDtMeqd8zj2g5opBD4GHrdtH0JzKnN2g==}
|
||||||
|
|
||||||
json5@1.0.2:
|
json5@1.0.2:
|
||||||
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
|
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -3524,6 +3539,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/json5@0.0.29': {}
|
'@types/json5@0.0.29': {}
|
||||||
|
|
||||||
|
'@types/lodash@4.17.16': {}
|
||||||
|
|
||||||
'@types/node@20.17.30':
|
'@types/node@20.17.30':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.19.8
|
undici-types: 6.19.8
|
||||||
@ -4089,7 +4106,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.25.0(jiti@2.4.2)):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import-x@4.10.6(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@9.25.0(jiti@2.4.2)))(eslint@9.25.0(jiti@2.4.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@ -4131,7 +4148,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 9.25.0(jiti@2.4.2)
|
eslint: 9.25.0(jiti@2.4.2)
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.25.0(jiti@2.4.2))
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import-x@4.10.6(eslint@9.25.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-import@2.31.0)(eslint@9.25.0(jiti@2.4.2)))(eslint@9.25.0(jiti@2.4.2))
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.16.1
|
is-core-module: 2.16.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@ -4579,6 +4596,8 @@ snapshots:
|
|||||||
|
|
||||||
json-stable-stringify-without-jsonify@1.0.1: {}
|
json-stable-stringify-without-jsonify@1.0.1: {}
|
||||||
|
|
||||||
|
json-to-graphql-query@2.3.0: {}
|
||||||
|
|
||||||
json5@1.0.2:
|
json5@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
|
|||||||
50
src/app/api-utlities/@types/index.ts
Normal file
50
src/app/api-utlities/@types/index.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
export type Root<T> = { records: T[] };
|
||||||
|
|
||||||
|
export interface Image {
|
||||||
|
url: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Select {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Discount = Root<{
|
||||||
|
_name: string;
|
||||||
|
_opisanie: string;
|
||||||
|
_do: string;
|
||||||
|
_foto: Image[];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type Job = Root<{
|
||||||
|
id: number;
|
||||||
|
_name: string;
|
||||||
|
_type: Select[];
|
||||||
|
_localtio: Select[];
|
||||||
|
_tags: Select[];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type Partner = Root<{
|
||||||
|
id: number;
|
||||||
|
_name: string;
|
||||||
|
_image: Image[];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export type Station = Root<{
|
||||||
|
_name: string;
|
||||||
|
_opisanie: string;
|
||||||
|
_adress: string;
|
||||||
|
_chasyRaboty: Select;
|
||||||
|
_lat: number;
|
||||||
|
_long: number;
|
||||||
|
_avtomojka: boolean;
|
||||||
|
_dtCopy: boolean;
|
||||||
|
_ai92Copy: boolean;
|
||||||
|
_ai95Copy: boolean;
|
||||||
|
_z100Copy: boolean;
|
||||||
|
_propanCopy: boolean;
|
||||||
|
_zaryadnayaStanci: boolean;
|
||||||
|
_miniMarketCop: boolean;
|
||||||
|
_region: Select;
|
||||||
|
_foto: Image[];
|
||||||
|
}>;
|
||||||
48
src/app/api-utlities/presenters/index.ts
Normal file
48
src/app/api-utlities/presenters/index.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
|
import { Discount, Image, Job, Partner, Station } from '../@types';
|
||||||
|
|
||||||
|
export const presentImage = (images: Image[]) =>
|
||||||
|
isEmpty(images) ? null : `${process.env.TAYLOR_MEDIA_URL}/${images[0].url}`;
|
||||||
|
|
||||||
|
export const presentPartners = (partners: Partner) =>
|
||||||
|
partners.records.map((record) => ({
|
||||||
|
name: record._name,
|
||||||
|
poster: presentImage(record._image),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const presentJobs = (jobs: Job) =>
|
||||||
|
jobs.records.map((job) => ({
|
||||||
|
name: job._name,
|
||||||
|
tags: job._tags.map((tag) => tag.name),
|
||||||
|
location: !isEmpty(job._localtio) ? job._localtio[0].name : null,
|
||||||
|
type: !isEmpty(job._type) ? job._type[0].name : null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const presentDiscounts = (discounts: Discount) =>
|
||||||
|
discounts.records.map((discount) => ({
|
||||||
|
name: discount._name,
|
||||||
|
description: discount._opisanie,
|
||||||
|
expiresAt: discount._do,
|
||||||
|
image: presentImage(discount._foto),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const presentStations = (stations: Station) =>
|
||||||
|
stations.records.map((station: any) => ({
|
||||||
|
name: station._name,
|
||||||
|
description: station._opisanie,
|
||||||
|
address: station._adress,
|
||||||
|
workingHours: station._chasyRaboty?.name || null,
|
||||||
|
latitude: station._lat,
|
||||||
|
longitude: station._long,
|
||||||
|
carWash: station._avtomojka || false,
|
||||||
|
ai92: station._dtCopy || false,
|
||||||
|
ai95: station._ai92Copy || false,
|
||||||
|
z100: station._ai95Copy || false,
|
||||||
|
propan: station._z100Copy || false,
|
||||||
|
electricCharge: station._propanCopy || false,
|
||||||
|
miniMarket: station._zaryadnayaStanci || false,
|
||||||
|
toilet: station._miniMarketCop || false,
|
||||||
|
region: !isEmpty(station._region) ? station._region[0].name : null,
|
||||||
|
image: presentImage(station._foto),
|
||||||
|
}));
|
||||||
69
src/app/api-utlities/requests/common.ts
Normal file
69
src/app/api-utlities/requests/common.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
export const stationsRequest = {
|
||||||
|
_azs: {
|
||||||
|
records: {
|
||||||
|
_name: true,
|
||||||
|
_opisanie: true,
|
||||||
|
_adress: true,
|
||||||
|
_chasyRaboty: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
_lat: true,
|
||||||
|
_long: true,
|
||||||
|
_avtomojka: true,
|
||||||
|
_dtCopy: true, // ai92
|
||||||
|
_ai92Copy: true, // ai95
|
||||||
|
_ai95Copy: true, // z100
|
||||||
|
_z100Copy: true, // propan
|
||||||
|
_propanCopy: true, // electricCharge
|
||||||
|
_zaryadnayaStanci: true, // miniMarket
|
||||||
|
_miniMarketCop: true, // toilet
|
||||||
|
_region: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
_foto: {
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const partnersRequest = {
|
||||||
|
_partners: {
|
||||||
|
records: {
|
||||||
|
_name: true,
|
||||||
|
_image: {
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const jobsRequest = {
|
||||||
|
_vacancies: {
|
||||||
|
records: {
|
||||||
|
_name: true,
|
||||||
|
_tags: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
_type: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
_localtio: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const discountsRequest = {
|
||||||
|
_akcii: {
|
||||||
|
records: {
|
||||||
|
_name: true,
|
||||||
|
_opisanie: true,
|
||||||
|
_do: true,
|
||||||
|
_foto: {
|
||||||
|
url: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
13
src/app/api-utlities/requests/main-page.request.ts
Normal file
13
src/app/api-utlities/requests/main-page.request.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import {
|
||||||
|
discountsRequest,
|
||||||
|
jobsRequest,
|
||||||
|
partnersRequest,
|
||||||
|
stationsRequest,
|
||||||
|
} from './common';
|
||||||
|
|
||||||
|
export const mainPageRequest = {
|
||||||
|
...partnersRequest,
|
||||||
|
...jobsRequest,
|
||||||
|
...discountsRequest,
|
||||||
|
...stationsRequest,
|
||||||
|
};
|
||||||
25
src/app/api-utlities/utilities/taylor.client.ts
Normal file
25
src/app/api-utlities/utilities/taylor.client.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
|
||||||
|
|
||||||
|
export const requestTaylor = async (query: object, variables?: object) => {
|
||||||
|
const body = JSON.stringify({
|
||||||
|
query: jsonToGraphQLQuery({ query }),
|
||||||
|
variables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await fetch(process.env.TAYLOR_API_ENDPOINT || '', {
|
||||||
|
body,
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization: process.env.TAYLOR_API_TOKEN || '',
|
||||||
|
'Content-type': 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsedResponse = await response.json();
|
||||||
|
|
||||||
|
if (parsedResponse.errors) {
|
||||||
|
throw parsedResponse.errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedResponse;
|
||||||
|
};
|
||||||
24
src/app/api/pages/main/route.ts
Normal file
24
src/app/api/pages/main/route.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {
|
||||||
|
presentDiscounts,
|
||||||
|
presentJobs,
|
||||||
|
presentPartners,
|
||||||
|
presentStations,
|
||||||
|
} from '@/app/api-utlities/presenters';
|
||||||
|
import { mainPageRequest } from '@/app/api-utlities/requests/main-page.request';
|
||||||
|
import { requestTaylor } from '@/app/api-utlities/utilities/taylor.client';
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const response = await requestTaylor(mainPageRequest);
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
partners: presentPartners(response.data._partners),
|
||||||
|
jobs: presentJobs(response.data._vacancies),
|
||||||
|
discounts: presentDiscounts(response.data._akcii),
|
||||||
|
stations: presentStations(response.data._azs),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -18,7 +18,7 @@ export const Providers = ({ children }: ProvidersProps) => {
|
|||||||
<LanguageProvider>
|
<LanguageProvider>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
attribute='class'
|
attribute='class'
|
||||||
defaultTheme='system'
|
defaultTheme='light'
|
||||||
enableSystem
|
enableSystem
|
||||||
disableTransitionOnChange
|
disableTransitionOnChange
|
||||||
>
|
>
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
|
"types": ["node"],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "next"
|
"name": "next"
|
||||||
@ -28,5 +29,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"],
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user