@mtldev514/retro-portfolio-engine 1.0.0 → 1.1.2

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 (52) hide show
  1. package/.github/workflows/build-and-deploy.yml +105 -0
  2. package/ADMIN_SETUP.md +306 -0
  3. package/README.md +193 -301
  4. package/USAGE.md +451 -0
  5. package/build.sh +326 -0
  6. package/index.html +85 -0
  7. package/js/manifest-loader.js +313 -0
  8. package/manifest.json +74 -0
  9. package/package.json +14 -38
  10. package/setup-admin.sh +134 -0
  11. package/sync-after-admin.sh +58 -0
  12. package/bin/cli.js +0 -103
  13. package/engine/admin/admin.css +0 -720
  14. package/engine/admin/admin.html +0 -801
  15. package/engine/admin/admin_api.py +0 -230
  16. package/engine/admin/scripts/backup.sh +0 -116
  17. package/engine/admin/scripts/config_loader.py +0 -180
  18. package/engine/admin/scripts/init.sh +0 -141
  19. package/engine/admin/scripts/manager.py +0 -308
  20. package/engine/admin/scripts/restore.sh +0 -121
  21. package/engine/admin/scripts/server.py +0 -41
  22. package/engine/admin/scripts/update.sh +0 -321
  23. package/engine/admin/scripts/validate_json.py +0 -62
  24. package/engine/fonts.css +0 -37
  25. package/engine/index.html +0 -190
  26. package/engine/js/config-loader.js +0 -370
  27. package/engine/js/config.js +0 -173
  28. package/engine/js/counter.js +0 -17
  29. package/engine/js/effects.js +0 -97
  30. package/engine/js/i18n.js +0 -68
  31. package/engine/js/init.js +0 -107
  32. package/engine/js/media.js +0 -264
  33. package/engine/js/render.js +0 -282
  34. package/engine/js/router.js +0 -133
  35. package/engine/js/sparkle.js +0 -123
  36. package/engine/js/themes.js +0 -607
  37. package/engine/style.css +0 -2037
  38. package/index.js +0 -35
  39. package/scripts/admin.js +0 -67
  40. package/scripts/build.js +0 -142
  41. package/scripts/init.js +0 -237
  42. package/scripts/post-install.js +0 -16
  43. package/scripts/serve.js +0 -54
  44. package/templates/user-portfolio/.github/workflows/deploy.yml +0 -57
  45. package/templates/user-portfolio/config/app.json +0 -36
  46. package/templates/user-portfolio/config/categories.json +0 -241
  47. package/templates/user-portfolio/config/languages.json +0 -15
  48. package/templates/user-portfolio/config/media-types.json +0 -59
  49. package/templates/user-portfolio/data/painting.json +0 -3
  50. package/templates/user-portfolio/data/projects.json +0 -3
  51. package/templates/user-portfolio/lang/en.json +0 -114
  52. package/templates/user-portfolio/lang/fr.json +0 -114
