🎯 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,14 @@
import { Type } from '@nestjs/common/interfaces';
import { ExceptionFilter } from '@nestjs/common/interfaces/exceptions/exception-filter.interface';
import { ContextCreator } from '../helpers/context-creator';
import { NestContainer } from '../injector/container';
import { InstanceWrapper } from '../injector/instance-wrapper';
export declare class BaseExceptionFilterContext extends ContextCreator {
private readonly container;
protected moduleContext: string;
constructor(container: NestContainer);
createConcreteContext<T extends any[], R extends any[]>(metadata: T, contextId?: import("../injector/instance-wrapper").ContextId, inquirerId?: string): R;
getFilterInstance(filter: Function | ExceptionFilter, contextId?: import("../injector/instance-wrapper").ContextId, inquirerId?: string): ExceptionFilter | null;
getInstanceByMetatype(metatype: Type<unknown>): InstanceWrapper | undefined;
reflectCatchExceptions(instance: ExceptionFilter): Type<any>[];
}

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseExceptionFilterContext = void 0;
const constants_1 = require("@nestjs/common/constants");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const iterare_1 = require("iterare");
const context_creator_1 = require("../helpers/context-creator");
const constants_2 = require("../injector/constants");
class BaseExceptionFilterContext extends context_creator_1.ContextCreator {
constructor(container) {
super();
this.container = container;
}
createConcreteContext(metadata, contextId = constants_2.STATIC_CONTEXT, inquirerId) {
if ((0, shared_utils_1.isEmpty)(metadata)) {
return [];
}
return (0, iterare_1.iterate)(metadata)
.filter(instance => instance && ((0, shared_utils_1.isFunction)(instance.catch) || instance.name))
.map(filter => this.getFilterInstance(filter, contextId, inquirerId))
.filter(item => !!item)
.map(instance => ({
func: instance.catch.bind(instance),
exceptionMetatypes: this.reflectCatchExceptions(instance),
}))
.toArray();
}
getFilterInstance(filter, contextId = constants_2.STATIC_CONTEXT, inquirerId) {
const isObject = filter.catch;
if (isObject) {
return filter;
}
const instanceWrapper = this.getInstanceByMetatype(filter);
if (!instanceWrapper) {
return null;
}
const instanceHost = instanceWrapper.getInstanceByContextId(this.getContextId(contextId, instanceWrapper), inquirerId);
return instanceHost && instanceHost.instance;
}
getInstanceByMetatype(metatype) {
if (!this.moduleContext) {
return;
}
const collection = this.container.getModules();
const moduleRef = collection.get(this.moduleContext);
if (!moduleRef) {
return;
}
return moduleRef.injectables.get(metatype);
}
reflectCatchExceptions(instance) {
const prototype = Object.getPrototypeOf(instance);
return (Reflect.getMetadata(constants_1.FILTER_CATCH_EXCEPTIONS, prototype.constructor) || []);
}
}
exports.BaseExceptionFilterContext = BaseExceptionFilterContext;

View File

@@ -0,0 +1,20 @@
import { ArgumentsHost, ExceptionFilter, HttpServer } from '@nestjs/common';
import { AbstractHttpAdapter } from '../adapters';
import { HttpAdapterHost } from '../helpers/http-adapter-host';
export declare class BaseExceptionFilter<T = any> implements ExceptionFilter<T> {
protected readonly applicationRef?: HttpServer;
private static readonly logger;
protected readonly httpAdapterHost?: HttpAdapterHost;
constructor(applicationRef?: HttpServer);
catch(exception: T, host: ArgumentsHost): void;
handleUnknownError(exception: T, host: ArgumentsHost, applicationRef: AbstractHttpAdapter | HttpServer): void;
isExceptionObject(err: any): err is Error;
/**
* Checks if the thrown error comes from the "http-errors" library.
* @param err error object
*/
isHttpError(err: any): err is {
statusCode: number;
message: string;
};
}

View File

