roadmap-kit 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +1 -1
- package/dashboard/dist/assets/index-BDNWoUOj.js +521 -0
- package/dashboard/dist/assets/index-BHRTkw53.css +1 -0
- package/dashboard/dist/index.html +20 -0
- package/dashboard/dist/roadmap.json +268 -0
- package/dashboard/src/App.jsx +109 -45
- package/dashboard/src/components/SharedResources.jsx +16 -16
- package/dashboard/src/components/TechnicalDebt.jsx +14 -11
- package/dashboard/src/index.css +269 -0
- package/package.json +1 -1
package/dashboard/src/App.jsx
CHANGED
|
@@ -400,7 +400,7 @@ const translations = {
|
|
|
400
400
|
setup: 'SETUP',
|
|
401
401
|
features: 'FEATURES',
|
|
402
402
|
resources: 'RESOURCES',
|
|
403
|
-
debt: 'DEBT',
|
|
403
|
+
debt: 'TECH DEBT',
|
|
404
404
|
info: 'INFO',
|
|
405
405
|
settings: 'SETTINGS',
|
|
406
406
|
help: 'HELP'
|
|
@@ -514,7 +514,39 @@ const translations = {
|
|
|
514
514
|
effort: 'Effort',
|
|
515
515
|
source: 'Source',
|
|
516
516
|
bySeverity: 'BY SEVERITY',
|
|
517
|
-
items: 'items'
|
|
517
|
+
items: 'items',
|
|
518
|
+
// Severity levels
|
|
519
|
+
high: 'HIGH',
|
|
520
|
+
medium: 'MEDIUM',
|
|
521
|
+
low: 'LOW',
|
|
522
|
+
// Status
|
|
523
|
+
status: 'STATUS',
|
|
524
|
+
pending: 'PENDING',
|
|
525
|
+
inProgress: 'IN PROGRESS',
|
|
526
|
+
resolved: 'RESOLVED',
|
|
527
|
+
// Actions
|
|
528
|
+
filter: 'FILTER',
|
|
529
|
+
all: 'ALL',
|
|
530
|
+
clear: 'CLEAR',
|
|
531
|
+
addDebt: 'ADD DEBT',
|
|
532
|
+
addFirstDebt: 'ADD FIRST DEBT',
|
|
533
|
+
noMatch: 'NO ITEMS MATCH FILTERS',
|
|
534
|
+
// Details
|
|
535
|
+
description: 'DESCRIPTION',
|
|
536
|
+
impact: 'IMPACT',
|
|
537
|
+
solution: 'PROPOSED SOLUTION',
|
|
538
|
+
affectedFiles: 'AFFECTED FILES',
|
|
539
|
+
feature: 'FEATURE',
|
|
540
|
+
task: 'TASK',
|
|
541
|
+
priority: 'PRIORITY',
|
|
542
|
+
notEstimated: 'Not estimated',
|
|
543
|
+
// Dates
|
|
544
|
+
created: 'Created',
|
|
545
|
+
resolvedAt: 'Resolved',
|
|
546
|
+
assigned: 'Assigned',
|
|
547
|
+
due: 'Due',
|
|
548
|
+
// Schema
|
|
549
|
+
jsonSchema: 'JSON SCHEMA FOR TECHNICAL DEBT'
|
|
518
550
|
},
|
|
519
551
|
// Info
|
|
520
552
|
info: {
|
|
@@ -746,7 +778,7 @@ const translations = {
|
|
|
746
778
|
setup: 'ASISTENTE',
|
|
747
779
|
features: 'ESTADO',
|
|
748
780
|
resources: 'RECURSOS',
|
|
749
|
-
debt: 'DEUDA',
|
|
781
|
+
debt: 'DEUDA TÉCNICA',
|
|
750
782
|
info: 'INFO',
|
|
751
783
|
settings: 'CONFIG',
|
|
752
784
|
help: 'AYUDA'
|
|
@@ -860,7 +892,39 @@ const translations = {
|
|
|
860
892
|
effort: 'Esfuerzo',
|
|
861
893
|
source: 'Origen',
|
|
862
894
|
bySeverity: 'POR SEVERIDAD',
|
|
863
|
-
items: 'elementos'
|
|
895
|
+
items: 'elementos',
|
|
896
|
+
// Niveles de severidad
|
|
897
|
+
high: 'ALTA',
|
|
898
|
+
medium: 'MEDIA',
|
|
899
|
+
low: 'BAJA',
|
|
900
|
+
// Estado
|
|
901
|
+
status: 'ESTADO',
|
|
902
|
+
pending: 'PENDIENTE',
|
|
903
|
+
inProgress: 'EN PROGRESO',
|
|
904
|
+
resolved: 'RESUELTO',
|
|
905
|
+
// Acciones
|
|
906
|
+
filter: 'FILTRAR',
|
|
907
|
+
all: 'TODOS',
|
|
908
|
+
clear: 'LIMPIAR',
|
|
909
|
+
addDebt: 'AÑADIR DEUDA',
|
|
910
|
+
addFirstDebt: 'AÑADIR PRIMERA DEUDA',
|
|
911
|
+
noMatch: 'NINGÚN ELEMENTO COINCIDE CON LOS FILTROS',
|
|
912
|
+
// Detalles
|
|
913
|
+
description: 'DESCRIPCIÓN',
|
|
914
|
+
impact: 'IMPACTO',
|
|
915
|
+
solution: 'SOLUCIÓN PROPUESTA',
|
|
916
|
+
affectedFiles: 'ARCHIVOS AFECTADOS',
|
|
917
|
+
feature: 'CARACTERÍSTICA',
|
|
918
|
+
task: 'TAREA',
|
|
919
|
+
priority: 'PRIORIDAD',
|
|
920
|
+
notEstimated: 'Sin estimar',
|
|
921
|
+
// Fechas
|
|
922
|
+
created: 'Creado',
|
|
923
|
+
resolvedAt: 'Resuelto',
|
|
924
|
+
assigned: 'Asignado',
|
|
925
|
+
due: 'Vence',
|
|
926
|
+
// Schema
|
|
927
|
+
jsonSchema: 'ESQUEMA JSON PARA DEUDA TÉCNICA'
|
|
864
928
|
},
|
|
865
929
|
// Info
|
|
866
930
|
info: {
|
|
@@ -1938,7 +2002,7 @@ function App() {
|
|
|
1938
2002
|
)}
|
|
1939
2003
|
{activeTab === 'metrics' && <MetricsTab roadmap={roadmap} language={language} />}
|
|
1940
2004
|
{activeTab === 'resources' && <ResourcesTab resources={projectInfo.shared_resources || {}} />}
|
|
1941
|
-
{activeTab === 'debt' && <DebtTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} />}
|
|
2005
|
+
{activeTab === 'debt' && <DebtTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} t={t} />}
|
|
1942
2006
|
{activeTab === 'info' && <InfoTab projectInfo={projectInfo} />}
|
|
1943
2007
|
{activeTab === 'settings' && <SettingsTab roadmap={roadmap} setRoadmap={setRoadmap} setHasChanges={setHasChanges} authState={authState} showConfirm={showConfirm} showAlert={showAlert} t={t} language={language} changeLanguage={changeLanguage} />}
|
|
1944
2008
|
{activeTab === 'help' && <HelpTab t={t} language={language} />}
|
|
@@ -3448,7 +3512,7 @@ function ResourcesTab({ resources }) {
|
|
|
3448
3512
|
}
|
|
3449
3513
|
|
|
3450
3514
|
// ============ DEBT TAB ============
|
|
3451
|
-
function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
3515
|
+
function DebtTab({ roadmap, setRoadmap, setHasChanges, t }) {
|
|
3452
3516
|
const [expandedDebt, setExpandedDebt] = useState(null);
|
|
3453
3517
|
const [filterSeverity, setFilterSeverity] = useState('all');
|
|
3454
3518
|
const [filterStatus, setFilterStatus] = useState('all');
|
|
@@ -3492,9 +3556,9 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3492
3556
|
});
|
|
3493
3557
|
|
|
3494
3558
|
const statusConfig = {
|
|
3495
|
-
pending: { led: 'led-gray', label: '
|
|
3496
|
-
in_progress: { led: 'theme-led theme-led-warning', label: '
|
|
3497
|
-
resolved: { led: 'theme-led theme-led-success', label: '
|
|
3559
|
+
pending: { led: 'led-gray', label: t('debt.pending'), color: 'text-gray-500' },
|
|
3560
|
+
in_progress: { led: 'theme-led theme-led-warning', label: t('debt.inProgress'), color: 'text-signal' },
|
|
3561
|
+
resolved: { led: 'theme-led theme-led-success', label: t('debt.resolved'), color: 'text-matrix' }
|
|
3498
3562
|
};
|
|
3499
3563
|
|
|
3500
3564
|
// Update debt status
|
|
@@ -3578,7 +3642,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3578
3642
|
|
|
3579
3643
|
return (
|
|
3580
3644
|
<div className="space-y-6 animate-fade-in">
|
|
3581
|
-
{/*
|
|
3645
|
+
{/* Resumen */}
|
|
3582
3646
|
<div className="grid grid-cols-3 gap-4">
|
|
3583
3647
|
<button
|
|
3584
3648
|
onClick={() => setFilterSeverity(filterSeverity === 'high' ? 'all' : 'high')}
|
|
@@ -3586,7 +3650,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3586
3650
|
>
|
|
3587
3651
|
<div className="flex items-center gap-3 mb-3">
|
|
3588
3652
|
<div className="led theme-led theme-led-danger" />
|
|
3589
|
-
<span className="font-mono text-[10px] text-gray-500 tracking-wider">
|
|
3653
|
+
<span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.high')}</span>
|
|
3590
3654
|
</div>
|
|
3591
3655
|
<div className="metric-display text-3xl text-alert">{bySeverity.high.length}</div>
|
|
3592
3656
|
</button>
|
|
@@ -3596,7 +3660,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3596
3660
|
>
|
|
3597
3661
|
<div className="flex items-center gap-3 mb-3">
|
|
3598
3662
|
<div className="led theme-led theme-led-warning" />
|
|
3599
|
-
<span className="font-mono text-[10px] text-gray-500 tracking-wider">
|
|
3663
|
+
<span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.medium')}</span>
|
|
3600
3664
|
</div>
|
|
3601
3665
|
<div className="metric-display text-3xl text-signal">{bySeverity.medium.length}</div>
|
|
3602
3666
|
</button>
|
|
@@ -3606,42 +3670,42 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3606
3670
|
>
|
|
3607
3671
|
<div className="flex items-center gap-3 mb-3">
|
|
3608
3672
|
<div className="led theme-led theme-led-success" />
|
|
3609
|
-
<span className="font-mono text-[10px] text-gray-500 tracking-wider">
|
|
3673
|
+
<span className="font-mono text-[10px] text-gray-500 tracking-wider">{t('debt.low')}</span>
|
|
3610
3674
|
</div>
|
|
3611
3675
|
<div className="metric-display text-3xl text-cyber">{bySeverity.low.length}</div>
|
|
3612
3676
|
</button>
|
|
3613
3677
|
</div>
|
|
3614
3678
|
|
|
3615
|
-
{/*
|
|
3679
|
+
{/* Filtros y Botón Añadir */}
|
|
3616
3680
|
<div className="flex items-center gap-3 flex-wrap">
|
|
3617
|
-
<span className="font-mono text-[10px] text-gray-600">
|
|
3681
|
+
<span className="font-mono text-[10px] text-gray-600">{t('debt.filter')}:</span>
|
|
3618
3682
|
<select
|
|
3619
3683
|
value={filterStatus}
|
|
3620
3684
|
onChange={(e) => setFilterStatus(e.target.value)}
|
|
3621
3685
|
className="theme-input px-3 py-2 text-xs"
|
|
3622
3686
|
>
|
|
3623
|
-
<option value="all">
|
|
3624
|
-
<option value="pending">
|
|
3625
|
-
<option value="in_progress">
|
|
3626
|
-
<option value="resolved">
|
|
3687
|
+
<option value="all">{t('debt.all')}</option>
|
|
3688
|
+
<option value="pending">{t('debt.pending')}</option>
|
|
3689
|
+
<option value="in_progress">{t('debt.inProgress')}</option>
|
|
3690
|
+
<option value="resolved">{t('debt.resolved')}</option>
|
|
3627
3691
|
</select>
|
|
3628
3692
|
{(filterSeverity !== 'all' || filterStatus !== 'all') && (
|
|
3629
3693
|
<button
|
|
3630
3694
|
onClick={() => { setFilterSeverity('all'); setFilterStatus('all'); }}
|
|
3631
3695
|
className="font-mono text-[10px] text-gray-500 hover:text-white transition-all"
|
|
3632
3696
|
>
|
|
3633
|
-
|
|
3697
|
+
{t('debt.clear')}
|
|
3634
3698
|
</button>
|
|
3635
3699
|
)}
|
|
3636
3700
|
<span className="font-mono text-[10px] text-gray-600">
|
|
3637
|
-
{filteredDebts.length} / {allDebts.length} items
|
|
3701
|
+
{filteredDebts.length} / {allDebts.length} {t('debt.items')}
|
|
3638
3702
|
</span>
|
|
3639
3703
|
<button
|
|
3640
3704
|
onClick={() => setShowAddDebt(true)}
|
|
3641
3705
|
className="ml-auto theme-btn-primary flex items-center gap-2"
|
|
3642
3706
|
>
|
|
3643
3707
|
<Plus className="w-4 h-4" />
|
|
3644
|
-
|
|
3708
|
+
{t('debt.addDebt')}
|
|
3645
3709
|
</button>
|
|
3646
3710
|
</div>
|
|
3647
3711
|
|
|
@@ -3658,7 +3722,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3658
3722
|
{/* Debt Items */}
|
|
3659
3723
|
{filteredDebts.length > 0 ? (
|
|
3660
3724
|
<div className="theme-card p-5">
|
|
3661
|
-
<h3 className="font-mono text-sm text-signal tracking-wider mb-4">#
|
|
3725
|
+
<h3 className="font-mono text-sm text-signal tracking-wider mb-4"># {t('debt.title')}</h3>
|
|
3662
3726
|
<div className="space-y-2">
|
|
3663
3727
|
{filteredDebts.map((debt) => {
|
|
3664
3728
|
const isExpanded = expandedDebt === debt.id;
|
|
@@ -3707,9 +3771,9 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3707
3771
|
{/* Expanded Content */}
|
|
3708
3772
|
{isExpanded && !isEditing && (
|
|
3709
3773
|
<div className="px-4 pb-4 pt-2 border-t border-white/5 space-y-4 animate-fade-in">
|
|
3710
|
-
{/*
|
|
3774
|
+
{/* Controles de Estado */}
|
|
3711
3775
|
<div className="flex items-center gap-2 p-3 bg-black/30 border border-white/5">
|
|
3712
|
-
<span className="font-mono text-[10px] text-gray-600">
|
|
3776
|
+
<span className="font-mono text-[10px] text-gray-600">{t('debt.status')}:</span>
|
|
3713
3777
|
<div className="flex gap-1">
|
|
3714
3778
|
{['pending', 'in_progress', 'resolved'].map((s) => {
|
|
3715
3779
|
const cfg = statusConfig[s];
|
|
@@ -3746,36 +3810,36 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3746
3810
|
</div>
|
|
3747
3811
|
</div>
|
|
3748
3812
|
|
|
3749
|
-
{/*
|
|
3813
|
+
{/* Descripción Completa */}
|
|
3750
3814
|
<div>
|
|
3751
|
-
<h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2">#
|
|
3815
|
+
<h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># {t('debt.description')}</h5>
|
|
3752
3816
|
<p className="font-mono text-xs text-gray-400">{debt.description}</p>
|
|
3753
3817
|
</div>
|
|
3754
3818
|
|
|
3755
|
-
{/*
|
|
3819
|
+
{/* Impacto */}
|
|
3756
3820
|
{debt.impact && (
|
|
3757
3821
|
<div className="p-3 border border-alert/20 bg-alert/5">
|
|
3758
3822
|
<h5 className="font-mono text-[10px] text-alert tracking-wider mb-2 flex items-center gap-2">
|
|
3759
|
-
<AlertTriangle className="w-3 h-3" />
|
|
3823
|
+
<AlertTriangle className="w-3 h-3" /> {t('debt.impact')}
|
|
3760
3824
|
</h5>
|
|
3761
3825
|
<p className="font-mono text-xs text-gray-400">{debt.impact}</p>
|
|
3762
3826
|
</div>
|
|
3763
3827
|
)}
|
|
3764
3828
|
|
|
3765
|
-
{/*
|
|
3829
|
+
{/* Solución */}
|
|
3766
3830
|
{debt.solution && (
|
|
3767
3831
|
<div className="p-3 border border-matrix/20 bg-matrix/5">
|
|
3768
3832
|
<h5 className="font-mono text-[10px] text-matrix tracking-wider mb-2 flex items-center gap-2">
|
|
3769
|
-
<Wrench className="w-3 h-3" />
|
|
3833
|
+
<Wrench className="w-3 h-3" /> {t('debt.solution')}
|
|
3770
3834
|
</h5>
|
|
3771
3835
|
<p className="font-mono text-xs text-gray-400">{debt.solution}</p>
|
|
3772
3836
|
</div>
|
|
3773
3837
|
)}
|
|
3774
3838
|
|
|
3775
|
-
{/*
|
|
3839
|
+
{/* Archivos Afectados */}
|
|
3776
3840
|
{debt.affected_files && debt.affected_files.length > 0 && (
|
|
3777
3841
|
<div>
|
|
3778
|
-
<h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2">#
|
|
3842
|
+
<h5 className="font-mono text-[10px] text-gray-600 tracking-wider mb-2"># {t('debt.affectedFiles')}</h5>
|
|
3779
3843
|
<div className="flex flex-wrap gap-2">
|
|
3780
3844
|
{debt.affected_files.map((file, idx) => (
|
|
3781
3845
|
<code key={idx} className="font-mono text-[11px] px-2 py-1 bg-black/50 border border-white/10 text-cyber">
|
|
@@ -3789,19 +3853,19 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3789
3853
|
{/* Metadata Grid */}
|
|
3790
3854
|
<div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
|
|
3791
3855
|
<div className="bg-black/30 p-3 border border-white/5">
|
|
3792
|
-
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">
|
|
3856
|
+
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.feature')}</div>
|
|
3793
3857
|
<div className="font-mono text-xs text-white truncate">{debt.featureName}</div>
|
|
3794
3858
|
</div>
|
|
3795
3859
|
<div className="bg-black/30 p-3 border border-white/5">
|
|
3796
|
-
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">
|
|
3860
|
+
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.task')}</div>
|
|
3797
3861
|
<div className="font-mono text-xs text-white truncate">{debt.taskName}</div>
|
|
3798
3862
|
</div>
|
|
3799
3863
|
<div className="bg-black/30 p-3 border border-white/5">
|
|
3800
|
-
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">
|
|
3801
|
-
<div className="font-mono text-xs text-signal">{debt.estimated_effort || '
|
|
3864
|
+
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.effort')}</div>
|
|
3865
|
+
<div className="font-mono text-xs text-signal">{debt.estimated_effort || t('debt.notEstimated')}</div>
|
|
3802
3866
|
</div>
|
|
3803
3867
|
<div className="bg-black/30 p-3 border border-white/5">
|
|
3804
|
-
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">
|
|
3868
|
+
<div className="font-mono text-[9px] text-gray-600 tracking-wider mb-1">{t('debt.priority')}</div>
|
|
3805
3869
|
<div className={`font-mono text-xs ${
|
|
3806
3870
|
debt.priority === 'critical' ? 'text-alert' :
|
|
3807
3871
|
debt.priority === 'high' ? 'text-signal' :
|
|
@@ -3813,16 +3877,16 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3813
3877
|
{/* Additional Info */}
|
|
3814
3878
|
<div className="flex items-center gap-4 pt-3 border-t border-white/5 font-mono text-[10px] text-gray-600 flex-wrap">
|
|
3815
3879
|
{debt.created_at && (
|
|
3816
|
-
<span>
|
|
3880
|
+
<span>{t('debt.created')}: {new Date(debt.created_at).toLocaleDateString()}</span>
|
|
3817
3881
|
)}
|
|
3818
3882
|
{debt.resolved_at && (
|
|
3819
|
-
<span className="text-matrix">
|
|
3883
|
+
<span className="text-matrix">{t('debt.resolvedAt')}: {new Date(debt.resolved_at).toLocaleDateString()}</span>
|
|
3820
3884
|
)}
|
|
3821
3885
|
{debt.assigned_to && (
|
|
3822
|
-
<span className="text-signal">
|
|
3886
|
+
<span className="text-signal">{t('debt.assigned')}: @{debt.assigned_to}</span>
|
|
3823
3887
|
)}
|
|
3824
3888
|
{debt.due_date && (
|
|
3825
|
-
<span className="text-alert">
|
|
3889
|
+
<span className="text-alert">{t('debt.due')}: {new Date(debt.due_date).toLocaleDateString()}</span>
|
|
3826
3890
|
)}
|
|
3827
3891
|
</div>
|
|
3828
3892
|
|
|
@@ -3861,7 +3925,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3861
3925
|
<div className="theme-card p-12 text-center">
|
|
3862
3926
|
<CheckCircle2 className="w-10 h-10 mx-auto mb-4 text-matrix" />
|
|
3863
3927
|
<p className="font-mono text-sm text-gray-600">
|
|
3864
|
-
{allDebts.length === 0 ? '
|
|
3928
|
+
{allDebts.length === 0 ? t('debt.noDebt') : t('debt.noMatch')}
|
|
3865
3929
|
</p>
|
|
3866
3930
|
{allDebts.length === 0 && (
|
|
3867
3931
|
<button
|
|
@@ -3869,7 +3933,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3869
3933
|
className="theme-btn-primary mt-4 inline-flex items-center gap-2"
|
|
3870
3934
|
>
|
|
3871
3935
|
<Plus className="w-4 h-4" />
|
|
3872
|
-
|
|
3936
|
+
{t('debt.addFirstDebt')}
|
|
3873
3937
|
</button>
|
|
3874
3938
|
)}
|
|
3875
3939
|
</div>
|
|
@@ -3879,7 +3943,7 @@ function DebtTab({ roadmap, setRoadmap, setHasChanges }) {
|
|
|
3879
3943
|
<div className="theme-card p-4">
|
|
3880
3944
|
<details>
|
|
3881
3945
|
<summary className="font-mono text-[10px] text-gray-600 cursor-pointer hover:text-white">
|
|
3882
|
-
|
|
3946
|
+
{t('debt.jsonSchema')}
|
|
3883
3947
|
</summary>
|
|
3884
3948
|
<pre className="mt-4 p-4 bg-void-100 border border-white/5 font-mono text-[10px] text-gray-500 overflow-x-auto">
|
|
3885
3949
|
{`{
|
|
@@ -17,9 +17,9 @@ export default function SharedResources({ resources = {} }) {
|
|
|
17
17
|
if (total === 0) {
|
|
18
18
|
return (
|
|
19
19
|
<div className="card-dark rounded-2xl p-12 text-center">
|
|
20
|
-
<Package className="w-12 h-12 mx-auto mb-4 text-
|
|
21
|
-
<h3 className="text-lg font-semibold text-
|
|
22
|
-
<p className="text-
|
|
20
|
+
<Package className="w-12 h-12 mx-auto mb-4 text-theme-muted" />
|
|
21
|
+
<h3 className="text-lg font-semibold text-theme-secondary mb-2">Sin recursos compartidos</h3>
|
|
22
|
+
<p className="text-theme-muted text-sm">Agrega componentes en roadmap.json</p>
|
|
23
23
|
</div>
|
|
24
24
|
);
|
|
25
25
|
}
|
|
@@ -118,7 +118,7 @@ function StatCard({ icon: Icon, label, value, gradient }) {
|
|
|
118
118
|
<div className="card-dark rounded-2xl p-5 hover:scale-[1.02] transition-all">
|
|
119
119
|
<div className="flex items-center justify-between">
|
|
120
120
|
<div>
|
|
121
|
-
<p className="text-xs text-
|
|
121
|
+
<p className="text-xs text-theme-muted uppercase tracking-wider mb-1">{label}</p>
|
|
122
122
|
<p className={`text-3xl font-bold bg-gradient-to-r ${gradient} bg-clip-text text-transparent`}>{value}</p>
|
|
123
123
|
</div>
|
|
124
124
|
<div className={`w-12 h-12 rounded-xl bg-gradient-to-br ${gradient} flex items-center justify-center opacity-80`}>
|
|
@@ -146,9 +146,9 @@ function Section({ title, icon: Icon, color, isOpen, onToggle, children }) {
|
|
|
146
146
|
<Icon className={`w-5 h-5 ${colors[color]}`} />
|
|
147
147
|
<h3 className={`text-lg font-semibold ${colors[color]}`}>{title}</h3>
|
|
148
148
|
</div>
|
|
149
|
-
<ChevronDown className={`w-5 h-5 text-
|
|
149
|
+
<ChevronDown className={`w-5 h-5 text-theme-muted transition-transform ${isOpen ? 'rotate-180' : ''}`} />
|
|
150
150
|
</button>
|
|
151
|
-
{isOpen && <div className="px-6 pb-6 pt-2 border-t border-
|
|
151
|
+
{isOpen && <div className="px-6 pb-6 pt-2 border-t border-theme">{children}</div>}
|
|
152
152
|
</div>
|
|
153
153
|
);
|
|
154
154
|
}
|
|
@@ -169,16 +169,16 @@ function ResourceItem({ path, description, usage, exports, warning, color, copyI
|
|
|
169
169
|
<FileCode className={`w-4 h-4 flex-shrink-0 ${colors[color].split(' ')[0]}`} />
|
|
170
170
|
<div className="flex-1 min-w-0">
|
|
171
171
|
<code className={`text-sm ${colors[color].split(' ')[0]}`}>{path}</code>
|
|
172
|
-
<p className="text-xs text-
|
|
172
|
+
<p className="text-xs text-theme-muted truncate mt-0.5">{description}</p>
|
|
173
173
|
</div>
|
|
174
|
-
<ChevronDown className={`w-4 h-4 text-
|
|
174
|
+
<ChevronDown className={`w-4 h-4 text-theme-muted transition-transform ${open ? 'rotate-180' : ''}`} />
|
|
175
175
|
</button>
|
|
176
176
|
|
|
177
177
|
{open && (
|
|
178
|
-
<div className="px-4 pb-4 pt-2 border-t border-
|
|
178
|
+
<div className="px-4 pb-4 pt-2 border-t border-theme space-y-3 animate-fade-in">
|
|
179
179
|
{exports?.length > 0 && (
|
|
180
180
|
<div>
|
|
181
|
-
<span className="text-[10px] text-
|
|
181
|
+
<span className="text-[10px] text-theme-muted uppercase tracking-wider">Exports:</span>
|
|
182
182
|
<div className="flex flex-wrap gap-1.5 mt-1.5">
|
|
183
183
|
{exports.map((e, i) => (
|
|
184
184
|
<span key={i} className="px-2 py-1 text-xs bg-white/5 text-blue-400 rounded border border-blue-500/20">{e}</span>
|
|
@@ -189,12 +189,12 @@ function ResourceItem({ path, description, usage, exports, warning, color, copyI
|
|
|
189
189
|
{usage && (
|
|
190
190
|
<div>
|
|
191
191
|
<div className="flex items-center justify-between mb-1.5">
|
|
192
|
-
<span className="text-[10px] text-
|
|
192
|
+
<span className="text-[10px] text-theme-muted uppercase tracking-wider">Uso:</span>
|
|
193
193
|
<button onClick={() => onCopy(usage, copyId)} className="text-xs text-blue-400 hover:text-blue-300 flex items-center gap-1">
|
|
194
194
|
{copiedItem === copyId ? <><Check className="w-3 h-3" /> Copiado</> : <><Copy className="w-3 h-3" /> Copiar</>}
|
|
195
195
|
</button>
|
|
196
196
|
</div>
|
|
197
|
-
<div className="bg-white/5 rounded-lg p-3 border border-
|
|
197
|
+
<div className="bg-white/5 rounded-lg p-3 border border-theme">
|
|
198
198
|
<code className="text-sm text-blue-400">{usage}</code>
|
|
199
199
|
</div>
|
|
200
200
|
</div>
|
|
@@ -220,16 +220,16 @@ function TableCard({ table, copyId, copiedItem, onCopy }) {
|
|
|
220
220
|
<code className="text-base font-semibold text-emerald-400">{table.name}</code>
|
|
221
221
|
</div>
|
|
222
222
|
<button onClick={() => onCopy(table.name, copyId)} className="p-1.5 hover:bg-white/5 rounded-lg transition-colors">
|
|
223
|
-
{copiedItem === copyId ? <Check className="w-3.5 h-3.5 text-emerald-400" /> : <Copy className="w-3.5 h-3.5 text-
|
|
223
|
+
{copiedItem === copyId ? <Check className="w-3.5 h-3.5 text-emerald-400" /> : <Copy className="w-3.5 h-3.5 text-theme-muted" />}
|
|
224
224
|
</button>
|
|
225
225
|
</div>
|
|
226
|
-
<p className="text-sm text-
|
|
226
|
+
<p className="text-sm text-theme-secondary mb-3">{table.description}</p>
|
|
227
227
|
{table.fields?.length > 0 && (
|
|
228
228
|
<div>
|
|
229
|
-
<span className="text-[10px] text-
|
|
229
|
+
<span className="text-[10px] text-theme-muted uppercase tracking-wider">Campos:</span>
|
|
230
230
|
<div className="flex flex-wrap gap-1 mt-1.5">
|
|
231
231
|
{table.fields.map((f, i) => (
|
|
232
|
-
<span key={i} className="text-xs bg-white/5 px-2 py-1 rounded text-
|
|
232
|
+
<span key={i} className="text-xs bg-white/5 px-2 py-1 rounded text-theme-secondary border border-emerald-500/10">{f}</span>
|
|
233
233
|
))}
|
|
234
234
|
</div>
|
|
235
235
|
</div>
|
|
@@ -28,11 +28,11 @@ export default function TechnicalDebt({ roadmap = {} }) {
|
|
|
28
28
|
if (allDebts.length === 0) {
|
|
29
29
|
return (
|
|
30
30
|
<div className="card-dark rounded-2xl p-12 text-center">
|
|
31
|
-
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-
|
|
32
|
-
<TrendingDown className="w-8 h-8 text-
|
|
31
|
+
<div className="w-16 h-16 mx-auto mb-4 rounded-full bg-matrix/10 flex items-center justify-center">
|
|
32
|
+
<TrendingDown className="w-8 h-8 text-matrix" />
|
|
33
33
|
</div>
|
|
34
|
-
<h3 className="text-lg font-semibold text-
|
|
35
|
-
<p className="text-
|
|
34
|
+
<h3 className="text-lg font-semibold text-matrix mb-2">Sin deuda técnica</h3>
|
|
35
|
+
<p className="text-theme-secondary text-sm">No hay deuda técnica registrada</p>
|
|
36
36
|
</div>
|
|
37
37
|
);
|
|
38
38
|
}
|
|
@@ -49,7 +49,7 @@ export default function TechnicalDebt({ roadmap = {} }) {
|
|
|
49
49
|
|
|
50
50
|
{/* Distribution Bar */}
|
|
51
51
|
<div className="card-dark rounded-2xl p-6">
|
|
52
|
-
<h3 className="text-sm text-
|
|
52
|
+
<h3 className="text-sm text-theme-secondary uppercase tracking-wider mb-4">Distribución</h3>
|
|
53
53
|
<div className="flex h-4 rounded-full overflow-hidden bg-white/5">
|
|
54
54
|
{grouped.high.length > 0 && (
|
|
55
55
|
<div
|
|
@@ -92,7 +92,7 @@ function StatCard({ label, value, gradient, icon: Icon }) {
|
|
|
92
92
|
<div className="card-dark rounded-2xl p-5 hover:scale-[1.02] transition-all">
|
|
93
93
|
<div className="flex items-center justify-between">
|
|
94
94
|
<div>
|
|
95
|
-
<p className="text-xs text-
|
|
95
|
+
<p className="text-xs text-theme-muted uppercase tracking-wider mb-1">{label}</p>
|
|
96
96
|
<p className={`text-3xl font-bold bg-gradient-to-r ${gradient} bg-clip-text text-transparent`}>{value}</p>
|
|
97
97
|
</div>
|
|
98
98
|
<Icon className={`w-8 h-8 opacity-50 bg-gradient-to-r ${gradient} bg-clip-text`} style={{ color: 'currentColor' }} />
|
|
@@ -105,6 +105,7 @@ function DebtSection({ severity, debts }) {
|
|
|
105
105
|
const config = {
|
|
106
106
|
high: {
|
|
107
107
|
title: 'Severidad Alta',
|
|
108
|
+
label: 'Alta',
|
|
108
109
|
textColor: 'text-rose-400',
|
|
109
110
|
bgColor: 'bg-rose-500/5',
|
|
110
111
|
borderColor: 'border-rose-500/20',
|
|
@@ -112,6 +113,7 @@ function DebtSection({ severity, debts }) {
|
|
|
112
113
|
},
|
|
113
114
|
medium: {
|
|
114
115
|
title: 'Severidad Media',
|
|
116
|
+
label: 'Media',
|
|
115
117
|
textColor: 'text-amber-400',
|
|
116
118
|
bgColor: 'bg-amber-500/5',
|
|
117
119
|
borderColor: 'border-amber-500/20',
|
|
@@ -119,6 +121,7 @@ function DebtSection({ severity, debts }) {
|
|
|
119
121
|
},
|
|
120
122
|
low: {
|
|
121
123
|
title: 'Severidad Baja',
|
|
124
|
+
label: 'Baja',
|
|
122
125
|
textColor: 'text-cyan-400',
|
|
123
126
|
bgColor: 'bg-cyan-500/5',
|
|
124
127
|
borderColor: 'border-cyan-500/20',
|
|
@@ -149,17 +152,17 @@ function DebtSection({ severity, debts }) {
|
|
|
149
152
|
<AlertTriangle className={`w-5 h-5 ${cfg.textColor}`} />
|
|
150
153
|
</div>
|
|
151
154
|
<div className="flex-1 min-w-0">
|
|
152
|
-
<p className="text-
|
|
155
|
+
<p className="text-theme-primary font-medium mb-2">{debt.description}</p>
|
|
153
156
|
<div className="flex flex-wrap items-center gap-x-4 gap-y-2 text-sm">
|
|
154
|
-
<span className="text-
|
|
155
|
-
<span className="text-
|
|
156
|
-
<span className="flex items-center gap-1 text-
|
|
157
|
+
<span className="text-theme-muted">Característica: <span className="text-cyber">{debt.featureName}</span></span>
|
|
158
|
+
<span className="text-theme-muted">Tarea: <span className="text-cyber">{debt.taskName}</span></span>
|
|
159
|
+
<span className="flex items-center gap-1 text-theme-muted">
|
|
157
160
|
<Clock className="w-3.5 h-3.5" /> {debt.estimated_effort}
|
|
158
161
|
</span>
|
|
159
162
|
</div>
|
|
160
163
|
</div>
|
|
161
164
|
<span className={`flex-shrink-0 px-2.5 py-1 text-[10px] font-bold text-white rounded-full uppercase tracking-wider ${cfg.badgeBg}`}>
|
|
162
|
-
{
|
|
165
|
+
{cfg.label}
|
|
163
166
|
</span>
|
|
164
167
|
</div>
|
|
165
168
|
</div>
|