package/build.sh ADDED
@@ -0,0 +1,326 @@
1
+ #!/bin/bash
2
+
3
+ ##############################################################################
4
+ # Site-as-a-Package Build Script
5
+ # Fetches content from remote data repository and builds static site
6
+ ##############################################################################
7
+
8
+ set -e # Exit on error
9
+
10
+ # Colors for output
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ YELLOW='\033[1;33m'
14
+ BLUE='\033[0;34m'
15
+ NC='\033[0m' # No Color
16
+
17
+ # Configuration
18
+ MANIFEST_URL="${MANIFEST_URL:-https://raw.githubusercontent.com/YOUR_USERNAME/retro-portfolio-data/main/manifest.json}"
19
+ CACHE_DIR=".cache"
20
+ DIST_DIR="dist"
21
+ FORCE_DOWNLOAD=false
22
+
23
+ ##############################################################################
24
+ # Helper Functions
25
+ ##############################################################################
26
+
27
+ print_header() {
28
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
29
+ echo -e "${BLUE} 🎨 Site-as-a-Package Builder${NC}"
30
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
31
+ }
32
+
33
+ print_step() {
34
+ echo -e "\n${GREEN}▶${NC} $1"
35
+ }
36
+
37
+ print_warning() {
38
+ echo -e "${YELLOW}⚠${NC} $1"
39
+ }
40
+
41
+ print_error() {
42
+ echo -e "${RED}✗${NC} $1"
43
+ }
44
+
45
+ print_success() {
46
+ echo -e "${GREEN}✓${NC} $1"
47
+ }
48
+
49
+ ##############################################################################
50
+ # Parse Arguments
51
+ ##############################################################################
52
+
53
+ parse_args() {
54
+ while [[ $# -gt 0 ]]; do
55
+ case $1 in
56
+ -f|--force)
57
+ FORCE_DOWNLOAD=true
58
+ shift
59
+ ;;
60
+ -m|--manifest)
61
+ MANIFEST_URL="$2"
62
+ shift 2
63
+ ;;
64
+ -c|--cache-dir)
65
+ CACHE_DIR="$2"
66
+ shift 2
67
+ ;;
68
+ -o|--output)
69
+ DIST_DIR="$2"
70
+ shift 2
71
+ ;;
72
+ -h|--help)
73
+ show_help
74
+ exit 0
75
+ ;;
76
+ *)
77
+ print_error "Unknown option: $1"
78
+ show_help
79
+ exit 1
80
+ ;;
81
+ esac
82
+ done
83
+ }
84
+
85
+ show_help() {
86
+ cat << EOF
87
+ Usage: ./build.sh [OPTIONS]
88
+
89
+ Options:
90
+ -f, --force Force re-download of all files (ignore cache)
91
+ -m, --manifest URL Specify custom manifest URL
92
+ -c, --cache-dir DIR Cache directory (default: .cache)
93
+ -o, --output DIR Output directory (default: dist)
94
+ -h, --help Show this help message
95
+
96
+ Examples:
97
+ ./build.sh # Build with cache
98
+ ./build.sh --force # Force fresh download
99
+ ./build.sh --manifest https://... # Use custom manifest
100
+
101
+ EOF
102
+ }
103
+
104
+ ##############################################################################
105
+ # Cache Management
106
+ ##############################################################################
107
+
108
+ check_cache() {
109
+ local file_path="$1"
110
+ local cached_file="${CACHE_DIR}/${file_path}"
111
+
112
+ if [[ "$FORCE_DOWNLOAD" == true ]]; then
113
+ return 1 # Don't use cache
114
+ fi
115
+
116
+ if [[ -f "$cached_file" ]]; then
117
+ # Check if cache is still valid (less than 1 hour old)
118
+ local cache_age=$(($(date +%s) - $(date -r "$cached_file" +%s)))
119
+ if [[ $cache_age -lt 3600 ]]; then
120
+ return 0 # Cache is valid
121
+ fi
122
+ fi
123
+
124
+ return 1 # Cache invalid or doesn't exist
125
+ }
126
+
127
+ ##############################################################################
128
+ # Download Functions
129
+ ##############################################################################
130
+
131
+ download_file() {
132
+ local url="$1"
133
+ local output_path="$2"
134
+ local use_cache="${3:-true}"
135
+
136
+ # Create directory if needed
137
+ mkdir -p "$(dirname "$output_path")"
138
+
139
+ # Check cache first
140
+ if [[ "$use_cache" == true ]] && check_cache "$output_path"; then
141
+ local cached_file="${CACHE_DIR}/${output_path}"
142
+ cp "$cached_file" "$output_path"
143
+ echo -e " ${BLUE}↻${NC} $(basename "$output_path") (cached)"
144
+ return 0
145
+ fi
146
+
147
+ # Download file
148
+ if curl -sfL "$url" -o "$output_path" 2>/dev/null; then
149
+ # Save to cache
150
+ if [[ "$use_cache" == true ]]; then
151
+ local cache_file="${CACHE_DIR}/${output_path}"
152
+ mkdir -p "$(dirname "$cache_file")"
153
+ cp "$output_path" "$cache_file"
154
+ fi
155
+ echo -e " ${GREEN}↓${NC} $(basename "$output_path")"
156
+ return 0
157
+ else
158
+ print_error "Failed to download: $url"
159
+ return 1
160
+ fi
161
+ }
162
+
163
+ ##############################################################################
164
+ # Build Process
165
+ ##############################################################################
166
+
167
+ load_manifest() {
168
+ print_step "Loading manifest from remote..."
169
+
170
+ local temp_manifest=$(mktemp)
171
+
172
+ if ! curl -sfL "$MANIFEST_URL" -o "$temp_manifest"; then
173
+ print_error "Failed to download manifest from: $MANIFEST_URL"
174
+ rm -f "$temp_manifest"
175
+ exit 1
176
+ fi
177
+
178
+ # Validate JSON
179
+ if ! jq empty "$temp_manifest" 2>/dev/null; then
180
+ print_error "Invalid JSON in manifest"
181
+ rm -f "$temp_manifest"
182
+ exit 1
183
+ fi
184
+
185
+ # Parse manifest
186
+ DATA_REPO_BASE=$(jq -r '.dataRepository.baseUrl' "$temp_manifest")
187
+
188
+ if [[ "$DATA_REPO_BASE" == "null" || -z "$DATA_REPO_BASE" ]]; then
189
+ print_error "Invalid manifest: missing dataRepository.baseUrl"
190
+ rm -f "$temp_manifest"
191
+ exit 1
192
+ fi
193
+
194
+ # Store manifest for later use
195
+ MANIFEST_FILE="$temp_manifest"
196
+
197
+ print_success "Manifest loaded successfully"
198
+ echo " Data source: $DATA_REPO_BASE"
199
+ }
200
+
201
+ download_structure() {
202
+ local section="$1"
203
+ local use_cache="$2"
204
+
205
+ print_step "Downloading $section files..."
206
+
207
+ # Get files from manifest
208
+ local files=$(jq -r ".structure.${section} | to_entries[] | .value" "$MANIFEST_FILE")
209
+
210
+ while IFS= read -r file_path; do
211
+ if [[ -n "$file_path" && "$file_path" != "null" ]]; then
212
+ local url="${DATA_REPO_BASE}${file_path}"
213
+ download_file "$url" "${DIST_DIR}/${file_path}" "$use_cache"
214
+ fi
215
+ done <<< "$files"
216
+ }
217
+
218
+ copy_engine_files() {
219
+ print_step "Copying engine files..."
220
+
221
+ # Copy index.html
222
+ if [[ -f "index.html" ]]; then
223
+ cp index.html "${DIST_DIR}/"
224
+ echo -e " ${GREEN}✓${NC} index.html"
225
+ fi
226
+
227
+ # Copy local JS files
228
+ if [[ -d "js" ]]; then
229
+ mkdir -p "${DIST_DIR}/js"
230
+ cp -r js/* "${DIST_DIR}/js/"
231
+ echo -e " ${GREEN}✓${NC} js/ ($(ls -1 js | wc -l) files)"
232
+ fi
233
+
234
+ # Copy local CSS files
235
+ for css_file in style.css fonts.css; do
236
+ if [[ -f "$css_file" ]]; then
237
+ cp "$css_file" "${DIST_DIR}/"
238
+ echo -e " ${GREEN}✓${NC} $css_file"
239
+ fi
240
+ done
241
+ }
242
+
243
+ create_build_info() {
244
+ print_step "Creating build info..."
245
+
246
+ cat > "${DIST_DIR}/build-info.json" << EOF
247
+ {
248
+ "buildDate": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
249
+ "manifestUrl": "$MANIFEST_URL",
250
+ "dataSource": "$DATA_REPO_BASE",
251
+ "cacheUsed": $([ "$FORCE_DOWNLOAD" == true ] && echo "false" || echo "true"),
252
+ "version": "$(jq -r '.version' "$MANIFEST_FILE")"
253
+ }
254
+ EOF
255
+
256
+ print_success "Build info created"
257
+ }
258
+
259
+ ##############################################################################
260
+ # Main Build Process
261
+ ##############################################################################
262
+
263
+ main() {
264
+ print_header
265
+
266
+ # Parse arguments
267
+ parse_args "$@"
268
+
269
+ # Show build configuration
270
+ echo ""
271
+ echo "Configuration:"
272
+ echo " Manifest URL: $MANIFEST_URL"
273
+ echo " Cache dir: $CACHE_DIR"
274
+ echo " Output dir: $DIST_DIR"
275
+ echo " Force reload: $FORCE_DOWNLOAD"
276
+ echo ""
277
+
278
+ # Check dependencies
279
+ if ! command -v jq &> /dev/null; then
280
+ print_error "jq is required but not installed. Install with: apt-get install jq"
281
+ exit 1
282
+ fi
283
+
284
+ # Clean output directory if needed
285
+ if [[ -d "$DIST_DIR" ]]; then
286
+ print_step "Cleaning output directory..."
287
+ rm -rf "$DIST_DIR"
288
+ fi
289
+ mkdir -p "$DIST_DIR"
290
+
291
+ # Create cache directory
292
+ mkdir -p "$CACHE_DIR"
293
+
294
+ # Load manifest
295
+ load_manifest
296
+
297
+ # Download data files
298
+ local use_cache=$([ "$FORCE_DOWNLOAD" == true ] && echo "false" || echo "true")
299
+
300
+ download_structure "config" "$use_cache"
301
+ download_structure "data" "$use_cache"
302
+ download_structure "lang" "$use_cache"
303
+
304
+ # Copy engine files
305
+ copy_engine_files
306
+
307
+ # Create build info
308
+ create_build_info
309
+
310
+ # Cleanup
311
+ rm -f "$MANIFEST_FILE"
312
+
313
+ # Success!
314
+ echo ""
315
+ echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
316
+ print_success "Build completed successfully!"
317
+ echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
318
+ echo ""
319
+ echo "Next steps:"
320
+ echo " 1. Test locally: cd ${DIST_DIR} && python3 -m http.server 8000"
321
+ echo " 2. Deploy: Deploy the ${DIST_DIR}/ folder to GitHub Pages"
322
+ echo ""
323
+ }
324
+
325
+ # Run main function
326
+ main "$@"
package/index.html ADDED
@@ -0,0 +1,85 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title data-i18n="header_title">Retro Portfolio</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <link rel="stylesheet" href="fonts.css">
9
+
10
+ <!-- Load manifest-based config loader -->
11
+ <script src="js/manifest-loader.js"></script>
12
+
13
+ <!-- Load application modules -->
14
+ <script src="js/i18n.js" defer></script>
15
+ <script src="js/themes.js" defer></script>
16
+ <script src="js/render.js" defer></script>
17
+ <script src="js/router.js" defer></script>
18
+ <script src="js/media.js" defer></script>
19
+ <script src="js/sparkle.js" defer></script>
20
+ <script src="js/effects.js" defer></script>
21
+
22
+ <!-- Initialize app after all modules loaded -->
23
+ <script src="js/init.js" defer></script>
24
+ </head>
25
+ <body>
26
+ <!-- Votre contenu HTML existant ici -->
27
+ <div id="rotate-overlay">
28
+ <div class="rotate-content">
29
+ <div class="rotate-icon">📺↩️</div>
30
+ <h2>ROTATE YOUR DEVICE!</h2>
31
+ <p>This website was designed for<br><b>DESKTOP COMPUTERS</b></p>
32
+ <p class="rotate-sub">Please turn your phone sideways<br>for the full retro experience!</p>
33
+ </div>
34
+ </div>
35
+
36
+ <div class="container">
37
+ <header>
38
+ <div class="settings-switcher">
39
+ <button class="settings-btn">⚙</button>
40
+ <div class="settings-dropdown">
41
+ <div class="settings-section-label">Theme</div>
42
+ <div class="settings-option" onclick="themes.changeTheme('jr16')">
43
+ <span class="theme-icon">🌿</span> JR-16
44
+ </div>
45
+ <div class="settings-divider"></div>
46
+ <div class="settings-section-label">Language</div>
47
+ <div class="settings-option" onclick="i18n.changeLang('en')">
48
+ <span class="lang-flag">🇬🇧</span> English
49
+ </div>
50
+ <div class="settings-option" onclick="i18n.changeLang('fr')">
51
+ <span class="lang-flag">🇫🇷</span> Français
52
+ </div>
53
+ </div>
54
+ </div>
55
+ <h1 id="page-title" data-i18n="header_title">Portfolio</h1>
56
+ </header>
57
+
58
+ <div class="content">
59
+ <main id="app">
60
+ <div class="loading-screen">
61
+ <div class="loading-spinner"></div>
62
+ <p>Loading site engine...</p>
63
+ </div>
64
+ </main>
65
+ </div>
66
+
67
+ <footer class="footer-terminal">
68
+ <div class="terminal-window">
69
+ <div class="terminal-titlebar">
70
+ <span class="terminal-titlebar-text">Built with Site-as-a-Package</span>
71
+ </div>
72
+ <div class="terminal-body">
73
+ <div class="terminal-line">
74
+ <span class="terminal-prompt">$</span>
75
+ <span data-i18n="footer_copy">&copy; 2026</span>
76
+ <span class="terminal-cursor">█</span>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </footer>
81
+ </div>
82
+
83
+ <script src="js/counter.js"></script>
84
+ </body>
85
+ </html>