shell-mirror
Version:
Access your Mac shell from any device securely. Perfect for mobile coding with Claude Code CLI, Gemini CLI, and any shell tool.
106 lines (96 loc) • 4.63 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shell Mirror Dashboard</title>
<!-- Google Analytics 4 -->
<script>
// Initialize dataLayer and gtag function first
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-LG7ZGLB8FK');
// Load gtag script with proper error handling
(function() {
var script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK';
script.onload = function() {
console.log('✅ Google Analytics script loaded successfully');
window.gtagLoaded = true;
};
script.onerror = function() {
console.warn('❌ Failed to load Google Analytics script');
window.gtagLoaded = false;
};
document.head.appendChild(script);
})();
// Google Analytics helper function
function sendGAEvent(eventName, eventParams) {
if (typeof gtag === 'function') {
console.log('📊 [GA] Sending event:', eventName, eventParams);
gtag('event', eventName, eventParams);
return true;
} else {
console.warn('❌ [GA] gtag not available, event not sent:', eventName);
return false;
}
}
</script>
<!-- Microsoft Clarity -->
<script type="text/javascript">
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "sy1w2d7il7");
</script>
<link rel="stylesheet" href="dashboard.css">
</head>
<body>
<!-- Header -->
<header class="dashboard-header">
<div class="header-content">
<div class="logo">
<a href="/" style="text-decoration: none; color: inherit;">
<h1>Shell Mirror</h1>
</a>
</div>
<div class="header-right">
<div class="user-section" id="user-section">
<!-- Dynamic content based on auth status -->
</div>
</div>
</div>
</header>
<!-- Main Dashboard Content -->
<main class="dashboard-main" id="dashboard-main">
<!-- Will be populated by JavaScript based on auth status -->
</main>
<!-- Centered Login Button (for unauthenticated users) -->
<div class="login-button-overlay" id="login-button-overlay" style="display: none;">
<div class="centered-login">
<button class="btn-primary large" onclick="handleLogin()">
<svg width="20" height="20" viewBox="0 0 24 24" style="margin-right: 8px;">
<path fill="white" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/>
<path fill="white" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/>
<path fill="white" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/>
<path fill="white" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/>
</svg>
Login with Google Account
</button>
</div>
</div>
<!-- Loading indicator -->
<div class="loading-overlay" id="loading-overlay">
<div class="loading-spinner"></div>
<p>Loading dashboard...</p>
</div>
<!-- Version Footer -->
<footer id="version-footer" style="background: var(--bg-secondary, #141519); color: var(--text-secondary, #8a8f98); text-align: center; padding: 8px 0; font-size: 0.75rem; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000; border-top: 1px solid var(--border, #2a2b30);">
<p id="dashboard-version-info" style="margin: 0;">Shell Mirror • Loading...</p>
</footer>
<script src="dashboard.js"></script>
</body>
</html>