@mtldev514/retro-portfolio-engine 1.0.0

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.
Files changed (43) hide show
  1. package/README.md +408 -0
  2. package/bin/cli.js +103 -0
  3. package/engine/admin/admin.css +720 -0
  4. package/engine/admin/admin.html +801 -0
  5. package/engine/admin/admin_api.py +230 -0
  6. package/engine/admin/scripts/backup.sh +116 -0
  7. package/engine/admin/scripts/config_loader.py +180 -0
  8. package/engine/admin/scripts/init.sh +141 -0
  9. package/engine/admin/scripts/manager.py +308 -0
  10. package/engine/admin/scripts/restore.sh +121 -0
  11. package/engine/admin/scripts/server.py +41 -0
  12. package/engine/admin/scripts/update.sh +321 -0
  13. package/engine/admin/scripts/validate_json.py +62 -0
  14. package/engine/fonts.css +37 -0
  15. package/engine/index.html +190 -0
  16. package/engine/js/config-loader.js +370 -0
  17. package/engine/js/config.js +173 -0
  18. package/engine/js/counter.js +17 -0
  19. package/engine/js/effects.js +97 -0
  20. package/engine/js/i18n.js +68 -0
  21. package/engine/js/init.js +107 -0
  22. package/engine/js/media.js +264 -0
  23. package/engine/js/render.js +282 -0
  24. package/engine/js/router.js +133 -0
  25. package/engine/js/sparkle.js +123 -0
  26. package/engine/js/themes.js +607 -0
  27. package/engine/style.css +2037 -0
  28. package/index.js +35 -0
  29. package/package.json +48 -0
  30. package/scripts/admin.js +67 -0
  31. package/scripts/build.js +142 -0
  32. package/scripts/init.js +237 -0
  33. package/scripts/post-install.js +16 -0
  34. package/scripts/serve.js +54 -0
  35. package/templates/user-portfolio/.github/workflows/deploy.yml +57 -0
  36. package/templates/user-portfolio/config/app.json +36 -0
  37. package/templates/user-portfolio/config/categories.json +241 -0
  38. package/templates/user-portfolio/config/languages.json +15 -0
  39. package/templates/user-portfolio/config/media-types.json +59 -0
  40. package/templates/user-portfolio/data/painting.json +3 -0
  41. package/templates/user-portfolio/data/projects.json +3 -0
  42. package/templates/user-portfolio/lang/en.json +114 -0
  43. package/templates/user-portfolio/lang/fr.json +114 -0
