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 <noreply@anthropic.com>
This commit is contained in:
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
docker-compose.yml
|
||||
.git
|
||||
.gitignore
|
||||
*.md
|
||||
README.md
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -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;"]
|
||||
18
docker-compose.yml
Normal file
18
docker-compose.yml
Normal file
@@ -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
|
||||
73
index.html
Normal file
73
index.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SilverLabs - Innovation Gateway</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Loading Screen -->
|
||||
<div id="loading-screen" class="loading-screen">
|
||||
<div class="loading-content">
|
||||
<img src="logo.png" alt="SilverLabs Logo" class="loading-logo">
|
||||
<div class="loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="main-content" class="main-content">
|
||||
<header class="header">
|
||||
<img src="logo.png" alt="SilverLabs Logo" class="logo">
|
||||
</header>
|
||||
|
||||
<main class="main">
|
||||
<h1 class="title">Welcome to SilverLabs</h1>
|
||||
<p class="subtitle">Your Innovation Gateway</p>
|
||||
|
||||
<div class="gateway-grid">
|
||||
<a href="https://helpdesk.silverlabs.uk" class="gateway-card">
|
||||
<div class="card-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="10"></circle>
|
||||
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
|
||||
<line x1="12" y1="17" x2="12.01" y2="17"></line>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title">Help Desk</h2>
|
||||
<p class="card-description">Support & Assistance</p>
|
||||
</a>
|
||||
|
||||
<a href="https://appstore.silverlabs.uk" class="gateway-card">
|
||||
<div class="card-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="3" width="7" height="7"></rect>
|
||||
<rect x="14" y="3" width="7" height="7"></rect>
|
||||
<rect x="14" y="14" width="7" height="7"></rect>
|
||||
<rect x="3" y="14" width="7" height="7"></rect>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title">App Store</h2>
|
||||
<p class="card-description">Applications & Tools</p>
|
||||
</a>
|
||||
|
||||
<a href="https://cloud.silverlabs.uk" class="gateway-card">
|
||||
<div class="card-icon">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="card-title">Cloud</h2>
|
||||
<p class="card-description">Storage & Collaboration</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<p>© 2025 SilverLabs. All rights reserved.</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
28
nginx-site.conf
Normal file
28
nginx-site.conf
Normal file
@@ -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;
|
||||
}
|
||||
139
script.js
Normal file
139
script.js
Normal file
@@ -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 = '';
|
||||
});
|
||||
});
|
||||
BIN
sdk/downloads/silvershell-module-template.tar.gz
Normal file
BIN
sdk/downloads/silvershell-module-template.tar.gz
Normal file
Binary file not shown.
BIN
sdk/downloads/silvershell-starter-template.tar.gz
Normal file
BIN
sdk/downloads/silvershell-starter-template.tar.gz
Normal file
Binary file not shown.
429
sdk/index.html
Normal file
429
sdk/index.html
Normal file
@@ -0,0 +1,429 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SilverSHELL SDK - SilverLabs</title>
|
||||
<link rel="stylesheet" href="../styles.css">
|
||||
<style>
|
||||
.sdk-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.sdk-header {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.sdk-header h1 {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.sdk-section {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 1rem;
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.sdk-section h2 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.sdk-section h3 {
|
||||
font-size: 1.5rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: #a78bfa;
|
||||
}
|
||||
|
||||
.code-block {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
overflow-x: auto;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.code-block code {
|
||||
color: #a5f3fc;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9rem;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.download-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.download-card {
|
||||
background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
|
||||
border-radius: 1rem;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid rgba(102, 126, 234, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.download-card:hover {
|
||||
transform: translateY(-4px);
|
||||
border-color: rgba(102, 126, 234, 0.6);
|
||||
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
|
||||
}
|
||||
|
||||
.download-card h3 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.download-card p {
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.download-btn {
|
||||
display: inline-block;
|
||||
margin-top: 1rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 0.5rem;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.download-btn:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.steps-list {
|
||||
counter-reset: step-counter;
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.steps-list li {
|
||||
counter-increment: step-counter;
|
||||
position: relative;
|
||||
padding-left: 3rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.steps-list li::before {
|
||||
content: counter(step-counter);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: rgba(102, 126, 234, 0.1);
|
||||
border-left: 4px solid #667eea;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
margin-top: 2rem;
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.back-link:hover {
|
||||
color: #764ba2;
|
||||
}
|
||||
|
||||
ul {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main-content" class="main-content">
|
||||
<header class="header">
|
||||
<img src="../logo.png" alt="SilverLabs Logo" class="logo">
|
||||
</header>
|
||||
|
||||
<div class="sdk-container">
|
||||
<div class="sdk-header">
|
||||
<h1>SilverSHELL SDK</h1>
|
||||
<p style="font-size: 1.2rem; color: rgba(255, 255, 255, 0.7);">Build modular Blazor WebAssembly applications with ease</p>
|
||||
</div>
|
||||
|
||||
<!-- Quick Start Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>🚀 Quick Start</h2>
|
||||
<p>Get started with SilverSHELL in just a few minutes. Follow these simple steps:</p>
|
||||
|
||||
<ol class="steps-list">
|
||||
<li>
|
||||
<strong>Download the templates</strong> (see downloads below)
|
||||
</li>
|
||||
<li>
|
||||
<strong>Extract the templates</strong> to a directory of your choice
|
||||
</li>
|
||||
<li>
|
||||
<strong>Install the templates</strong>
|
||||
<div class="code-block"><code>dotnet new install ./path/to/SilverSHELL.Starter.Template
|
||||
dotnet new install ./path/to/SilverSHELL.AppModule.Template</code></div>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Create your first project</strong>
|
||||
<div class="code-block"><code>dotnet new silvershell-starter -n MyApp --pwa true --module-repository true
|
||||
cd MyApp
|
||||
dotnet run</code></div>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Access your application</strong> at <code>https://localhost:5001</code>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!-- Downloads Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>📦 Downloads</h2>
|
||||
<p>Download the SilverSHELL project templates to get started:</p>
|
||||
|
||||
<div class="download-grid">
|
||||
<div class="download-card">
|
||||
<h3>Starter Template</h3>
|
||||
<p>Create a new SilverSHELL application with minimal configuration</p>
|
||||
<p><strong>Size:</strong> 6.3 KB</p>
|
||||
<p><strong>Includes:</strong> Blazor WebAssembly setup, module loading, PWA support</p>
|
||||
<a href="downloads/silvershell-starter-template.tar.gz" class="download-btn" download>
|
||||
Download Starter Template
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="download-card">
|
||||
<h3>Module Template</h3>
|
||||
<p>Create reusable SilverSHELL modules with best practices</p>
|
||||
<p><strong>Size:</strong> 14 KB</p>
|
||||
<p><strong>Includes:</strong> Module structure, configuration, CI/CD templates</p>
|
||||
<a href="downloads/silvershell-module-template.tar.gz" class="download-btn" download>
|
||||
Download Module Template
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Creating Applications Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>🏗️ Creating Applications</h2>
|
||||
|
||||
<h3>Using the Starter Template</h3>
|
||||
<div class="code-block"><code># 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</code></div>
|
||||
|
||||
<h3>Adding Modules</h3>
|
||||
<p>SilverSHELL supports multiple ways to add modules to your application:</p>
|
||||
|
||||
<h3>Option 1: Configuration File</h3>
|
||||
<p>Edit <code>wwwroot/appsettings.json</code>:</p>
|
||||
<div class="code-block"><code>{
|
||||
"AMS": {
|
||||
"Deployment": {
|
||||
"PreloadModules": [
|
||||
"SilverLabs.SilverSHELL.Auth.Login",
|
||||
"SilverSHELL.Modules.ModuleBrowser"
|
||||
]
|
||||
}
|
||||
}
|
||||
}</code></div>
|
||||
|
||||
<h3>Option 2: Module Browser UI</h3>
|
||||
<ol>
|
||||
<li>Navigate to <code>/modules/browse</code> in your application</li>
|
||||
<li>Search for modules from <strong>library.silverlabs.uk</strong></li>
|
||||
<li>Click "Install" on any module</li>
|
||||
<li>Modules are downloaded and installed automatically</li>
|
||||
</ol>
|
||||
|
||||
<h3>Option 3: Manual Installation</h3>
|
||||
<div class="code-block"><code># Copy module DLLs to the modules directory
|
||||
cp SomeModule.dll wwwroot/modules/
|
||||
dotnet run
|
||||
# Module is automatically discovered and loaded!</code></div>
|
||||
</div>
|
||||
|
||||
<!-- Creating Modules Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>🔧 Creating Modules</h2>
|
||||
|
||||
<h3>Using the Module Template</h3>
|
||||
<div class="code-block"><code># 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</code></div>
|
||||
|
||||
<h3>Module Structure</h3>
|
||||
<p>The template creates an organized structure:</p>
|
||||
<div class="code-block"><code>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</code></div>
|
||||
</div>
|
||||
|
||||
<!-- Publishing Modules Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>🚀 Publishing Modules</h2>
|
||||
|
||||
<div class="info-box">
|
||||
<strong>CI/CD Included!</strong> The module template includes ready-to-use CI/CD pipelines for both GitLab and GitHub.
|
||||
</div>
|
||||
|
||||
<h3>Automated Publishing (Recommended)</h3>
|
||||
<p>The templates include CI/CD pipelines for automatic publishing:</p>
|
||||
|
||||
<ol class="steps-list">
|
||||
<li>
|
||||
<strong>Configure CI/CD variables</strong>
|
||||
<div class="code-block"><code># In GitLab: Settings > CI/CD > Variables
|
||||
# In GitHub: Settings > Secrets > Actions
|
||||
|
||||
# Add variable:
|
||||
MODULE_REPO_TOKEN: [your token from library.silverlabs.uk]</code></div>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Commit and push your code</strong>
|
||||
<div class="code-block"><code>git add .
|
||||
git commit -m "feat: Initial module implementation"
|
||||
git push</code></div>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Create a release tag</strong>
|
||||
<div class="code-block"><code>git tag v1.0.0
|
||||
git push --tags</code></div>
|
||||
</li>
|
||||
<li>
|
||||
<strong>Trigger publish</strong> from your CI/CD pipeline UI
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h3>Manual Publishing</h3>
|
||||
<div class="code-block"><code># 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"</code></div>
|
||||
</div>
|
||||
|
||||
<!-- Available Modules Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>📚 Available Modules</h2>
|
||||
<p>Browse and install modules from the SilverSHELL module repository:</p>
|
||||
|
||||
<div class="info-box">
|
||||
<strong>Module Repository:</strong> <a href="https://library.silverlabs.uk" target="_blank" style="color: #a78bfa;">library.silverlabs.uk</a>
|
||||
</div>
|
||||
|
||||
<h3>Featured Modules:</h3>
|
||||
<ul>
|
||||
<li><strong>Auth.Login</strong> - User authentication and login UI</li>
|
||||
<li><strong>Auth.Registration</strong> - User registration system</li>
|
||||
<li><strong>Auth.UserManagement</strong> - User administration</li>
|
||||
<li><strong>Auth.MyAccount</strong> - User profile management</li>
|
||||
<li><strong>ModuleBrowser</strong> - Browse and install modules from the UI</li>
|
||||
</ul>
|
||||
|
||||
<h3>Explore All Modules</h3>
|
||||
<div class="code-block"><code># 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</code></div>
|
||||
</div>
|
||||
|
||||
<!-- Resources Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>📖 Resources</h2>
|
||||
<ul>
|
||||
<li><strong>Module Repository API:</strong> <a href="https://library.silverlabs.uk/api/modules" target="_blank" style="color: #a78bfa;">https://library.silverlabs.uk/api/modules</a></li>
|
||||
<li><strong>Demo Application:</strong> <a href="https://demo.silverlabs.uk" target="_blank" style="color: #a78bfa;">https://demo.silverlabs.uk</a></li>
|
||||
<li><strong>GitLab Repository:</strong> <a href="https://gitlab.silverlabs.uk/silverlabs/silvershell" target="_blank" style="color: #a78bfa;">GitLab</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Support Section -->
|
||||
<div class="sdk-section">
|
||||
<h2>💬 Support</h2>
|
||||
<p>Need help? We're here for you:</p>
|
||||
<ul>
|
||||
<li><strong>Help Desk:</strong> <a href="https://helpdesk.silverlabs.uk" target="_blank" style="color: #a78bfa;">helpdesk.silverlabs.uk</a></li>
|
||||
<li><strong>Issues:</strong> <a href="https://gitlab.silverlabs.uk/silverlabs/silvershell/-/issues" target="_blank" style="color: #a78bfa;">GitLab Issues</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="/" class="back-link">← Back to SilverLabs Home</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
314
styles.css
Normal file
314
styles.css
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user