commit cf01a75179556bcb7230d87f7ddbf76b588920fa Author: SysAdmin Date: Sun Oct 19 21:36:57 2025 +0100 feat: Add SilverSHELL SDK documentation page with downloadable templates Added comprehensive SDK page at /sdk with: - Downloadable SilverSHELL starter template (6.3 KB) - Downloadable SilverSHELL module template (14 KB) - Quick start guide with step-by-step instructions - Creating applications guide (configuration, UI, manual install) - Creating modules guide with template options - Publishing modules guide (automated CI/CD + manual) - Available modules list from library.silverlabs.uk - Resources and support links Initial commit includes: - Complete static website with Docker deployment - SilverLabs branding and styling - Nginx configuration for production serving 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fead5f0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +docker-compose.yml +.git +.gitignore +*.md +README.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9f31396 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM nginx:alpine + +# Copy website files to nginx html directory +COPY index.html /usr/share/nginx/html/ +COPY styles.css /usr/share/nginx/html/ +COPY script.js /usr/share/nginx/html/ +COPY logo.png /usr/share/nginx/html/ + +# Copy custom nginx configuration +COPY nginx-site.conf /etc/nginx/conf.d/default.conf + +# Expose port 80 +EXPOSE 80 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b0e12c7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.8' + +services: + silverlabs-web: + build: . + container_name: silverlabs-web + restart: unless-stopped + ports: + - "8210:80" + networks: + - web + labels: + - "com.silverlabs.service=website" + - "com.silverlabs.description=SilverLabs Landing Page" + +networks: + web: + external: false diff --git a/index.html b/index.html new file mode 100644 index 0000000..61ccfc7 --- /dev/null +++ b/index.html @@ -0,0 +1,73 @@ + + + + + + SilverLabs - Innovation Gateway + + + + +
+
+ +
+
+
+ + +
+
+ +
+ +
+

Welcome to SilverLabs

+

Your Innovation Gateway

+ + +
+ +
+

© 2025 SilverLabs. All rights reserved.