@@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseExceptionFilter = void 0;
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const constants_1 = require("../constants");
const http_adapter_host_1 = require("../helpers/http-adapter-host");
class BaseExceptionFilter {
constructor(applicationRef) {
this.applicationRef = applicationRef;
}
catch(exception, host) {
const applicationRef = this.applicationRef ||
(this.httpAdapterHost && this.httpAdapterHost.httpAdapter);
if (!(exception instanceof common_1.HttpException)) {
return this.handleUnknownError(exception, host, applicationRef);
}
const res = exception.getResponse();
const message = (0, shared_utils_1.isObject)(res)
? res
: {
statusCode: exception.getStatus(),
message: res,
};
const response = host.getArgByIndex(1);
if (!applicationRef.isHeadersSent(response)) {
applicationRef.reply(response, message, exception.getStatus());
}
else {
applicationRef.end(response);
}
}
handleUnknownError(exception, host, applicationRef) {
const body = this.isHttpError(exception)
? {
statusCode: exception.statusCode,
message: exception.message,
}
: {
statusCode: common_1.HttpStatus.INTERNAL_SERVER_ERROR,
message: constants_1.MESSAGES.UNKNOWN_EXCEPTION_MESSAGE,
};
const response = host.getArgByIndex(1);
if (!applicationRef.isHeadersSent(response)) {
applicationRef.reply(response, body, body.statusCode);
}
else {
applicationRef.end(response);
}
if (this.isExceptionObject(exception)) {
return BaseExceptionFilter.logger.error(exception.message, exception.stack);
}
return BaseExceptionFilter.logger.error(exception);
}
isExceptionObject(err) {
return (0, shared_utils_1.isObject)(err) && !!err.message;
}
/**
* Checks if the thrown error comes from the "http-errors" library.
* @param err error object
*/
isHttpError(err) {
return err?.statusCode && err?.message;
}
}
exports.BaseExceptionFilter = BaseExceptionFilter;
BaseExceptionFilter.logger = new common_1.Logger('ExceptionsHandler');
tslib_1.__decorate([
(0, common_1.Optional)(),
(0, common_1.Inject)(),
tslib_1.__metadata("design:type", http_adapter_host_1.HttpAdapterHost)
], BaseExceptionFilter.prototype, "httpAdapterHost", void 0);

View File

@@ -0,0 +1,10 @@
import { HttpException } from '@nestjs/common';
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface';
import { BaseExceptionFilter } from './base-exception-filter';
export declare class ExceptionsHandler extends BaseExceptionFilter {
private filters;
next(exception: Error | HttpException | any, ctx: ArgumentsHost): void;
setCustomFilters(filters: ExceptionFilterMetadata[]): void;
invokeCustomFilters<T = any>(exception: T, ctx: ArgumentsHost): boolean;
}

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExceptionsHandler = void 0;
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const select_exception_filter_metadata_util_1 = require("@nestjs/common/utils/select-exception-filter-metadata.util");
const base_exception_filter_1 = require("./base-exception-filter");
const invalid_exception_filter_exception_1 = require("../errors/exceptions/invalid-exception-filter.exception");
class ExceptionsHandler extends base_exception_filter_1.BaseExceptionFilter {
constructor() {
super(...arguments);
this.filters = [];
}
next(exception, ctx) {
if (this.invokeCustomFilters(exception, ctx)) {
return;
}
super.catch(exception, ctx);
}
setCustomFilters(filters) {
if (!Array.isArray(filters)) {
throw new invalid_exception_filter_exception_1.InvalidExceptionFilterException();
}
this.filters = filters;
}
invokeCustomFilters(exception, ctx) {
if ((0, shared_utils_1.isEmpty)(this.filters)) {
return false;
}
const filter = (0, select_exception_filter_metadata_util_1.selectExceptionFilterMetadata)(this.filters, exception);
filter && filter.func(exception, ctx);
return !!filter;
}
}
exports.ExceptionsHandler = ExceptionsHandler;

View File

