Initial commit
This commit is contained in:
128
frontend/src/routes/Home.svelte
Normal file
128
frontend/src/routes/Home.svelte
Normal file
@@ -0,0 +1,128 @@
|
||||
<script>
|
||||
import { fetchMetadata, verifyPassword } from '../lib/api.js'
|
||||
|
||||
let cxidInput = $state('')
|
||||
let passwordInput = $state('')
|
||||
let needsPassword = $state(false)
|
||||
let loading = $state(false)
|
||||
let error = $state('')
|
||||
|
||||
async function submit() {
|
||||
error = ''
|
||||
if (!cxidInput.trim()) return
|
||||
loading = true
|
||||
try {
|
||||
const meta = await fetchMetadata(cxidInput.trim())
|
||||
if (meta.has_password && !passwordInput) {
|
||||
needsPassword = true
|
||||
loading = false
|
||||
return
|
||||
}
|
||||
if (meta.has_password) {
|
||||
const ok = await verifyPassword(cxidInput.trim(), passwordInput)
|
||||
if (!ok) {
|
||||
error = 'Incorrect password.'
|
||||
loading = false
|
||||
return
|
||||
}
|
||||
}
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.set('cxid', cxidInput.trim())
|
||||
if (passwordInput) url.searchParams.set('sc', passwordInput)
|
||||
history.pushState({}, '', url.toString())
|
||||
window.dispatchEvent(new PopStateEvent('popstate'))
|
||||
} catch (e) {
|
||||
error = e.message || 'Content not found.'
|
||||
loading = false
|
||||
}
|
||||
}
|
||||
|
||||
function onKeydown(e) {
|
||||
if (e.key === 'Enter') submit()
|
||||
}
|
||||
</script>
|
||||
|
||||
<main class="home">
|
||||
<div class="hero">
|
||||
<h1 class="retro-heading">CG.CX</h1>
|
||||
<p class="tagline">Secure content sharing</p>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
<label for="cxid">Content ID</label>
|
||||
<input id="cxid" type="text" bind:value={cxidInput} placeholder="Enter content ID..." onkeydown={onKeydown} />
|
||||
|
||||
{#if needsPassword}
|
||||
<label for="pw">Password</label>
|
||||
<input id="pw" type="password" bind:value={passwordInput} placeholder="Enter password..." onkeydown={onKeydown} />
|
||||
{/if}
|
||||
|
||||
{#if error}
|
||||
<p class="error">{error}</p>
|
||||
{/if}
|
||||
|
||||
<button onclick={submit} disabled={loading}>
|
||||
{loading ? 'Loading...' : '[ Unlock ]'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>Developed by <a href="https://t.me/forgecadrape" target="_blank" rel="noopener">@forgecadrape</a></p>
|
||||
<p>portfolio <a href="https://kittens.rip/" target="_blank" rel="noopener">kittens.rip</a></p>
|
||||
<p class="footer-small">Created with <3 in Europe<br/>@2026 <a href="https://cg.cx/">cg.cx</a></p>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.home {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
gap: 32px;
|
||||
}
|
||||
.hero {
|
||||
text-align: center;
|
||||
}
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
color: var(--retro-green-light);
|
||||
margin-top: 8px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
.panel {
|
||||
width: min(400px, 100%);
|
||||
background: var(--retro-panel);
|
||||
border: 3px solid var(--retro-border);
|
||||
padding: 24px;
|
||||
box-shadow: 6px 6px 0px var(--retro-shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.panel label {
|
||||
font-family: 'Press Start 2P', cursive;
|
||||
font-size: 0.55rem;
|
||||
color: var(--retro-green);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.error {
|
||||
color: var(--retro-danger);
|
||||
font-size: 1rem;
|
||||
}
|
||||
footer {
|
||||
text-align: center;
|
||||
font-size: 0.95rem;
|
||||
color: #555;
|
||||
}
|
||||
footer p {
|
||||
margin: 4px 0;
|
||||
}
|
||||
.footer-small {
|
||||
font-size: 0.85rem;
|
||||
margin-top: 12px;
|
||||
color: #777;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user