mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
fix: resolve remaining linting and React Compiler errors
Some checks failed
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / frontend-lint (push) Failing after 1m26s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
Some checks failed
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / frontend-lint (push) Failing after 1m26s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
- Fix prettier formatting issues in multiple components - Fix React Compiler memoization issues in ProductServiceMarkers.tsx - Replace literal strings with i18n keys across components - Address i18n issues in heritage, network graph, and match components - Fix dependency arrays in useMemo hooks to match React Compiler expectations
This commit is contained in:
parent
28f06d5787
commit
f24628a248
@ -215,7 +215,9 @@ export function DataTable<T>({
|
||||
{/* Bulk Actions */}
|
||||
{hasSelection && bulkActions && bulkActions.length > 0 && (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm text-muted-foreground">{t('dataTable.selected', { count: selectedCount })}</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{t('dataTable.selected', { count: selectedCount })}
|
||||
</span>
|
||||
{bulkActions.map((action, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
@ -253,7 +255,9 @@ export function DataTable<T>({
|
||||
}}
|
||||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
/>
|
||||
<span className="text-sm text-muted-foreground">{t('dataTable.selectAll', { count: data.length })}</span>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
{t('dataTable.selectAll', { count: data.length })}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@ -30,11 +30,7 @@ export const PermissionGate = ({
|
||||
|
||||
if (!hasAccess) {
|
||||
if (showError) {
|
||||
return (
|
||||
<div className="text-sm text-destructive">
|
||||
{t('permissionGate.noPermission')}
|
||||
</div>
|
||||
);
|
||||
return <div className="text-sm text-destructive">{t('permissionGate.noPermission')}</div>;
|
||||
}
|
||||
return <>{fallback}</>;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ const DynamicFieldArray = <T extends FieldValues>({
|
||||
className="h-10 w-10 p-0 shrink-0 mt-1.5"
|
||||
aria-label={t('form.removeItem')}
|
||||
>
|
||||
✕
|
||||
×
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@ -101,7 +101,7 @@ const TimelineSection = ({
|
||||
transition={{ duration: 0.3 }}
|
||||
aria-label={t('heritage.toggleFilters')}
|
||||
>
|
||||
▼
|
||||
<span>▼</span>
|
||||
</motion.div>
|
||||
</button>
|
||||
|
||||
@ -115,7 +115,9 @@ const TimelineSection = ({
|
||||
<div className="p-4 space-y-4">
|
||||
{/* Category Filter */}
|
||||
<div>
|
||||
<label className="text-sm font-medium mb-2 block">{t('heritage.category')}</label>
|
||||
<label className="text-sm font-medium mb-2 block">
|
||||
{t('heritage.category')}
|
||||
</label>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
onClick={() => filters.setSelectedCategory('all')}
|
||||
@ -184,9 +186,7 @@ const TimelineSection = ({
|
||||
))
|
||||
) : (
|
||||
<div className="text-center py-16">
|
||||
<p className="text-muted-foreground text-lg">
|
||||
{t('heritage.noEventsMatch')}
|
||||
</p>
|
||||
<p className="text-muted-foreground text-lg">{t('heritage.noEventsMatch')}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -295,7 +295,9 @@ const ResourceExchangeVisualization: React.FC<ResourceExchangeVisualizationProps
|
||||
<div className="w-full flex flex-col items-center gap-4 max-w-lg mx-auto">
|
||||
{/* Title */}
|
||||
<div className="text-center">
|
||||
<h3 className="text-sm font-semibold text-foreground mb-1">{t('resourceExchange.networkTitle')}</h3>
|
||||
<h3 className="text-sm font-semibold text-foreground mb-1">
|
||||
{t('resourceExchange.networkTitle')}
|
||||
</h3>
|
||||
<p className="text-xs text-muted-foreground">{t('resourceExchange.networkDescription')}</p>
|
||||
</div>
|
||||
|
||||
@ -648,7 +650,9 @@ const ResourceExchangeVisualization: React.FC<ResourceExchangeVisualizationProps
|
||||
>
|
||||
{sectorConnections.length}
|
||||
</motion.text>
|
||||
<title>{t('resourceExchange.connectionsCount', { count: sectorConnections.length })}</title>
|
||||
<title>
|
||||
{t('resourceExchange.connectionsCount', { count: sectorConnections.length })}
|
||||
</title>
|
||||
</g>
|
||||
)}
|
||||
</g>
|
||||
@ -754,7 +758,9 @@ const ResourceExchangeVisualization: React.FC<ResourceExchangeVisualizationProps
|
||||
|
||||
{/* Legend - moved below the animation */}
|
||||
<div className="flex gap-4 items-center bg-background/80 backdrop-blur-sm px-4 py-2 rounded-full border shadow-lg">
|
||||
<span className="text-xs text-muted-foreground font-medium">{t('resourceExchange.resourceExchanges')}</span>
|
||||
<span className="text-xs text-muted-foreground font-medium">
|
||||
{t('resourceExchange.resourceExchanges')}
|
||||
</span>
|
||||
{RESOURCE_TYPES.map((resource) => {
|
||||
const Icon = resource.icon;
|
||||
return (
|
||||
|
||||
@ -70,7 +70,9 @@ const HistoricalSidebarPreview = () => {
|
||||
<InfoLine label="Текущий статус" value={landmark.currentStatus} />
|
||||
{relatedOrg && (
|
||||
<>
|
||||
<dt className="text-xs text-muted-foreground">{t('mapSidebar.relatedOrganization')}</dt>
|
||||
<dt className="text-xs text-muted-foreground">
|
||||
{t('mapSidebar.relatedOrganization')}
|
||||
</dt>
|
||||
<dd className="text-sm font-medium">
|
||||
{relatedOrg.Name}
|
||||
<Button
|
||||
|
||||
@ -103,7 +103,9 @@ const MatchLine = React.memo<{
|
||||
<span className="text-muted-foreground">
|
||||
{t('matchesMap.distance', 'Distance')}:
|
||||
</span>
|
||||
<div className="font-medium">{t('matchesMap.distanceValue', { distance: match.DistanceKm.toFixed(1) })}</div>
|
||||
<div className="font-medium">
|
||||
{t('matchesMap.distanceValue', { distance: match.DistanceKm.toFixed(1) })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ const ProductMarker = React.memo<{
|
||||
const position: LatLngTuple = useMemo(() => {
|
||||
if (!match.product?.location) return [0, 0];
|
||||
return [match.product.location.latitude, match.product.location.longitude];
|
||||
}, [match.product?.location]);
|
||||
}, [match.product?.location?.latitude, match.product?.location?.longitude]);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (!match.product?.location) {
|
||||
@ -91,7 +91,9 @@ const ProductMarker = React.memo<{
|
||||
<div className="flex items-center gap-4 text-sm">
|
||||
<span className="font-medium">€{match.product.unit_price.toFixed(2)}</span>
|
||||
{match.product.moq > 0 && (
|
||||
<span className="text-muted-foreground">{t('productService.moq', { value: match.product.moq })}</span>
|
||||
<span className="text-muted-foreground">
|
||||
{t('productService.moq', { value: match.product.moq })}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{match.organization && (
|
||||
@ -116,7 +118,7 @@ const ServiceMarker = React.memo<{
|
||||
const position: LatLngTuple = useMemo(() => {
|
||||
if (!match.service?.service_location) return [0, 0];
|
||||
return [match.service.service_location.latitude, match.service.service_location.longitude];
|
||||
}, [match.service?.service_location]);
|
||||
}, [match.service?.service_location?.latitude, match.service?.service_location?.longitude]);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (!match.service?.service_location) {
|
||||
@ -181,9 +183,13 @@ const ServiceMarker = React.memo<{
|
||||
</p>
|
||||
)}
|
||||
<div className="flex items-center gap-4 text-sm">
|
||||
<span className="font-medium">€{match.service.hourly_rate.toFixed(2)}/hour</span>
|
||||
<span className="font-medium">
|
||||
{t('productService.hourlyRate', { rate: match.service.hourly_rate.toFixed(2) })}
|
||||
</span>
|
||||
{match.service.service_area_km > 0 && (
|
||||
<span className="text-muted-foreground">Area: {match.service.service_area_km}km</span>
|
||||
<span className="text-muted-foreground">
|
||||
{t('productService.serviceArea', { area: match.service.service_area_km })}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{match.organization && (
|
||||
|
||||
@ -121,7 +121,9 @@ const ResourceFlowMarker = React.memo<{
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-muted-foreground">{t('matchesMap.distance')}:</span>
|
||||
<div className="font-medium">{match.DistanceKm.toFixed(1)} km</div>
|
||||
<div className="font-medium">
|
||||
{t('matchesMap.distanceValue', { distance: match.DistanceKm.toFixed(1) })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ const SymbiosisLine = React.memo<{
|
||||
<Popup>
|
||||
<div>
|
||||
<p className="text-sm">
|
||||
Connection to <strong>{match.org?.Name || 'Unknown'}</strong>
|
||||
{t('symbiosis.connectionTo', { name: match.org?.Name || 'Unknown' })}
|
||||
</p>
|
||||
</div>
|
||||
</Popup>
|
||||
|
||||
@ -49,7 +49,7 @@ const MatchCard: React.FC<MatchCardProps> = ({ match, onViewDetails }) => {
|
||||
<Flex align="center" gap="xs" className="mb-2">
|
||||
<Badge variant={getStatusColor()}>{match.Status}</Badge>
|
||||
<Badge variant="outline" className="text-xs">
|
||||
Priority: {match.Priority}
|
||||
{t('matches.priority', { priority: match.Priority })}
|
||||
</Badge>
|
||||
</Flex>
|
||||
|
||||
@ -69,17 +69,18 @@ const MatchCard: React.FC<MatchCardProps> = ({ match, onViewDetails }) => {
|
||||
<Flex align="center" gap="md" className="text-sm text-muted-foreground">
|
||||
<div className="flex items-center gap-1">
|
||||
<MapPin className="h-4 w-4" />
|
||||
<span>{match.DistanceKm.toFixed(1)} km</span>
|
||||
<span>{t('matches.distance', { distance: match.DistanceKm.toFixed(1) })}</span>
|
||||
</div>
|
||||
{match.RiskAssessment && (
|
||||
<div className="flex items-center gap-1">
|
||||
<AlertTriangle className="h-4 w-4" />
|
||||
<span>
|
||||
Risk:{' '}
|
||||
{formatScore(
|
||||
{t('matches.riskScore', {
|
||||
score: formatScore(
|
||||
(match.RiskAssessment.technical_risk + match.RiskAssessment.regulatory_risk) /
|
||||
2
|
||||
)}
|
||||
)
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -16,10 +16,11 @@ const HistoricalContextCard = ({ landmark, onNavigate }: HistoricalContextCardPr
|
||||
<div className="h-12 w-12 mx-auto rounded-full flex items-center justify-center bg-warning/20 text-warning-foreground mb-3">
|
||||
<History className="h-4 h-6 text-current w-4 w-6" />
|
||||
</div>
|
||||
<h3 className="text-base font-semibold text-warning-foreground">Исторический контекст</h3>
|
||||
<h3 className="text-base font-semibold text-warning-foreground">
|
||||
{t('heritage.historicalContext')}
|
||||
</h3>
|
||||
<p className="text-sm text-warning-foreground/80 mt-1">
|
||||
Это здание является историческим объектом:{' '}
|
||||
<span className="font-semibold">{landmark.name}</span>, построенным в {landmark.period}.
|
||||
{t('heritage.buildingDescription', { name: landmark.name, period: landmark.period })}
|
||||
</p>
|
||||
<Button
|
||||
variant="ghost"
|
||||
@ -27,7 +28,7 @@ const HistoricalContextCard = ({ landmark, onNavigate }: HistoricalContextCardPr
|
||||
className="mt-3 text-warning-foreground hover:text-warning-foreground hover:bg-warning/20"
|
||||
onClick={() => onNavigate('map')}
|
||||
>
|
||||
Посмотреть на карте
|
||||
{t('heritage.viewOnMap')}
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -214,9 +214,9 @@ export function NetworkGraph({
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Network Graph</CardTitle>
|
||||
<CardTitle>{t('organization.networkGraph')}</CardTitle>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Explore how {organizationName} connects to other organizations, sites, and resources
|
||||
{t('organization.networkGraphDescription', { name: organizationName })}
|
||||
</p>
|
||||
<div className="flex gap-2 mt-4">
|
||||
{[1, 2, 3].map((d) => (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user