🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

View File

@@ -0,0 +1,11 @@
import { BaseExceptionFilterContext } from '@nestjs/core/exceptions/base-exception-filter-context';
import { NestContainer } from '@nestjs/core/injector/container';
import { WsExceptionsHandler } from '../exceptions/ws-exceptions-handler';
/**
* @publicApi
*/
export declare class ExceptionFiltersContext extends BaseExceptionFilterContext {
constructor(container: NestContainer);
create(instance: object, callback: <TClient>(client: TClient, data: any) => any, moduleKey: string): WsExceptionsHandler;
getGlobalMetadata<T extends any[]>(): T;
}

View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExceptionFiltersContext = void 0;
const constants_1 = require("@nestjs/common/constants");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const base_exception_filter_context_1 = require("@nestjs/core/exceptions/base-exception-filter-context");
const ws_exceptions_handler_1 = require("../exceptions/ws-exceptions-handler");
/**
* @publicApi
*/
class ExceptionFiltersContext extends base_exception_filter_context_1.BaseExceptionFilterContext {
constructor(container) {
super(container);
}
create(instance, callback, moduleKey) {
this.moduleContext = moduleKey;
const exceptionHandler = new ws_exceptions_handler_1.WsExceptionsHandler();
const filters = this.createContext(instance, callback, constants_1.EXCEPTION_FILTERS_METADATA);
if ((0, shared_utils_1.isEmpty)(filters)) {
return exceptionHandler;
}
exceptionHandler.setCustomFilters(filters.reverse());
return exceptionHandler;
}
getGlobalMetadata() {
return [];
}
}
exports.ExceptionFiltersContext = ExceptionFiltersContext;

View File

@@ -0,0 +1,48 @@
import { ContextType, Controller, PipeTransform } from '@nestjs/common/interfaces';
import { GuardsConsumer } from '@nestjs/core/guards/guards-consumer';
import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator';
import { ParamProperties } from '@nestjs/core/helpers/context-utils';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { ParamsMetadata } from '@nestjs/core/helpers/interfaces';
import { InterceptorsConsumer, InterceptorsContextCreator } from '@nestjs/core/interceptors';
import { PipesConsumer, PipesContextCreator } from '@nestjs/core/pipes';
import { WsParamsFactory } from '../factories/ws-params-factory';
import { ExceptionFiltersContext } from './exception-filters-context';
import { WsProxy } from './ws-proxy';
type WsParamProperties = ParamProperties & {
metatype?: any;
};
export interface WsHandlerMetadata {
argsLength: number;
paramtypes: any[];
getParamsMetadata: (moduleKey: string) => WsParamProperties[];
}
export declare class WsContextCreator {
private readonly wsProxy;
private readonly exceptionFiltersContext;
private readonly pipesContextCreator;
private readonly pipesConsumer;
private readonly guardsContextCreator;
private readonly guardsConsumer;
private readonly interceptorsContextCreator;
private readonly interceptorsConsumer;
private readonly contextUtils;
private readonly wsParamsFactory;
private readonly handlerMetadataStorage;
constructor(wsProxy: WsProxy, exceptionFiltersContext: ExceptionFiltersContext, pipesContextCreator: PipesContextCreator, pipesConsumer: PipesConsumer, guardsContextCreator: GuardsContextCreator, guardsConsumer: GuardsConsumer, interceptorsContextCreator: InterceptorsContextCreator, interceptorsConsumer: InterceptorsConsumer);
create<T extends ParamsMetadata = ParamsMetadata>(instance: Controller, callback: (...args: unknown[]) => void, moduleKey: string, methodName: string): (...args: any[]) => Promise<void>;
reflectCallbackParamtypes(instance: Controller, callback: (...args: any[]) => any): any[];
reflectCallbackPattern(callback: (...args: any[]) => any): string;
createGuardsFn<TContext extends string = ContextType>(guards: any[], instance: Controller, callback: (...args: unknown[]) => any, contextType?: TContext): Function | null;
getMetadata<TMetadata, TContext extends ContextType = ContextType>(instance: Controller, methodName: string, contextType: TContext): WsHandlerMetadata;
exchangeKeysForValues<TMetadata = any>(keys: string[], metadata: TMetadata, moduleContext: string, paramsFactory: WsParamsFactory, contextFactory: (args: unknown[]) => ExecutionContextHost): ParamProperties[];
createPipesFn(pipes: PipeTransform[], paramsOptions: (ParamProperties & {
metatype?: unknown;
})[]): (args: unknown[], ...params: unknown[]) => Promise<void>;
getParamValue<T>(value: T, { metatype, type, data }: {
metatype: any;
type: any;
data: any;
}, pipes: PipeTransform[]): Promise<any>;
}
export {};

