Merge branch 'dev' of https://devgit.oriyo.tj/adilovcode/oriyo_next into feat-get-media

This commit is contained in:
Umar Adilov 2025-05-14 20:05:00 +05:00
commit a6d836a543
19 changed files with 292 additions and 225 deletions

View File

@ -7,10 +7,18 @@ RUN corepack enable && corepack prepare pnpm@latest --activate
ENV CI=true ENV CI=true
WORKDIR /app WORKDIR /app
# Copy package.json and pnpm-lock.yaml first for caching
COPY package.json pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install
# Copy the rest of the files
COPY . . COPY . .
# Install dependencies and build # Build the application
RUN pnpm install && pnpm build RUN pnpm build
FROM node:18-alpine AS runner FROM node:18-alpine AS runner

View File

@ -22,49 +22,49 @@ export interface Select {
} }
export type Discount = Root<{ export type Discount = Root<{
_name: string; zagolovok: string;
_opisanie: string; opisanie: string;
_do: string; do: string;
_foto: Image[]; foto: Image[];
}>; }>;
export type Job = Root<{ export type Job = Root<{
id: number; id: number;
_name: string; zagolovok: string;
_type: Select[]; tip: Select[];
_localtio: Select[]; lokaciya: Select[];
_tags: Select[]; tegi: Select[];
}>; }>;
export type Partner = Root<{ export type Partner = Root<{
id: number; id: number;
_name: string; nazvanie: string;
_image: Image[]; izobrozhenie: Image[];
}>; }>;
export type Station = Root<{ export type Station = Root<{
_name: string; imya: string;
_opisanie: string; opisanie: string;
_adress: string; adress: string;
_chasyRaboty: Select; chasyraboty: Select[];
_lat: number; lat: number;
_long: number; long: number;
_avtomojka: boolean; avtomojka: boolean;
_dtCopy: boolean; ai92: boolean;
_avtomojkaCopy: boolean; ai95: boolean;
_ai92Copy: boolean; z100: boolean;
_ai95Copy: boolean; propan: boolean;
_z100Copy: boolean; zaryadnayastanciya: boolean;
_propanCopy: boolean; dt: boolean;
_zaryadnayaStanci: boolean; minimarket: boolean;
_miniMarketCop: boolean; tualet: boolean;
_region: Select[]; region: Select[];
_foto: Image[]; foto: Image[];
}>; }>;
export type TextResponse = Root<{ export type TextResponse = Root<{
_name: string; klyuchneizmenyat: string;
_znachenie: string | null; znachenie: string | null;
}>; }>;
export type MediaResponse = Root<{ export type MediaResponse = Root<{
@ -74,38 +74,38 @@ export type MediaResponse = Root<{
}>; }>;
export type Team = Root<{ export type Team = Root<{
_foto: Image[]; foto: Image[];
_zvanie: string; zvanie: string;
_name: string; polnoeimya: string;
}>; }>;
export type History = Root<{ export type History = Root<{
_name: string; zagolovok: string;
_god: string; god: string;
_opisanie: string; opisanie: string;
}>; }>;
export type Review = Root<{ export type Review = Root<{
id: number; id: number;
_name: string; polnoeimya: string;
_otzyv: string; otzyv: string;
_rejting: number; rejting: number;
}>; }>;
export type Charity = Root<{ export type Charity = Root<{
_name: string; zagolovok: string;
_opisanie: string; opisanie: string;
_data: string; data: string;
_lokaciya: string; lokaciya: string;
_foto: Image[]; foto: Image[];
}>; }>;
export type Certificate = Root<{ export type Certificate = Root<{
_name: string; nazvanie: string;
_opisanie: string; opisanie: string;
_dataVydachi: string; datavydachi: string;
_dejstvitelenDo: string; dejstvitelenDo: string;
_foto: Image[]; foto: Image[];
}>; }>;
export type TeamMembers = ReturnType<typeof presentTeamMembers>; export type TeamMembers = ReturnType<typeof presentTeamMembers>;

View File

@ -12,6 +12,7 @@ export const requestTaylor = async (query: object, variables?: object) => {
headers: { headers: {
Authorization: process.env.TAYLOR_API_TOKEN || '', Authorization: process.env.TAYLOR_API_TOKEN || '',
'Content-type': 'application/json', 'Content-type': 'application/json',
schema: 'readable',
}, },
}); });