@@ -0,0 +1,241 @@
1
+ {
2
+ "contentTypes": [
3
+ {
4
+ "id": "painting",
5
+ "name": "Painting",
6
+ "icon": "🎨",
7
+ "mediaType": "image",
8
+ "dataFile": "data/painting.json",
9
+ "description": "Traditional paintings using various media",
10
+ "fields": {
11
+ "required": ["title", "url"],
12
+ "optional": [
13
+ {
14
+ "name": "medium",
15
+ "type": "text",
16
+ "label": "Medium",
17
+ "placeholder": "e.g., Oil on canvas, Acrylic, Watercolor"
18
+ },
19
+ {
20
+ "name": "dimensions",
21
+ "type": "text",
22
+ "label": "Dimensions",
23
+ "placeholder": "e.g., 24x36 inches"
24
+ },
25
+ {
26
+ "name": "year",
27
+ "type": "text",
28
+ "label": "Year",
29
+ "placeholder": "e.g., 2024"
30
+ },
31
+ {
32
+ "name": "description",
33
+ "type": "textarea",
34
+ "label": "Description"
35
+ },
36
+ {
37
+ "name": "date",
38
+ "type": "text",
39
+ "label": "Date"
40
+ }
41
+ ]
42
+ }
43
+ },
44
+ {
45
+ "id": "drawing",
46
+ "name": "Drawing",
47
+ "icon": "✏️",
48
+ "mediaType": "image",
49
+ "dataFile": "data/drawing.json",
50
+ "description": "Hand-drawn artwork and sketches",
51
+ "fields": {
52
+ "required": ["title", "url"],
53
+ "optional": [
54
+ {
55
+ "name": "medium",
56
+ "type": "text",
57
+ "label": "Medium",
58
+ "placeholder": "e.g., Pencil, Charcoal, Ink"
59
+ },
60
+ {
61
+ "name": "dimensions",
62
+ "type": "text",
63
+ "label": "Dimensions"
64
+ },
65
+ {
66
+ "name": "description",
67
+ "type": "textarea",
68
+ "label": "Description"
69
+ },
70
+ {
71
+ "name": "date",
72
+ "type": "text",
73
+ "label": "Date"
74
+ }
75
+ ]
76
+ }
77
+ },
78
+ {
79
+ "id": "photography",
80
+ "name": "Photography",
81
+ "icon": "đź“·",
82
+ "mediaType": "image",
83
+ "dataFile": "data/photography.json",
84
+ "description": "Photographic works",
85
+ "fields": {
86
+ "required": ["title", "url"],
87
+ "optional": [
88
+ {
89
+ "name": "camera",
90
+ "type": "text",
91
+ "label": "Camera",
92
+ "placeholder": "e.g., Canon EOS R5"
93
+ },
94
+ {
95
+ "name": "lens",
96
+ "type": "text",
97
+ "label": "Lens",
98
+ "placeholder": "e.g., 50mm f/1.8"
99
+ },
100
+ {
101
+ "name": "settings",
102
+ "type": "text",
103
+ "label": "Camera Settings",
104
+ "placeholder": "e.g., ISO 400, f/2.8, 1/250s"
105
+ },
106
+ {
107
+ "name": "description",
108
+ "type": "textarea",
109
+ "label": "Description"
110
+ },
111
+ {
112
+ "name": "date",
113
+ "type": "text",
114
+ "label": "Date"
115
+ }
116
+ ]
117
+ }
118
+ },
119
+ {
120
+ "id": "sculpting",
121
+ "name": "Sculpting",
122
+ "icon": "đź—ż",
123
+ "mediaType": "image",
124
+ "dataFile": "data/sculpting.json",
125
+ "description": "Three-dimensional sculptural works",
126
+ "fields": {
127
+ "required": ["title"],
128
+ "optional": [
129
+ {
130
+ "name": "material",
131
+ "type": "text",
132
+ "label": "Material",
133
+ "placeholder": "e.g., Bronze, Clay, Marble"
134
+ },
135
+ {
136
+ "name": "dimensions",
137
+ "type": "text",
138
+ "label": "Dimensions",
139
+ "placeholder": "e.g., 12x8x6 inches"
140
+ },
141
+ {
142
+ "name": "weight",
143
+ "type": "text",
144
+ "label": "Weight"
145
+ },
146
+ {
147
+ "name": "description",
148
+ "type": "textarea",
149
+ "label": "Description"
150
+ },
151
+ {
152
+ "name": "url",
153
+ "type": "text",
154
+ "label": "Image URL"
155
+ }
156
+ ]
157
+ }
158
+ },
159
+ {
160
+ "id": "music",
161
+ "name": "Music",
162
+ "icon": "🎵",
163
+ "mediaType": "audio",
164
+ "dataFile": "data/music.json",
165
+ "description": "Musical compositions and recordings",
166
+ "fields": {
167
+ "required": ["title", "url"],
168
+ "optional": [
169
+ {
170
+ "name": "genre",
171
+ "type": "text",
172
+ "label": "Genre",
173
+ "placeholder": "e.g., Jazz, Rock, Classical"
174
+ },
175
+ {
176
+ "name": "duration",
177
+ "type": "text",
178
+ "label": "Duration",
179
+ "placeholder": "e.g., 3:45"
180
+ },
181
+ {
182
+ "name": "lyrics",
183
+ "type": "textarea",
184
+ "label": "Lyrics"
185
+ },
186
+ {
187
+ "name": "description",
188
+ "type": "textarea",
189
+ "label": "Description"
190
+ }
191
+ ]
192
+ }
193
+ },
194
+ {
195
+ "id": "projects",
196
+ "name": "Projects",
197
+ "icon": "đź’»",
198
+ "mediaType": "link",
199
+ "dataFile": "data/projects.json",
200
+ "description": "Web projects, code repositories, and digital work",
201
+ "fields": {
202
+ "required": ["title"],
203
+ "optional": [
204
+ {
205
+ "name": "techStack",
206
+ "type": "text",
207
+ "label": "Tech Stack",
208
+ "placeholder": "e.g., React, Node.js, PostgreSQL"
209
+ },
210
+ {
211
+ "name": "repo",
212
+ "type": "text",
213
+ "label": "GitHub Repository",
214
+ "placeholder": "e.g., username/repo-name"
215
+ },
216
+ {
217
+ "name": "liveUrl",
218
+ "type": "text",
219
+ "label": "Live URL",
220
+ "placeholder": "https://example.com"
221
+ },
222
+ {
223
+ "name": "description",
224
+ "type": "textarea",
225
+ "label": "Description"
226
+ },
227
+ {
228
+ "name": "url",
229
+ "type": "text",
230
+ "label": "URL"
231
+ },
232
+ {
233
+ "name": "visibility",
234
+ "type": "text",
235
+ "label": "Visibility"
236
+ }
237
+ ]
238
+ }
239
+ }
240
+ ]
241
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "defaultLanguage": "en",
3
+ "supportedLanguages": [
4
+ {
5
+ "code": "en",
6
+ "name": "English",
7
+ "flag": "🇺🇸"
8
+ },
9
+ {
10
+ "code": "fr",
11
+ "name": "Français",
12
+ "flag": "🇫🇷"
13
+ }
14
+ ]
15
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "mediaTypes": [
3
+ {
4
+ "id": "image",
5
+ "name": "Image",
6
+ "icon": "🖼️",
7
+ "viewer": "ImageViewer",
8
+ "supportsGallery": true,
9
+ "supportsMetadata": true,
10
+ "acceptedFormats": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"],
11
+ "uploadDestination": "cloudinary",
12
+ "description": "Static images (photos, paintings, drawings, etc.)"
13
+ },
14
+ {
15
+ "id": "audio",
16
+ "name": "Audio",
17
+ "icon": "🎵",
18
+ "viewer": "AudioPlayer",
19
+ "supportsGallery": false,
20
+ "supportsMetadata": false,
21
+ "acceptedFormats": [".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac"],
22
+ "uploadDestination": "github",
23
+ "description": "Audio files (music, podcasts, sounds)"
24
+ },
25
+ {
26
+ "id": "video",
27
+ "name": "Video",
28
+ "icon": "🎬",
29
+ "viewer": "VideoPlayer",
30
+ "supportsGallery": false,
31
+ "supportsMetadata": false,
32
+ "acceptedFormats": [".mp4", ".webm", ".mov"],
33
+ "uploadDestination": "cloudinary",
34
+ "description": "Video files (films, animations, recordings)"
35
+ },
36
+ {
37
+ "id": "text",
38
+ "name": "Text",
39
+ "icon": "📝",
40
+ "viewer": "TextRenderer",
41
+ "supportsGallery": false,
42
+ "supportsMetadata": false,
43
+ "acceptedFormats": [".md", ".txt", ".html"],
44
+ "uploadDestination": "none",
45
+ "description": "Text content (blogs, poetry, articles)"
46
+ },
47
+ {
48
+ "id": "link",
49
+ "name": "Link",
50
+ "icon": "đź”—",
51
+ "viewer": "LinkCard",
52
+ "supportsGallery": false,
53
+ "supportsMetadata": false,
54
+ "acceptedFormats": [],
55
+ "uploadDestination": "none",
56
+ "description": "External links (projects, websites, portfolios)"
57
+ }
58
+ ]
59
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "items": []
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "items": []
3
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "nav_home": "Home",
3
+ "filter_all": "All",
4
+ "nav_painting": "Painting",
5
+ "nav_drawing": "Drawing",
6
+ "nav_photo": "Photo",
7
+ "nav_sculpting": "Volume",
8
+ "nav_projects": "Code",
9
+ "header_title": "Your Portfolio",
10
+ "header_subtitle": "Your creative subtitle here.",
11
+ "marquee": "*** Welcome to my portfolio - Customize this scrolling text in lang/en.json ***",
12
+ "sidebar_about_title": "About",
13
+ "sidebar_about_text": "Write a short bio about yourself here.",
14
+ "sidebar_links_title": "Connect",
15
+ "sidebar_github": "GitHub",
16
+ "sidebar_linkedin": "LinkedIn",
17
+ "sidebar_status_title": "Status",
18
+ "sidebar_status_available": "Open to projects",
19
+ "sidebar_construction": "Work in progress",
20
+ "sidebar_radio_title": "Radio",
21
+ "sidebar_radio_playing": "Now Playing:",
22
+ "footer_copy": "© 2026 Your Name",
23
+ "footer_browser": "Best viewed with...",
24
+ "footer_visitors": "Visits:",
25
+ "footer_last_updated": "Last update:",
26
+ "gallery_created_on": "Created:",
27
+ "gallery_added_on": "Added:",
28
+ "filter_empty": "Nothing here yet.",
29
+ "index_welcome": "Hello.",
30
+ "index_intro": "Introduction text about your work.",
31
+ "index_featured": "Featured Work:",
32
+ "index_look_around": "Look around.",
33
+ "index_highlights_title": "Highlights:",
34
+ "index_highlight_street": "Highlight 1",
35
+ "index_highlight_pastel": "Highlight 2",
36
+ "index_highlight_charcoal": "Highlight 3",
37
+ "gallery_title": "Gallery",
38
+ "gallery_subtitle": "Subtitle",
39
+ "gallery_painting": "Painting",
40
+ "gallery_drawing": "Drawing",
41
+ "photo_title": "Photography",
42
+ "photo_subtitle": "Subtitle",
43
+ "photo_nature": "Collection 1",
44
+ "photo_portraits": "Collection 2",
45
+ "street_title": "Street Photography",
46
+ "street_subtitle": "Subtitle",
47
+ "street_shadows": "Collection 1",
48
+ "gallery_painting_drawing": "Artworks",
49
+ "gallery_intro": "Intro text for gallery.",
50
+ "gallery_back": "Back",
51
+ "photo_collections": "Series",
52
+ "photo_intro": "Intro text for photography.",
53
+ "street_candid": "Candid",
54
+ "street_intro": "Intro text for street photography.",
55
+ "street_marquee": ">>> SCROLLING TEXT <<<",
56
+ "projects_title": "Projects",
57
+ "projects_subtitle": "Subtitle",
58
+ "projects_intro": "Intro text for projects.",
59
+ "projects_view_code": "View Source",
60
+ "sidebar_radio_select": "Select Station:",
61
+ "sidebar_video_title": "Video",
62
+ "sidebar_video_note": "Click to play",
63
+ "sculpting_title": "Sculpting",
64
+ "sculpting_subtitle": "Subtitle",
65
+ "sculpting_intro": "Intro text.",
66
+ "photo_consolidated_title": "Photography",
67
+ "photo_consolidated_subtitle": "Subtitle",
68
+ "nav_music": "Music",
69
+ "music_title": "Music",
70
+ "music_subtitle": "Subtitle",
71
+ "music_tracks_heading": "Tracks",
72
+ "music_loading": "Loading...",
73
+ "music_marquee": ">>> MUSIC MARQUEE <<<",
74
+ "music_no_tracks": "No tracks yet.",
75
+ "music_load_error": "Error loading music.",
76
+ "music_audio_unsupported": "Audio not supported.",
77
+ "music_play_in_radio": "Play in Radio",
78
+ "index_latest_loading": "Loading...",
79
+ "index_latest_label": "NEW",
80
+ "index_latest_added": "Date:",
81
+ "index_latest_empty": "Nothing new.",
82
+ "sidebar_radio_loading": "Loading...",
83
+ "sidebar_radio_no_tracks": "No tracks.",
84
+ "detail_loading": "Loading...",
85
+ "detail_not_found": "Not found.",
86
+ "detail_medium": "Medium:",
87
+ "detail_genre": "Genre:",
88
+ "detail_description": "Description",
89
+ "detail_listen": "Listen",
90
+ "detail_back": "Back",
91
+ "detail_private": "Private",
92
+ "detail_public": "Public",
93
+ "detail_error": "Error loading details.",
94
+ "detail_lyrics": "Lyrics",
95
+ "card_github": "GitHub",
96
+ "card_website": "Website",
97
+ "music_play_me": "Play",
98
+ "admin_title": "PORTFOLIO MANAGER",
99
+ "admin_tab_add": "Add Media",
100
+ "admin_tab_manage": "Manage Content",
101
+ "admin_tab_bulk": "Bulk Edit",
102
+ "admin_tab_translations": "Translations",
103
+ "admin_tab_config": "Configuration",
104
+ "admin_drop_title": "DROP FILES HERE",
105
+ "admin_drop_subtitle": "or click to upload",
106
+ "admin_upload_button": "Upload",
107
+ "admin_loading": "Loading...",
108
+ "admin_fetching": "Fetching...",
109
+ "admin_kernel_ready": "Ready...",
110
+ "admin_logged_as": "Logged in as",
111
+ "admin_user": "ADMIN",
112
+ "admin_system": "System Ready",
113
+ "edit_title": "CONTROL PANEL"
114
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "nav_home": "Accueil",
3
+ "filter_all": "Tout",
4
+ "nav_painting": "Peinture",
5
+ "nav_drawing": "Dessin",
6
+ "nav_photo": "Photo",
7
+ "nav_sculpting": "Volume",
8
+ "nav_projects": "Code",
9
+ "header_title": "Votre Portfolio",
10
+ "header_subtitle": "Votre sous-titre ici.",
11
+ "marquee": "*** Bienvenue sur mon portfolio - Personnalisez ce texte dans lang/fr.json ***",
12
+ "sidebar_about_title": "Ă€ propos",
13
+ "sidebar_about_text": "Écrivez une courte bio ici.",
14
+ "sidebar_links_title": "Réseaux",
15
+ "sidebar_github": "GitHub",
16
+ "sidebar_linkedin": "LinkedIn",
17
+ "sidebar_status_title": "Statut",
18
+ "sidebar_status_available": "Disponible",
19
+ "sidebar_construction": "En construction",
20
+ "sidebar_radio_title": "Radio",
21
+ "sidebar_radio_playing": "En lecture :",
22
+ "footer_copy": "© 2026 Votre Nom",
23
+ "footer_browser": "Meilleur affichage sur...",
24
+ "footer_visitors": "Visites :",
25
+ "footer_last_updated": "Dernière MAJ :",
26
+ "gallery_created_on": "Créé le :",
27
+ "gallery_added_on": "Ajouté le :",
28
+ "filter_empty": "Rien pour l'instant.",
29
+ "index_welcome": "Bonjour.",
30
+ "index_intro": "Texte d'introduction.",
31
+ "index_featured": "Ă€ la une :",
32
+ "index_look_around": "Explorez.",
33
+ "index_highlights_title": "Sélection :",
34
+ "index_highlight_street": "Highlight 1",
35
+ "index_highlight_pastel": "Highlight 2",
36
+ "index_highlight_charcoal": "Highlight 3",
37
+ "gallery_title": "Galerie",
38
+ "gallery_subtitle": "Sous-titre",
39
+ "gallery_painting": "Peinture",
40
+ "gallery_drawing": "Dessin",
41
+ "photo_title": "Photographie",
42
+ "photo_subtitle": "Sous-titre",
43
+ "photo_nature": "Collection 1",
44
+ "photo_portraits": "Collection 2",
45
+ "street_title": "Photo de rue",
46
+ "street_subtitle": "Sous-titre",
47
+ "street_shadows": "Collection 1",
48
+ "gallery_painting_drawing": "Ĺ’uvres",
49
+ "gallery_intro": "Intro galerie.",
50
+ "gallery_back": "Retour",
51
+ "photo_collections": "Séries",
52
+ "photo_intro": "Intro photo.",
53
+ "street_candid": "Candid",
54
+ "street_intro": "Intro photo de rue.",
55
+ "street_marquee": ">>> TEXTE DEFILANT <<<",
56
+ "projects_title": "Projets",
57
+ "projects_subtitle": "Sous-titre",
58
+ "projects_intro": "Intro projets.",
59
+ "projects_view_code": "Voir le code",
60
+ "sidebar_radio_select": "Choisir station :",
61
+ "sidebar_video_title": "Vidéo",
62
+ "sidebar_video_note": "Clic pour lire",
63
+ "sculpting_title": "Volume",
64
+ "sculpting_subtitle": "Sous-titre",
65
+ "sculpting_intro": "Intro volume.",
66
+ "photo_consolidated_title": "Photographie",
67
+ "photo_consolidated_subtitle": "Sous-titre",
68
+ "nav_music": "Musique",
69
+ "music_title": "Musique",
70
+ "music_subtitle": "Sous-titre",
71
+ "music_tracks_heading": "Pistes",
72
+ "music_loading": "Chargement...",
73
+ "music_marquee": ">>> MARQUEE MUSIQUE <<<",
74
+ "music_no_tracks": "Aucune piste.",
75
+ "music_load_error": "Erreur de chargement.",
76
+ "music_audio_unsupported": "Audio non supporté.",
77
+ "music_play_in_radio": "Jouer dans la radio",
78
+ "index_latest_loading": "Chargement...",
79
+ "index_latest_label": "NOUVEAU",
80
+ "index_latest_added": "Date :",
81
+ "index_latest_empty": "Rien de nouveau.",
82
+ "sidebar_radio_loading": "Chargement...",
83
+ "sidebar_radio_no_tracks": "Aucune piste.",
84
+ "detail_loading": "Chargement...",
85
+ "detail_not_found": "Introuvable.",
86
+ "detail_medium": "Technique :",
87
+ "detail_genre": "Style :",
88
+ "detail_description": "Description",
89
+ "detail_listen": "Écouter",
90
+ "detail_back": "Retour",
91
+ "detail_private": "Privé",
92
+ "detail_public": "Public",
93
+ "detail_error": "Erreur.",
94
+ "detail_lyrics": "Paroles",
95
+ "card_github": "GitHub",
96
+ "card_website": "Site Web",
97
+ "music_play_me": "Lire",
98
+ "admin_title": "GESTIONNAIRE",
99
+ "admin_tab_add": "Ajouter Média",
100
+ "admin_tab_manage": "Gérer Contenu",
101
+ "admin_tab_bulk": "Édition Groupée",
102
+ "admin_tab_translations": "Traductions",
103
+ "admin_tab_config": "Configuration",
104
+ "admin_drop_title": "DÉPOSER FICHIERS ICI",
105
+ "admin_drop_subtitle": "ou cliquer pour parcourir",
106
+ "admin_upload_button": "Téléverser",
107
+ "admin_loading": "Chargement...",
108
+ "admin_fetching": "Récupération...",
109
+ "admin_kernel_ready": "PrĂŞt...",
110
+ "admin_logged_as": "Connecté en tant que",
111
+ "admin_user": "ADMIN",
112
+ "admin_system": "Système Prêt",
113
+ "edit_title": "PANNEAU DE CONTRÔLE"
114
+ }