View File

@@ -0,0 +1,122 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsContextCreator = void 0;
const constants_1 = require("@nestjs/common/constants");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const constants_2 = require("@nestjs/core/guards/constants");
const context_utils_1 = require("@nestjs/core/helpers/context-utils");
const handler_metadata_storage_1 = require("@nestjs/core/helpers/handler-metadata-storage");
const constants_3 = require("../constants");
const ws_exception_1 = require("../errors/ws-exception");
const ws_params_factory_1 = require("../factories/ws-params-factory");
const ws_metadata_constants_1 = require("./ws-metadata-constants");
class WsContextCreator {
constructor(wsProxy, exceptionFiltersContext, pipesContextCreator, pipesConsumer, guardsContextCreator, guardsConsumer, interceptorsContextCreator, interceptorsConsumer) {
this.wsProxy = wsProxy;
this.exceptionFiltersContext = exceptionFiltersContext;
this.pipesContextCreator = pipesContextCreator;
this.pipesConsumer = pipesConsumer;
this.guardsContextCreator = guardsContextCreator;
this.guardsConsumer = guardsConsumer;
this.interceptorsContextCreator = interceptorsContextCreator;
this.interceptorsConsumer = interceptorsConsumer;
this.contextUtils = new context_utils_1.ContextUtils();
this.wsParamsFactory = new ws_params_factory_1.WsParamsFactory();
this.handlerMetadataStorage = new handler_metadata_storage_1.HandlerMetadataStorage();
}
create(instance, callback, moduleKey, methodName) {
const contextType = 'ws';
const { argsLength, paramtypes, getParamsMetadata } = this.getMetadata(instance, methodName, contextType);
const exceptionHandler = this.exceptionFiltersContext.create(instance, callback, moduleKey);
const pipes = this.pipesContextCreator.create(instance, callback, moduleKey);
const guards = this.guardsContextCreator.create(instance, callback, moduleKey);
const interceptors = this.interceptorsContextCreator.create(instance, callback, moduleKey);
const paramsMetadata = getParamsMetadata(moduleKey);
const paramsOptions = paramsMetadata
? this.contextUtils.mergeParamsMetatypes(paramsMetadata, paramtypes)
: [];
const fnApplyPipes = this.createPipesFn(pipes, paramsOptions);
const fnCanActivate = this.createGuardsFn(guards, instance, callback, contextType);
const handler = (initialArgs, args) => async () => {
if (fnApplyPipes) {
await fnApplyPipes(initialArgs, ...args);
return callback.apply(instance, initialArgs);
}
return callback.apply(instance, args);
};
const targetPattern = this.reflectCallbackPattern(callback);
return this.wsProxy.create(async (...args) => {
args.push(targetPattern);
const initialArgs = this.contextUtils.createNullArray(argsLength);
fnCanActivate && (await fnCanActivate(args));
return this.interceptorsConsumer.intercept(interceptors, args, instance, callback, handler(initialArgs, args), contextType);
}, exceptionHandler, targetPattern);
}
reflectCallbackParamtypes(instance, callback) {
return Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, instance, callback.name);
}
reflectCallbackPattern(callback) {
return Reflect.getMetadata(constants_3.MESSAGE_METADATA, callback);
}
createGuardsFn(guards, instance, callback, contextType) {
const canActivateFn = async (args) => {
const canActivate = await this.guardsConsumer.tryActivate(guards, args, instance, callback, contextType);
if (!canActivate) {
throw new ws_exception_1.WsException(constants_2.FORBIDDEN_MESSAGE);
}
};
return guards.length ? canActivateFn : null;
}
getMetadata(instance, methodName, contextType) {
const cacheMetadata = this.handlerMetadataStorage.get(instance, methodName);
if (cacheMetadata) {
return cacheMetadata;
}
const metadata = this.contextUtils.reflectCallbackMetadata(instance, methodName, constants_3.PARAM_ARGS_METADATA) || ws_metadata_constants_1.DEFAULT_CALLBACK_METADATA;
const keys = Object.keys(metadata);
const argsLength = this.contextUtils.getArgumentsLength(keys, metadata);
const paramtypes = this.contextUtils.reflectCallbackParamtypes(instance, methodName);
const contextFactory = this.contextUtils.getContextFactory(contextType, instance, instance[methodName]);
const getParamsMetadata = (moduleKey) => this.exchangeKeysForValues(keys, metadata, moduleKey, this.wsParamsFactory, contextFactory);
const handlerMetadata = {
argsLength,
paramtypes,
getParamsMetadata,
};
this.handlerMetadataStorage.set(instance, methodName, handlerMetadata);
return handlerMetadata;
}
exchangeKeysForValues(keys, metadata, moduleContext, paramsFactory, contextFactory) {
this.pipesContextCreator.setModuleContext(moduleContext);
return keys.map(key => {
const { index, data, pipes: pipesCollection } = metadata[key];
const pipes = this.pipesContextCreator.createConcreteContext(pipesCollection);
const type = this.contextUtils.mapParamType(key);
if (key.includes(constants_1.CUSTOM_ROUTE_ARGS_METADATA)) {
const { factory } = metadata[key];
const customExtractValue = this.contextUtils.getCustomFactory(factory, data, contextFactory);
return { index, extractValue: customExtractValue, type, data, pipes };
}
const numericType = Number(type);
const extractValue = (...args) => paramsFactory.exchangeKeyForValue(numericType, data, args);
return { index, extractValue, type: numericType, data, pipes };
});
}
createPipesFn(pipes, paramsOptions) {
const pipesFn = async (args, ...params) => {
const resolveParamValue = async (param) => {
const { index, extractValue, type, data, metatype, pipes: paramPipes, } = param;
const value = extractValue(...params);
args[index] = await this.getParamValue(value, { metatype, type, data }, pipes.concat(paramPipes));
};
await Promise.all(paramsOptions.map(resolveParamValue));
};
return paramsOptions.length ? pipesFn : null;
}
async getParamValue(value, { metatype, type, data }, pipes) {
return (0, shared_utils_1.isEmpty)(pipes)
? value
: this.pipesConsumer.apply(value, { metatype, type, data }, pipes);
}
}
exports.WsContextCreator = WsContextCreator;