@@ -0,0 +1,12 @@
import { Controller } from '@nestjs/common/interfaces';
import { ApplicationConfig } from '../application-config';
import { NestContainer } from '../injector/container';
import { RouterProxyCallback } from '../router/router-proxy';
import { BaseExceptionFilterContext } from './base-exception-filter-context';
import { ExternalExceptionsHandler } from './external-exceptions-handler';
export declare class ExternalExceptionFilterContext extends BaseExceptionFilterContext {
private readonly config?;
constructor(container: NestContainer, config?: ApplicationConfig);
create(instance: Controller, callback: RouterProxyCallback, module: string, contextId?: import("../injector/instance-wrapper").ContextId, inquirerId?: string): ExternalExceptionsHandler;
getGlobalMetadata<T extends any[]>(contextId?: import("../injector/instance-wrapper").ContextId, inquirerId?: string): T;
}

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExternalExceptionFilterContext = void 0;
const constants_1 = require("@nestjs/common/constants");
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const constants_2 = require("../injector/constants");
const base_exception_filter_context_1 = require("./base-exception-filter-context");
const external_exceptions_handler_1 = require("./external-exceptions-handler");
const iterare_1 = require("iterare");
class ExternalExceptionFilterContext extends base_exception_filter_context_1.BaseExceptionFilterContext {
constructor(container, config) {
super(container);
this.config = config;
}
create(instance, callback, module, contextId = constants_2.STATIC_CONTEXT, inquirerId) {
this.moduleContext = module;
const exceptionHandler = new external_exceptions_handler_1.ExternalExceptionsHandler();
const filters = this.createContext(instance, callback, constants_1.EXCEPTION_FILTERS_METADATA, contextId, inquirerId);
if ((0, shared_utils_1.isEmpty)(filters)) {
return exceptionHandler;
}
exceptionHandler.setCustomFilters(filters.reverse());
return exceptionHandler;
}
getGlobalMetadata(contextId = constants_2.STATIC_CONTEXT, inquirerId) {
if (!this.config) {
return [];
}
const globalFilters = this.config.getGlobalFilters();
if (contextId === constants_2.STATIC_CONTEXT && !inquirerId) {
return globalFilters;
}
const scopedFilterWrappers = this.config.getGlobalRequestFilters();
const scopedFilters = (0, iterare_1.iterate)(scopedFilterWrappers)
.map(wrapper => wrapper.getInstanceByContextId(contextId, inquirerId))
.filter(host => !!host)
.map(host => host.instance)
.toArray();
return globalFilters.concat(scopedFilters);
}
}
exports.ExternalExceptionFilterContext = ExternalExceptionFilterContext;

View File

@@ -0,0 +1,5 @@
import { ArgumentsHost } from '@nestjs/common';
export declare class ExternalExceptionFilter<T = any, R = any> {
private static readonly logger;
catch(exception: T, host: ArgumentsHost): R | Promise<R>;
}

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExternalExceptionFilter = void 0;
const common_1 = require("@nestjs/common");
class ExternalExceptionFilter {
catch(exception, host) {
if (exception instanceof Error && !(exception instanceof common_1.HttpException)) {
ExternalExceptionFilter.logger.error(exception.message, exception.stack);
}
throw exception;
}
}
exports.ExternalExceptionFilter = ExternalExceptionFilter;
ExternalExceptionFilter.logger = new common_1.Logger('ExceptionsHandler');

View File

@@ -0,0 +1,9 @@
import { ArgumentsHost } from '@nestjs/common/interfaces/features/arguments-host.interface';
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions';
import { ExternalExceptionFilter } from './external-exception-filter';
export declare class ExternalExceptionsHandler extends ExternalExceptionFilter {
private filters;
next(exception: Error | any, host: ArgumentsHost): Promise<any>;
setCustomFilters(filters: ExceptionFilterMetadata[]): void;
invokeCustomFilters<T = any>(exception: T, host: ArgumentsHost): Promise<any> | null;
}

View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExternalExceptionsHandler = void 0;
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
const select_exception_filter_metadata_util_1 = require("@nestjs/common/utils/select-exception-filter-metadata.util");
const external_exception_filter_1 = require("./external-exception-filter");
const invalid_exception_filter_exception_1 = require("../errors/exceptions/invalid-exception-filter.exception");
class ExternalExceptionsHandler extends external_exception_filter_1.ExternalExceptionFilter {
constructor() {
super(...arguments);
this.filters = [];
}
next(exception, host) {
const result = this.invokeCustomFilters(exception, host);
if (result) {
return result;
}
return super.catch(exception, host);
}
setCustomFilters(filters) {
if (!Array.isArray(filters)) {
throw new invalid_exception_filter_exception_1.InvalidExceptionFilterException();
}
this.filters = filters;
}
invokeCustomFilters(exception, host) {
if ((0, shared_utils_1.isEmpty)(this.filters)) {
return null;
}
const filter = (0, select_exception_filter_metadata_util_1.selectExceptionFilterMetadata)(this.filters, exception);
return filter ? filter.func(exception, host) : null;
}
}
exports.ExternalExceptionsHandler = ExternalExceptionsHandler;

View File

@@ -0,0 +1 @@
export * from './base-exception-filter';

View File

@@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./base-exception-filter"), exports);