+
+
+ + + + diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 0000000..be45fa8 Binary files /dev/null and b/logo.jpg differ diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..73ec8a0 Binary files /dev/null and b/logo.png differ diff --git a/nginx-site.conf b/nginx-site.conf new file mode 100644 index 0000000..59ae2b1 --- /dev/null +++ b/nginx-site.conf @@ -0,0 +1,28 @@ +server { + listen 80; + server_name localhost; + + root /usr/share/nginx/html; + index index.html; + + # Enable gzip compression + gzip on; + gzip_types text/css application/javascript image/jpeg image/png; + gzip_min_length 1000; + + # Cache static assets + location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Main location + location / { + try_files $uri $uri/ /index.html; + } + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; +} diff --git a/script.js b/script.js new file mode 100644 index 0000000..bd3cecf --- /dev/null +++ b/script.js @@ -0,0 +1,139 @@ +// Loading screen functionality +document.addEventListener('DOMContentLoaded', function() { + const loadingScreen = document.getElementById('loading-screen'); + const mainContent = document.getElementById('main-content'); + + // Minimum loading time (in milliseconds) to show the loading screen + const minLoadingTime = 2000; + const startTime = Date.now(); + + // Function to hide loading screen and show main content + function hideLoadingScreen() { + const elapsedTime = Date.now() - startTime; + const remainingTime = Math.max(0, minLoadingTime - elapsedTime); + + setTimeout(() => { + loadingScreen.classList.add('fade-out'); + mainContent.classList.add('visible'); + + // Remove loading screen from DOM after transition + setTimeout(() => { + loadingScreen.style.display = 'none'; + }, 500); + }, remainingTime); + } + + // Hide loading screen when page is fully loaded + if (document.readyState === 'complete') { + hideLoadingScreen(); + } else { + window.addEventListener('load', hideLoadingScreen); + } + + // Add floating particles animation to background + createFloatingParticles(); +}); + +// Create floating particles for background effect +function createFloatingParticles() { + const mainContent = document.getElementById('main-content'); + const particleCount = 20; + + for (let i = 0; i < particleCount; i++) { + createParticle(mainContent); + } +} + +function createParticle(container) { + const particle = document.createElement('div'); + particle.className = 'particle'; + + // Random size between 2px and 6px + const size = Math.random() * 4 + 2; + particle.style.width = `${size}px`; + particle.style.height = `${size}px`; + + // Random position + particle.style.left = `${Math.random() * 100}%`; + particle.style.top = `${Math.random() * 100}%`; + + // Random animation duration between 10s and 30s + const duration = Math.random() * 20 + 10; + particle.style.animationDuration = `${duration}s`; + + // Random delay + const delay = Math.random() * 5; + particle.style.animationDelay = `${delay}s`; + + // Random opacity + const opacity = Math.random() * 0.3 + 0.1; + particle.style.opacity = opacity; + + // Apply styles + particle.style.position = 'absolute'; + particle.style.borderRadius = '50%'; + particle.style.background = 'rgba(255, 255, 255, 0.5)'; + particle.style.pointerEvents = 'none'; + particle.style.zIndex = '0'; + particle.style.animation = 'float ' + particle.style.animationDuration + ' ease-in-out infinite'; + + container.appendChild(particle); +} + +// Add CSS animation for particles +const style = document.createElement('style'); +style.textContent = ` + @keyframes float { + 0%, 100% { + transform: translate(0, 0) rotate(0deg); + } + 25% { + transform: translate(10px, -20px) rotate(90deg); + } + 50% { + transform: translate(-15px, -10px) rotate(180deg); + } + 75% { + transform: translate(-10px, 20px) rotate(270deg); + } + } + + .particle { + filter: blur(1px); + } +`; +document.head.appendChild(style); + +// Add smooth scroll behavior for potential internal links +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + if (target) { + target.scrollIntoView({ + behavior: 'smooth' + }); + } + }); +}); + +// Add interactive hover effect to cards +document.querySelectorAll('.gateway-card').forEach(card => { + card.addEventListener('mousemove', function(e) { + const rect = card.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + + const centerX = rect.width / 2; + const centerY = rect.height / 2; + + const rotateX = (y - centerY) / 10; + const rotateY = (centerX - x) / 10; + + card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateY(-10px)`; + }); + + card.addEventListener('mouseleave', function() { + card.style.transform = ''; + }); +}); diff --git a/sdk/downloads/silvershell-module-template.tar.gz b/sdk/downloads/silvershell-module-template.tar.gz new file mode 100644 index 0000000..059963d Binary files /dev/null and b/sdk/downloads/silvershell-module-template.tar.gz differ diff --git a/sdk/downloads/silvershell-starter-template.tar.gz b/sdk/downloads/silvershell-starter-template.tar.gz new file mode 100644 index 0000000..f18e30d Binary files /dev/null and b/sdk/downloads/silvershell-starter-template.tar.gz differ diff --git a/sdk/index.html b/sdk/index.html new file mode 100644 index 0000000..03b674a --- /dev/null +++ b/sdk/index.html @@ -0,0 +1,429 @@ + + + + + + SilverSHELL SDK - SilverLabs + + + + +
+
+ +
+ +
+
+

SilverSHELL SDK

+

Build modular Blazor WebAssembly applications with ease

+
+ + +
+

🚀 Quick Start

+

Get started with SilverSHELL in just a few minutes. Follow these simple steps:

+ +
    +
  1. + Download the templates (see downloads below) +
  2. +
  3. + Extract the templates to a directory of your choice +
  4. +
  5. + Install the templates +
    dotnet new install ./path/to/SilverSHELL.Starter.Template +dotnet new install ./path/to/SilverSHELL.AppModule.Template
    +
  6. +
  7. + Create your first project +
    dotnet new silvershell-starter -n MyApp --pwa true --module-repository true +cd MyApp +dotnet run
    +
  8. +
  9. + Access your application at https://localhost:5001 +
  10. +
+
+ + +
+

📦 Downloads

+

Download the SilverSHELL project templates to get started:

+ +
+
+

Starter Template

+

Create a new SilverSHELL application with minimal configuration

+

Size: 6.3 KB

+

Includes: Blazor WebAssembly setup, module loading, PWA support

+ + Download Starter Template + +
+ +
+

Module Template

+

Create reusable SilverSHELL modules with best practices

+

Size: 14 KB

+

Includes: Module structure, configuration, CI/CD templates

+ + Download Module Template + +
+
+
+ + +
+

🏗️ Creating Applications

+ +

Using the Starter Template

+
# Create a new application +dotnet new silvershell-starter -n MyAwesomeApp + +# With PWA support +dotnet new silvershell-starter -n MyAwesomeApp --pwa true + +# With Module Repository integration +dotnet new silvershell-starter -n MyAwesomeApp --module-repository true
+ +

Adding Modules

+

SilverSHELL supports multiple ways to add modules to your application:

+ +

Option 1: Configuration File

+

Edit wwwroot/appsettings.json:

+
{ + "AMS": { + "Deployment": { + "PreloadModules": [ + "SilverLabs.SilverSHELL.Auth.Login", + "SilverSHELL.Modules.ModuleBrowser" + ] + } + } +}
+ +

Option 2: Module Browser UI

+
    +
  1. Navigate to /modules/browse in your application
  2. +
  3. Search for modules from library.silverlabs.uk
  4. +
  5. Click "Install" on any module
  6. +
  7. Modules are downloaded and installed automatically
  8. +
+ +

Option 3: Manual Installation

+
# Copy module DLLs to the modules directory +cp SomeModule.dll wwwroot/modules/ +dotnet run +# Module is automatically discovered and loaded!
+
+ + +
+

🔧 Creating Modules

+ +

Using the Module Template

+
# Create a basic module +dotnet new silvershell-module -n MyModule + +# Create a module with widgets +dotnet new silvershell-module -n MyModule --includeWidgets true + +# Create a module with search provider +dotnet new silvershell-module -n MyModule --includeSearchProvider true + +# Create a module with everything +dotnet new silvershell-module -n MyModule \ + --includeWidgets true \ + --includeSearchProvider true \ + --includeTests true
+ +

Module Structure

+

The template creates an organized structure:

+
MyModule/ +├── Configuration/ +│ ├── ModuleMetadata.cs # Module identity and version +│ ├── EndpointConfiguration.cs # Navigation routes +│ └── WidgetConfiguration.cs # Dashboard widgets +├── Pages/ +│ └── Index.razor # Razor pages +├── Components/ +│ └── ... # Razor components +├── .gitlab-ci.yml # GitLab CI/CD +├── .github/workflows/ +│ └── publish.yml # GitHub Actions +└── MyModuleMain.cs # Module entry point
+
+ + +
+

🚀 Publishing Modules

+ +
+ CI/CD Included! The module template includes ready-to-use CI/CD pipelines for both GitLab and GitHub. +
+ +

Automated Publishing (Recommended)

+

The templates include CI/CD pipelines for automatic publishing:

+ +
    +
  1. + Configure CI/CD variables +
    # In GitLab: Settings > CI/CD > Variables +# In GitHub: Settings > Secrets > Actions + +# Add variable: +MODULE_REPO_TOKEN: [your token from library.silverlabs.uk]
    +
  2. +
  3. + Commit and push your code +
    git add . +git commit -m "feat: Initial module implementation" +git push
    +
  4. +
  5. + Create a release tag +
    git tag v1.0.0 +git push --tags
    +
  6. +
  7. + Trigger publish from your CI/CD pipeline UI +
  8. +
+ +

Manual Publishing

+
# Build and package +dotnet pack --configuration Release -o dist/ + +# Upload to repository +curl -X POST "https://library.silverlabs.uk/api/modules/publish" \ + -F "id=MyModule" \ + -F "name=My Awesome Module" \ + -F "version=1.0.0" \ + -F "description=A great module" \ + -F "author=Your Name" \ + -F "package=@dist/MyModule.1.0.0.nupkg"
+
+ + +
+

📚 Available Modules

+

Browse and install modules from the SilverSHELL module repository:

+ +
+ Module Repository: library.silverlabs.uk +
+ +

Featured Modules:

+
    +
  • Auth.Login - User authentication and login UI
  • +
  • Auth.Registration - User registration system
  • +
  • Auth.UserManagement - User administration
  • +
  • Auth.MyAccount - User profile management
  • +
  • ModuleBrowser - Browse and install modules from the UI
  • +
+ +

Explore All Modules

+
# List all available modules via API +curl https://library.silverlabs.uk/api/modules + +# Search for specific modules +curl https://library.silverlabs.uk/api/modules/search?q=auth
+
+ + +
+

📖 Resources

+ +
+ + +
+

💬 Support

+

Need help? We're here for you:

+ +
+ + ← Back to SilverLabs Home +
+
+ + + + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..cceda2d --- /dev/null +++ b/styles.css @@ -0,0 +1,314 @@ +:root { + --primary-blue: #2E3192; + --secondary-blue: #1E5A9E; + --cyan: #00B8D4; + --light-cyan: #4DD0E1; + --gradient: linear-gradient(135deg, #2E3192 0%, #1E5A9E 50%, #00B8D4 100%); + --text-primary: #FFFFFF; + --text-secondary: rgba(255, 255, 255, 0.8); + --card-bg: rgba(255, 255, 255, 0.1); + --card-border: rgba(255, 255, 255, 0.2); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + background: var(--gradient); + background-attachment: fixed; + color: var(--text-primary); + min-height: 100vh; + overflow-x: hidden; +} + +/* Loading Screen */ +.loading-screen { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: var(--gradient); + display: flex; + justify-content: center; + align-items: center; + z-index: 9999; + transition: opacity 0.5s ease, visibility 0.5s ease; +} + +.loading-screen.fade-out { + opacity: 0; + visibility: hidden; +} + +.loading-content { + text-align: center; +} + +.loading-logo { + width: 300px; + height: auto; + max-width: 80vw; + animation: pulse 2s ease-in-out infinite; + filter: drop-shadow(0 10px 30px rgba(0, 0, 0, 0.3)); +} + +.loading-spinner { + margin-top: 30px; + width: 50px; + height: 50px; + border: 4px solid rgba(255, 255, 255, 0.3); + border-top-color: var(--text-primary); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-left: auto; + margin-right: auto; +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* Main Content */ +.main-content { + opacity: 0; + transition: opacity 0.5s ease; + min-height: 100vh; + display: flex; + flex-direction: column; +} + +.main-content.visible { + opacity: 1; +} + +.header { + padding: 40px 20px; + text-align: center; +} + +.logo { + width: 200px; + height: auto; + max-width: 80vw; + filter: drop-shadow(0 5px 20px rgba(0, 0, 0, 0.2)); + animation: fadeInDown 0.8s ease; +} + +@keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.main { + flex: 1; + padding: 20px; + max-width: 1200px; + margin: 0 auto; + width: 100%; +} + +.title { + font-size: 3rem; + font-weight: 700; + text-align: center; + margin-bottom: 10px; + text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + animation: fadeInUp 0.8s ease 0.2s both; +} + +.subtitle { + font-size: 1.5rem; + text-align: center; + color: var(--text-secondary); + margin-bottom: 60px; + animation: fadeInUp 0.8s ease 0.3s both; +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.gateway-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 30px; + margin-bottom: 60px; +} + +.gateway-card { + background: var(--card-bg); + backdrop-filter: blur(10px); + border: 1px solid var(--card-border); + border-radius: 20px; + padding: 40px 30px; + text-align: center; + text-decoration: none; + color: var(--text-primary); + transition: all 0.3s ease; + position: relative; + overflow: hidden; + animation: fadeInScale 0.6s ease both; +} + +.gateway-card:nth-child(1) { + animation-delay: 0.4s; +} + +.gateway-card:nth-child(2) { + animation-delay: 0.5s; +} + +.gateway-card:nth-child(3) { + animation-delay: 0.6s; +} + +@keyframes fadeInScale { + from { + opacity: 0; + transform: scale(0.9); + } + to { + opacity: 1; + transform: scale(1); + } +} + +.gateway-card::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); + transition: left 0.5s ease; +} + +.gateway-card:hover::before { + left: 100%; +} + +.gateway-card:hover { + transform: translateY(-10px); + background: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.4); + box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3); +} + +.card-icon { + width: 80px; + height: 80px; + margin: 0 auto 20px; + background: rgba(255, 255, 255, 0.1); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; +} + +.card-icon svg { + width: 40px; + height: 40px; + stroke: var(--light-cyan); + transition: all 0.3s ease; +} + +.gateway-card:hover .card-icon { + background: rgba(255, 255, 255, 0.2); + transform: rotate(10deg) scale(1.1); +} + +.gateway-card:hover .card-icon svg { + stroke: var(--text-primary); +} + +.card-title { + font-size: 1.8rem; + font-weight: 600; + margin-bottom: 10px; +} + +.card-description { + font-size: 1rem; + color: var(--text-secondary); +} + +.footer { + padding: 30px 20px; + text-align: center; + color: var(--text-secondary); + font-size: 0.9rem; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .title { + font-size: 2rem; + } + + .subtitle { + font-size: 1.2rem; + margin-bottom: 40px; + } + + .gateway-grid { + grid-template-columns: 1fr; + gap: 20px; + } + + .logo { + width: 150px; + } + + .loading-logo { + width: 200px; + } +} + +@media (max-width: 480px) { + .title { + font-size: 1.5rem; + } + + .subtitle { + font-size: 1rem; + } + + .card-title { + font-size: 1.5rem; + } + + .gateway-card { + padding: 30px 20px; + } +}