feat: Implement SAM structure mirroring in PostgreSQL for study plans and courses

- Added functionality to save study plans and courses in SAM format to PostgreSQL.
- Updated SQL queries to reflect SAM-native column names and handle conflicts appropriately.
- Introduced new fields in the Asset model for English level and SAM identifiers.
- Enhanced the TestTemplateForm component to manage linked assets and shared materials.
- Created a new AdminSharedMaterialsPage for uploading ZIP files of shared materials.
- Added migrations to create SAM mirror tables and update the assets table with new columns.
This commit is contained in:
2026-04-06 17:04:36 -04:00
parent eea456cd95
commit 7f9b9d69ae
12 changed files with 795 additions and 59 deletions
@@ -155,6 +155,13 @@ export default function TestTemplateManager({ onSelectTemplate, onCreateTemplate
return 'bg-gray-100 text-gray-800';
};
const getLinkedMaterialsCount = (template: TestTemplate): number => {
const data = template.template_data;
if (!data || typeof data !== 'object') return 0;
const selected = (data as Record<string, unknown>).selected_assets;
return Array.isArray(selected) ? selected.length : 0;
};
return (
<div className="p-6">
<div className="mb-6 flex items-center justify-between">
@@ -326,6 +333,10 @@ export default function TestTemplateManager({ onSelectTemplate, onCreateTemplate
<Tag className="w-4 h-4" />
<span>Puntos totales: {template.total_points}</span>
</div>
<div className="flex items-center gap-2 text-sm text-gray-600">
<BookOpen className="w-4 h-4" />
<span>Materiales vinculados: {getLinkedMaterialsCount(template)}</span>
</div>
</div>
{template.tags && template.tags.length > 0 && (
@@ -392,6 +403,10 @@ export default function TestTemplateManager({ onSelectTemplate, onCreateTemplate
<span className="text-blue-700">Aprobación:</span>
<span className="ml-2 font-medium">{selectedTemplate.passing_score}%</span>
</div>
<div className="col-span-2">
<span className="text-blue-700">Materiales vinculados:</span>
<span className="ml-2 font-medium">{getLinkedMaterialsCount(selectedTemplate)}</span>
</div>
</div>
</div>