kafka-dance-site/src/routes/+page.svelte

284 lines
6.9 KiB
Svelte

<script>
import logo from '$lib/kd-full-logo.png';
import Todo from "$lib/Todo.svelte";
const id = 'a59038fa-5098-4e7a-836b-f62342ac445b'
const id2 = '1b581662-2f49-4307-af93-fcd97a1dbd8e'
const repeat = (arr, n) => [].concat(...Array(n).fill(arr));
const stringy = o => o && JSON.stringify(o, null, 2)
const fakeObjects = repeat([
JSON.parse(`{
"eventType": "purchase",
"username": "sagev",
"itemName": "Bean Enchilada",
"quantity": 2,
"purchaseId": "${id}"
}`),
JSON.parse(`{
"eventType": "purchase",
"username": "cameronl",
"itemName": "Taco",
"quantity": 7,
"purchaseId": "${id2}"
}`),
JSON.parse(`{
"eventType": "refund",
"username": "sagev",
"refundStatus": "APPROVED",
"approvedBy": "westonm",
"purchaseId": "${id}"
}`)
], 3)
let realTimeIndex = 0
const randomizeRealTime = () => setTimeout(() => {
realTimeIndex = (realTimeIndex + 1) % fakeObjects.length
randomizeRealTime()
}, 1500)
randomizeRealTime()
let line = 0
let oneShotText = JSON.stringify(fakeObjects[0])
const loadingColor = '#df5dcf'
let oneShotColor = loadingColor
const blockLines = 7
const fakeJsonLines = fakeObjects.map(o => JSON.stringify(o, null, 2)).join('\n').split('\n')
const randomizeOneShot = (wait = 30) => setTimeout(() => {
if (line < fakeJsonLines.length - blockLines) {
line += 1
oneShotColor = loadingColor
oneShotText = fakeJsonLines.slice(line, line + blockLines).join('\n')
randomizeOneShot()
} else {
line = 0
oneShotColor = 'var(--accent-color)'
randomizeOneShot(4000)
}
}, wait)
randomizeOneShot()
const filterTexts = [
'message.approvedBy === "westonm"',
'message.itemName.includes("Bean")',
'message.quantity > 4',
]
let filterTextIndex = 0
$: filterFunc = text => {
try {
return new Function('message', 'return ' + filterTexts[filterTextIndex])(text)
} catch (e) {
return undefined
}
}
$: filteredObject = stringy(fakeObjects.filter(filterFunc)[0]) || 'No results found.'.padEnd(50)
const nextFilterText = () => setTimeout(() => {
filterTextIndex = (filterTextIndex + 1) % filterTexts.length
nextFilterText()
}, 2800)
nextFilterText()
</script>
<div class="logo-json-box">
<!--
<img src="/json.png" alt="With Kafka Dance, browsing Kafka data is easy" />
-->
</div>
<div class="content">
<div class="eye-catch">
<h1>Data should be <span class="fun">Fun</span></h1>
<h2 class="with-kafka-dance">With <span><img class="inline-logo" src={logo} alt="Kafka Dance" />,</span> it is.</h2>
<div class="button-container">
<a href="/download"><button class="colored">Download Now</button></a>
</div>
<Todo>
Push 'What is Kafka Dance?' down further, but come up with a visual indicator that there's
more to read. Something like this, but better:
</Todo>
</div>
<div class="column">
<h3 class="continue-reading">Read how<br><br><span class="pulse">V</span></h3>
<h2>What is Kafka Dance?</h2>
<h3>Kafka Dance is a simple, elegant way to interact with your Kafka servers.</h3>
<a href="/example_query.png">
<img class="big-photo" src="/example_query.png" alt="Example query" />
</a>
</div>
<div>
<h2>Query data your way</h2>
<div class="data-display">
<div class="data-display-section">
<h3>Search your message history</h3>
<pre style={`color: ${oneShotColor}`};>{oneShotText}</pre>
</div>
<div class="data-display-section real-time-display">
<h3>Or monitor in real time</h3>
<pre>{JSON.stringify(fakeObjects[realTimeIndex], null, 2)}</pre>
</div>
</div>
</div>
<div>
<h2>Flexible search</h2>
<h3>Powered by Javascript</h3>
<div class="data-display">
<div class="data-display-section">
<pre style="width: 90%; margin-top: 0; padding-bottom: 0.5em; border-bottom: solid #fbc; border-radius: 0; border-width: 1px;"><span style="color: #533;">=&gt;</span> {filterTexts[filterTextIndex]}</pre>
<pre>{filteredObject}</pre>
</div>
</div>
</div>
</div>
<style>
h1 {
padding-top: 1em;
}
.with-kafka-dance span {
padding-right: 0.2em;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
}
.data-display-section h3 {
}
.data-display-section {
padding: 1em 1em 0;
border-radius: 4px;
border-style: solid;
border-width: 2px;
border-color: var(--accent-color);
margin: 1em;
}
.real-time-display {
background-color: var(--accent-color);
color: white;
}
.real-time-display pre {
background-color: var(--accent-color);
color: white;
}
pre {
max-width: 75vw;
overflow: hidden;
}
h2 {
flex-wrap: wrap;
font-size: 4rem;
color: black;
margin: 2em 0.5em 0.5em;
}
h3 {
margin-left: 2em;
margin-right: 2em;
}
.content {
text-align: left;
display: flex;
align-items: center;
flex-direction: column;
margin-bottom: 2em;
}
.column {
display: flex;
flex-direction: column;
align-items: center;
}
.eye-catch {
margin-bottom: 1em;
}
.eye-catch h2 {
font-size: 1.5rem;
}
h2 {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
}
img.inline-logo {
height: 2em;
object-fit: contain;
padding-bottom: 0.5em;
padding-left: 0.2em;
padding-right: 0.05em;
}
img.big-photo {
display: inline-block;
/*max-width: 40vw;*/
/*max-height: 50vw;*/
margin-top: 2em;
max-width: 60vw;
height: auto;
}
pre {
color: var(--accent-color);
font-weight: bold;
box-shadow: none;
}
.button-container {
margin-top: 6em;
}
.logo-json-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.data-display {
display: flex;
flex-wrap: wrap;
flex-direction: column;
justify-content: center;
}
.data-display h3 {
margin-left: 0;
margin-right: 0;
}
.continue-reading {
display: none;
}
@media (min-width: 720px) {
.eye-catch h2 {
font-size: 2rem;
}
.data-display {
flex-direction: row;
}
img.big-photo {
width: 70vw;
}
.continue-reading {
display: block;
text-align: center;
margin-top: 10em;
}
}
</style>