View File

@@ -0,0 +1,12 @@
export declare const DEFAULT_CALLBACK_METADATA: {
"3:1": {
index: number;
data: any;
pipes: any[];
};
"0:0": {
index: number;
data: any;
pipes: any[];
};
};

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_CALLBACK_METADATA = void 0;
const ws_paramtype_enum_1 = require("../enums/ws-paramtype.enum");
exports.DEFAULT_CALLBACK_METADATA = {
[`${ws_paramtype_enum_1.WsParamtype.PAYLOAD}:1`]: { index: 1, data: undefined, pipes: [] },
[`${ws_paramtype_enum_1.WsParamtype.SOCKET}:0`]: { index: 0, data: undefined, pipes: [] },
};

View File

@@ -0,0 +1,5 @@
import { WsExceptionsHandler } from '../exceptions/ws-exceptions-handler';
export declare class WsProxy {
create(targetCallback: (...args: unknown[]) => Promise<any>, exceptionsHandler: WsExceptionsHandler, targetPattern?: string): (...args: unknown[]) => Promise<any>;
handleError<T>(exceptionsHandler: WsExceptionsHandler, args: unknown[], error: T): void;
}

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WsProxy = void 0;
const execution_context_host_1 = require("@nestjs/core/helpers/execution-context-host");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
class WsProxy {
create(targetCallback, exceptionsHandler, targetPattern) {
return async (...args) => {
args = [...args, targetPattern ?? 'unknown'];
try {
const result = await targetCallback(...args);
return !(0, rxjs_1.isObservable)(result)
? result
: result.pipe((0, operators_1.catchError)(error => {
this.handleError(exceptionsHandler, args, error);
return rxjs_1.EMPTY;
}));
}
catch (error) {
this.handleError(exceptionsHandler, args, error);
}
};
}
handleError(exceptionsHandler, args, error) {
const host = new execution_context_host_1.ExecutionContextHost(args);
host.setType('ws');
exceptionsHandler.handle(error, host);
}
}
exports.WsProxy = WsProxy;