View File

@ -0,0 +1 @@
export class AuthorizationError extends Error {}

View File

@ -25,68 +25,68 @@ export const presentSelect = (selectItems: Select[]) =>
export const presentPartners = (partners: Partner) => export const presentPartners = (partners: Partner) =>
partners.records.map((record, index) => ({ partners.records.map((record, index) => ({
id: index + 1, id: index + 1,
name: record._name, name: record.nazvanie,
poster: presentImage(record._image), poster: presentImage(record.izobrozhenie),
})); }));
export const presentJobs = (jobs: Job) => export const presentJobs = (jobs: Job) =>
jobs.records.map((job, index) => ({ jobs.records.map((job, index) => ({
id: index + 1, id: index + 1,
name: job._name, name: job.zagolovok,
tags: job._tags.map((tag) => tag.name), tags: job.tegi.map((tag) => tag.name),
location: presentSelect(job._localtio), location: presentSelect(job.lokaciya),
type: presentSelect(job._type), type: presentSelect(job.tip),
})); }));
export const presentTeamMembers = (members: Team) => export const presentTeamMembers = (members: Team) =>
members.records.map((member) => ({ members.records.map((member) => ({
name: member._name, name: member.polnoeimya,
photo: presentImage(member._foto), photo: presentImage(member.foto),
profession: member._zvanie, profession: member.zvanie,
})); }));
export const presentHistoryItems = (historyItems: History) => export const presentHistoryItems = (historyItems: History) =>
historyItems.records.map((item) => ({ historyItems.records.map((item) => ({
name: item._name, name: item.zagolovok,
year: item._god, year: item.god,
description: item._opisanie, description: item.opisanie,
})); }));
export const presentDiscounts = (discounts: Discount) => export const presentDiscounts = (discounts: Discount) =>
discounts.records.map((discount, index) => ({ discounts.records.map((discount, index) => ({
id: index + 1, id: index + 1,
name: discount._name, name: discount.zagolovok,
description: discount._opisanie, description: discount.opisanie,
expiresAt: discount._do, expiresAt: discount.do,
image: presentImage(discount._foto), image: presentImage(discount.foto),
})); }));
export const presentStations = (stations: Station) => export const presentStations = (stations: Station) =>
stations.records.map((station, index) => ({ stations.records.map((station, index) => ({
id: index + 1, id: index + 1,
name: station._name, name: station.imya,
description: station._opisanie, description: station.opisanie,
address: station._adress, address: station.adress,
workingHours: station._chasyRaboty?.name || null, workingHours: presentSelect(station.chasyraboty),
latitude: station._lat, latitude: station.lat,
longitude: station._long, longitude: station.long,
carWash: station._avtomojka || false, carWash: station.avtomojka || false,
ai92: station._dtCopy || false, ai92: station.ai92 || false,
ai95: station._ai92Copy || false, ai95: station.ai95 || false,
dt: station._avtomojkaCopy || false, dt: station.dt || false,
z100: station._ai95Copy || false, z100: station.z100 || false,
propan: station._z100Copy || false, propan: station.propan || false,
electricCharge: station._propanCopy || false, electricCharge: station.zaryadnayastanciya || false,
miniMarket: station._zaryadnayaStanci || false, miniMarket: station.minimarket || false,
toilet: station._miniMarketCop || false, toilet: station.tualet || false,
region: presentSelect(station._region), region: presentSelect(station.region),
image: presentImage(station._foto), image: presentImage(station.foto),
})); }));
export const presentTexts = (texts: TextResponse) => export const presentTexts = (texts: TextResponse) =>
texts.records.map((item) => ({ texts.records.map((item) => ({
key: item._name, key: item.klyuchneizmenyat,
value: item._znachenie, value: item.znachenie,
})); }));
export const presentMedia = (media: MediaResponse) => { export const presentMedia = (media: MediaResponse) => {
@ -100,27 +100,27 @@ export const presentMedia = (media: MediaResponse) => {
export const presentReviews = (reviews: Review) => export const presentReviews = (reviews: Review) =>
reviews.records.map((review) => ({ reviews.records.map((review) => ({
id: review.id, id: review.id,
fullname: review._name, fullname: review.polnoeimya,
review: review._otzyv, review: review.otzyv,
rating: review._rejting, rating: review.rejting,
})); }));
export const presentCharities = (charities: Charity) => export const presentCharities = (charities: Charity) =>
charities.records.map((charity, index) => ({ charities.records.map((charity, index) => ({
id: index + 1, id: index + 1,
name: charity._name, name: charity.zagolovok,
description: charity._opisanie, description: charity.opisanie,
date: charity._data, date: charity.data,
location: charity._lokaciya, location: charity.lokaciya,
image: presentImage(charity._foto), image: presentImage(charity.foto),
})); }));
export const presentCertificates = (certificates: Certificate) => export const presentCertificates = (certificates: Certificate) =>
certificates.records.map((certificate, index) => ({ certificates.records.map((certificate, index) => ({
id: index + 1, id: index + 1,
name: certificate._name, name: certificate.nazvanie,
description: certificate._opisanie, description: certificate.opisanie,
issuedAt: certificate._dataVydachi, issuedAt: certificate.datavydachi,
validUntil: certificate._dejstvitelenDo, validUntil: certificate.dejstvitelenDo,
image: presentImage(certificate._foto), image: presentImage(certificate.foto),
})); }));

View File

@ -1,29 +1,29 @@
import { EnumType, VariableType } from 'json-to-graphql-query'; import { EnumType, VariableType } from 'json-to-graphql-query';
export const stationsRequest = { export const stationsRequest = {
_azs: { azs: {
records: { records: {
_name: true, imya: true,
_opisanie: true, opisanie: true,
_adress: true, adress: true,
_chasyRaboty: { chasyraboty: {
name: true, name: true,
}, },
_lat: true, lat: true,
_long: true, long: true,
_avtomojka: true, avtomojka: true,
_dtCopy: true, // ai92 ai92: true,
_ai92Copy: true, // ai95 ai95: true,
_ai95Copy: true, // z100 z100: true,
_z100Copy: true, // propan propan: true,
_propanCopy: true, // electricCharge zaryadnayastanciya: true,
_avtomojkaCopy: true, // DT dt: true,
_zaryadnayaStanci: true, // miniMarket minimarket: true,
_miniMarketCop: true, // toilet tualet: true,
_region: { region: {
name: true, name: true,
}, },
_foto: { foto: {
url: true, url: true,
}, },
}, },
@ -31,13 +31,13 @@ export const stationsRequest = {
}; };
export const stationsWithImageRequest = { export const stationsWithImageRequest = {
_azs: { azs: {
__args: { __args: {
filtersSet: { filtersSet: {
conjunction: new EnumType('and'), conjunction: new EnumType('and'),
filtersSet: [ filtersSet: [
{ {
field: new EnumType('_foto'), field: new EnumType('foto'),
operator: 'isNotEmpty', operator: 'isNotEmpty',
value: [], value: [],
}, },
@ -46,26 +46,27 @@ export const stationsWithImageRequest = {
}, },
records: { records: {
_name: true, imya: true,
_opisanie: true, opisanie: true,
_adress: true, adress: true,
_chasyRaboty: { chasyraboty: {
name: true, name: true,
}, },
_lat: true, lat: true,
_long: true, long: true,
_avtomojka: true, avtomojka: true,
_dtCopy: true, // ai92 ai92: true,
_ai92Copy: true, // ai95 ai95: true,
_ai95Copy: true, // z100 z100: true,
_z100Copy: true, // propan propan: true,
_propanCopy: true, // electricCharge zaryadnayastanciya: true,
_zaryadnayaStanci: true, // miniMarket dt: true,
_miniMarketCop: true, // toilet minimarket: true,
_region: { tualet: true,
region: {
name: true, name: true,
}, },
_foto: { foto: {
url: true, url: true,
}, },
}, },
@ -73,10 +74,10 @@ export const stationsWithImageRequest = {
}; };
export const partnersRequest = { export const partnersRequest = {
_partners: { partnyory: {
records: { records: {
_name: true, nazvanie: true,
_image: { izobrozhenie: {
url: true, url: true,
}, },
}, },
@ -84,16 +85,16 @@ export const partnersRequest = {
}; };
export const jobsRequest = { export const jobsRequest = {
_vacancies: { vakansii: {
records: { records: {
_name: true, zagolovok: true,
_tags: { tegi: {
name: true, name: true,
}, },
_type: { tip: {
name: true, name: true,
}, },
_localtio: { lokaciya: {
name: true, name: true,
}, },
}, },
@ -101,23 +102,23 @@ export const jobsRequest = {
}; };
export const discountsRequest = { export const discountsRequest = {
_akcii: { akcii: {
records: { records: {
_name: true, zagolovok: true,
_opisanie: true, opisanie: true,
_do: true, do: true,
_foto: { foto: {
url: true, name: true,
}, },
}, },
}, },
}; };
export const textsRequest = { export const textsRequest = {
_kontentSajta: { tekstovyjkontentsajta: {
records: { records: {
_name: true, znachenie: true,
_znachenie: true, klyuchneizmenyat: true,
}, },
}, },
}; };
@ -136,35 +137,35 @@ export const mediaRequest = {
}; };
export const teamRequest = { export const teamRequest = {
_komanda: { komanda: {
records: { records: {
_foto: { foto: {
url: true, url: true,
}, },
_zvanie: true, zvanie: true,
_name: true, polnoeimya: true,
}, },
}, },
}; };
export const historyRequest = { export const historyRequest = {
_istoriya: { istoriyakompanii: {
records: { records: {
_name: true, zagolovok: true,
_god: true, god: true,
_opisanie: true, opisanie: true,
}, },
}, },
}; };
export const reviewsRequest = { export const reviewsRequest = {
_otzyvy: { otzyvy: {
__args: { __args: {
filtersSet: { filtersSet: {
conjunction: new EnumType('and'), conjunction: new EnumType('and'),
filtersSet: [ filtersSet: [
{ {
field: new EnumType('_status'), field: new EnumType('status'),
operator: 'contains', operator: 'contains',
value: 'Опубликовано', value: 'Опубликовано',
}, },
@ -173,21 +174,21 @@ export const reviewsRequest = {
}, },
records: { records: {
id: true, id: true,
_name: true, polnoeimya: true,
_otzyv: true, otzyv: true,
_rejting: true, rejting: true,
}, },
}, },
}; };
export const charityRequest = { export const charityRequest = {
_blagotvoriteln: { blagotvoritelnyjfond: {
records: { records: {
_name: true, zagolovok: true,
_opisanie: true, opisanie: true,
_data: true, data: true,
_lokaciya: true, lokaciya: true,
_foto: { foto: {
url: true, url: true,
}, },
}, },
@ -195,13 +196,13 @@ export const charityRequest = {
}; };
export const certificatesRequest = { export const certificatesRequest = {
_sertifikaty: { sertifikaty: {
records: { records: {
_name: true, nazvanie: true,
_opisanie: true, opisanie: true,
_dataVydachi: true, datavydachi: true,
_dejstvitelenDo: true, dejstvitelendo: true,
_foto: { foto: {
url: true, url: true,
}, },
}, },
@ -212,7 +213,7 @@ export const createReviewMutation = {
__variables: { __variables: {
review: 'TableOtzyvyMutationParameters', review: 'TableOtzyvyMutationParameters',
}, },
_otzyvy: { otzyvy: {
createRecord: { createRecord: {
__args: { __args: {
records: [new VariableType('review')], records: [new VariableType('review')],

View File

@ -2,6 +2,7 @@ import { RequestCookie } from 'next/dist/compiled/@edge-runtime/cookies';
import { NextRequest } from 'next/server'; import { NextRequest } from 'next/server';
import oriyoClient from '@/app/api-utlities/clients/oriyo.client'; import oriyoClient from '@/app/api-utlities/clients/oriyo.client';
import { AuthorizationError } from '@/app/api-utlities/errors/authorization.error';
import { authorizationMiddleware } from '../../middlewares/auth.middleware'; import { authorizationMiddleware } from '../../middlewares/auth.middleware';
import { validationErrorHandler } from '../../middlewares/error-handler.middleware'; import { validationErrorHandler } from '../../middlewares/error-handler.middleware';
@ -16,6 +17,10 @@ const routeHandler = async (req: NextRequest, requestCookie: RequestCookie) => {
}, },
}); });
if (oriyoResponse.status === 401) {
throw new AuthorizationError();
}
return new Response(JSON.stringify(oriyoResponse.data), { return new Response(JSON.stringify(oriyoResponse.data), {
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
}); });

View File

@ -3,6 +3,7 @@ import { NextRequest } from 'next/server';
import { z } from 'zod'; import { z } from 'zod';
import oriyoClient from '@/app/api-utlities/clients/oriyo.client'; import oriyoClient from '@/app/api-utlities/clients/oriyo.client';
import { AuthorizationError } from '@/app/api-utlities/errors/authorization.error';
import { getParams } from '@/app/api-utlities/utilities/get-params'; import { getParams } from '@/app/api-utlities/utilities/get-params';
import { authorizationMiddleware } from '../../middlewares/auth.middleware'; import { authorizationMiddleware } from '../../middlewares/auth.middleware';
@ -34,6 +35,25 @@ const routeHandler = async (req: NextRequest, requestCookie: RequestCookie) => {
}, },
}); });
if (oriyoResponse.status === 404)
return new Response(
JSON.stringify({
transactions: [],
card_id,
current_page: validatedRequest.page,
limit: validatedRequest.limit,
total_records: 0,
total_pages: 0,
}),
{
headers: { 'Content-Type': 'application/json' },
},
);
if (oriyoResponse.status === 401) {
throw new AuthorizationError();
}
if (oriyoResponse.data.error) throw oriyoResponse.data; if (oriyoResponse.data.error) throw oriyoResponse.data;
return new Response(JSON.stringify(oriyoResponse.data), { return new Response(JSON.stringify(oriyoResponse.data), {

View File

@ -1,16 +1,15 @@
import { revalidateTag } from 'next/cache'; import { revalidatePath } from 'next/cache';
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import { FetchTags } from '@/shared/api/tags';
export async function GET() { export async function GET() {
try { try {
revalidateTag(FetchTags.TAYLOR); revalidatePath('/', 'layout');
revalidatePath('/', 'page');
return NextResponse.json({ success: true }); return NextResponse.json({ success: true });
} catch (err) { } catch (err) {
return NextResponse.json( return NextResponse.json(
{ error: 'Failed to revalidate', detail: err }, { error: 'Failed to drop cache', detail: err },
{ status: 500 }, { status: 500 },
); );
} }

View File

@ -3,6 +3,7 @@ import { NextRequest } from 'next/server';
import { z } from 'zod'; import { z } from 'zod';
import oriyoClient from '@/app/api-utlities/clients/oriyo.client'; import oriyoClient from '@/app/api-utlities/clients/oriyo.client';
import { AuthorizationError } from '@/app/api-utlities/errors/authorization.error';
import { getParams } from '@/app/api-utlities/utilities/get-params'; import { getParams } from '@/app/api-utlities/utilities/get-params';
import { authorizationMiddleware } from '../../middlewares/auth.middleware'; import { authorizationMiddleware } from '../../middlewares/auth.middleware';
@ -34,6 +35,24 @@ const routeHandler = async (req: NextRequest, requestCookie: RequestCookie) => {
}, },
}); });
if (oriyoResponse.status === 404)
return new Response(
JSON.stringify({
transactions: [],
current_page: validatedRequest.page,
limit: validatedRequest.limit,
total_records: 0,
total_pages: 0,
}),
{
headers: { 'Content-Type': 'application/json' },
},
);
if (oriyoResponse.status === 401) {
throw new AuthorizationError();
}
if (oriyoResponse.data.error) throw oriyoResponse.data; if (oriyoResponse.data.error) throw oriyoResponse.data;
return new Response(JSON.stringify(oriyoResponse.data), { return new Response(JSON.stringify(oriyoResponse.data), {

View File

@ -1,6 +1,7 @@
import { has } from 'lodash';
import { NextRequest, NextResponse } from 'next/server'; import { NextRequest, NextResponse } from 'next/server';
import { AuthorizationError } from '@/app/api-utlities/errors/authorization.error';
export const authorizationMiddleware = export const authorizationMiddleware =
(handler: Function, authorizationTokenKey: string) => (handler: Function, authorizationTokenKey: string) =>
async (req: NextRequest, ...args: any[]) => { async (req: NextRequest, ...args: any[]) => {
@ -16,7 +17,7 @@ export const authorizationMiddleware =
try { try {
return await handler(req, requestedToken, ...args); return await handler(req, requestedToken, ...args);
} catch (error) { } catch (error) {
if (has(error, 'code') && error.code === 401) { if (error instanceof AuthorizationError) {
const response = NextResponse.json( const response = NextResponse.json(
{ message: 'Authorization session was timed out' }, { message: 'Authorization session was timed out' },
{ status: 401 }, { status: 401 },

View File

@ -1,5 +1,4 @@
import { NextRequest } from 'next/server'; import { NextRequest } from 'next/server';
import { z } from 'zod';
import { requestTaylor } from '@/app/api-utlities/clients/taylor.client'; import { requestTaylor } from '@/app/api-utlities/clients/taylor.client';
import { createReviewMutation } from '@/app/api-utlities/requests/common'; import { createReviewMutation } from '@/app/api-utlities/requests/common';
@ -15,9 +14,9 @@ export const POST = async (req: NextRequest) => {
{ mutation: createReviewMutation }, { mutation: createReviewMutation },
{ {
review: { review: {
_name: validatedRequest.name, polnoeimya: validatedRequest.name,
_otzyv: validatedRequest.reviewMessage, otzyv: validatedRequest.reviewMessage,
_rejting: validatedRequest.rating, rejting: validatedRequest.rating,
}, },
}, },
); );

View File

@ -1,6 +1,5 @@
export interface TransactionResponse { export interface TransactionResponse {
transactions: Transaction[]; transactions: Transaction[];
card_id: string;
current_page: number; current_page: number;
limit: number; limit: number;
total_records: number; total_records: number;

View File

@ -37,10 +37,10 @@ export const mainPageApi = taylorAPI.injectEndpoints({
transformResponse: (response: any) => { transformResponse: (response: any) => {
return { return {
partners: presentPartners(response.data._partners), partners: presentPartners(response.data.partnyory),
jobs: presentJobs(response.data._vacancies), jobs: presentJobs(response.data.vakansii),
discounts: presentDiscounts(response.data._akcii), discounts: presentDiscounts(response.data.akcii),
stations: presentStations(response.data._azs), stations: presentStations(response.data.azs),
}; };
}, },
}), }),
@ -56,10 +56,10 @@ export const mainPageApi = taylorAPI.injectEndpoints({
transformResponse: (response: any) => { transformResponse: (response: any) => {
return { return {
team: presentTeamMembers(response.data._komanda), team: presentTeamMembers(response.data.komanda),
history: presentHistoryItems(response.data._istoriya), history: presentHistoryItems(response.data.istoriyakompanii),
stations: presentStations(response.data._azs), stations: presentStations(response.data.azs),
reviews: presentReviews(response.data._otzyvy), reviews: presentReviews(response.data.otzyvy),
}; };
}, },
}), }),
@ -75,7 +75,7 @@ export const mainPageApi = taylorAPI.injectEndpoints({
transformResponse: (response: any) => { transformResponse: (response: any) => {
return { return {
charities: presentCharities(response.data._blagotvoriteln), charities: presentCharities(response.data.blagotvoritelnyjfond),
}; };
}, },
}), }),
@ -91,7 +91,7 @@ export const mainPageApi = taylorAPI.injectEndpoints({
transformResponse: (response: any) => { transformResponse: (response: any) => {
return { return {
certificates: presentCertificates(response.data._sertifikaty), certificates: presentCertificates(response.data.sertifikaty),
}; };
}, },
}), }),

View File

@ -25,7 +25,7 @@ import { TransactionsTable } from '@/widgets/transactions-table';
export function CorporateDashboard() { export function CorporateDashboard() {
const { t } = useTextController(); const { t } = useTextController();
const { data, isLoading } = useFetchMyCorporateInfoQuery({}); const { data } = useFetchMyCorporateInfoQuery({});
const [request, setTransactionFetchRequest] = useState<TransactionRequest>({ const [request, setTransactionFetchRequest] = useState<TransactionRequest>({
limit: 10, limit: 10,
@ -159,12 +159,18 @@ export function CorporateDashboard() {
</Card> </Card>
</div> </div>
{transactionsResponse && (
<TransactionsTable <TransactionsTable
data={transactionsResponse} data={
transactionsResponse || {
limit: 10,
current_page: 1,
total_pages: 0,
total_records: 0,
transactions: [],
}
}
onChange={setTransactionFetchRequest} onChange={setTransactionFetchRequest}
/> />
)}
</div> </div>
</main> </main>
</div> </div>

View File

@ -148,12 +148,18 @@ export function CustomerDashboard() {
</Card> </Card>
</div> </div>
{transactionsResponse && (
<TransactionsTable <TransactionsTable
data={transactionsResponse} data={
transactionsResponse || {
limit: 10,
current_page: 1,
total_pages: 0,
total_records: 0,
transactions: [],
}
}
onChange={setTransactionFetchRequest} onChange={setTransactionFetchRequest}
/> />
)}
</div> </div>
</main> </main>
</div> </div>

View File

@ -6,6 +6,7 @@ const baseQuery = fetchBaseQuery({
baseUrl: process.env.TAYLOR_API_ENDPOINT, baseUrl: process.env.TAYLOR_API_ENDPOINT,
headers: { headers: {
Authorization: process.env.TAYLOR_API_TOKEN || '', Authorization: process.env.TAYLOR_API_TOKEN || '',
schema: 'readable',
}, },
next: { next: {
tags: [FetchTags.TAYLOR], tags: [FetchTags.TAYLOR],

View File

@ -18,7 +18,7 @@ export const textControlApi = taylorAPI.injectEndpoints({
}), }),
transformResponse: (response: any) => { transformResponse: (response: any) => {
return presentTexts(response.data._kontentSajta); return presentTexts(response.data.tekstovyjkontentsajta);
}, },
}), }),
}), }),

View File

@ -2,7 +2,7 @@
import { format } from 'date-fns'; import { format } from 'date-fns';
import { ru } from 'date-fns/locale'; import { ru } from 'date-fns/locale';
import { CalendarIcon } from 'lucide-react'; import { CalendarIcon, X } from 'lucide-react';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { import {
@ -46,8 +46,10 @@ export const TransactionsTable = ({
data, data,
onChange, onChange,
}: TransactionsTableProps) => { }: TransactionsTableProps) => {
const [startDate, setStartDate] = useState<Date | undefined>(undefined); const [startDate, setStartDate] = useState<Date | undefined>(
const [endDate, setEndDate] = useState<Date | undefined>(undefined); new Date(new Date().setMonth(new Date().getMonth() - 1)),
);
const [endDate, setEndDate] = useState<Date | undefined>(new Date());
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(10); const [itemsPerPage, setItemsPerPage] = useState(10);
@ -128,6 +130,9 @@ export const TransactionsTable = ({
initialFocus initialFocus
/> />
</PopoverContent> </PopoverContent>
<Button variant='ghost' onClick={() => setStartDate(undefined)}>
<X className='mr-2 h-4 w-4' />
</Button>
</Popover> </Popover>
</div> </div>
@ -155,16 +160,12 @@ export const TransactionsTable = ({
initialFocus initialFocus
/> />
</PopoverContent> </PopoverContent>
<Button variant='ghost' onClick={() => setEndDate(undefined)}>
<X className='mr-2 h-4 w-4' />
</Button>
</Popover> </Popover>
</div> </div>
</div> </div>
<Button
className='mt-auto bg-red-600 hover:bg-red-700'
onClick={filterTransactions}
>
{t('corporate.transactions.applyButton')}
</Button>
</div> </div>
</div> </div>
@ -204,10 +205,10 @@ export const TransactionsTable = ({
</TableCell> </TableCell>
<TableCell>{transaction.product_name}</TableCell> <TableCell>{transaction.product_name}</TableCell>
<TableCell className='text-right'> <TableCell className='text-right'>
{transaction.price_real} {transaction.amount}
</TableCell> </TableCell>
<TableCell className='text-right'> <TableCell className='text-right'>
{transaction.amount} {t('corporate.currency')} {transaction.price_real} {t('corporate.currency')}
</TableCell> </TableCell>
<TableCell className='text-right font-medium'> <TableCell className='text-right font-medium'>
{transaction.sum_real} {t('corporate.currency')} {transaction.sum_real} {t('corporate.currency')}