home.tsximport { o } from '../jsx/jsx.js'
import { prerender } from '../jsx/html.js'
import SourceCode from '../components/source-code.js'
import { Routes } from '../routes.js'
import { title } from '../../config.js'
import { mapArray } from '../components/fragment.js'
import Style from '../components/style.js'
import { Link } from '../components/router.js'
import { proxy } from '../../../db/proxy.js'
import { count, filter } from 'better-sqlite3-proxy'
import { toRouteUrl } from '../../url.js'
import Model from './editor.js'
import DateTimeText from '../components/datetime.js'
import { getTimes } from '../../../db/helper.js'
import { DAY } from '@beenotung/tslib/time.js'
import { Button } from '../components/button.js'
import editor from './editor.js'
import { getModelName } from '../models/name.js'// Calling <Component/> will transform the JSX into AST for each rendering.
// You can reuse a pre-compute AST like `let component = <Component/>`.
// If the expression is static (not depending on the render Context),
// you don't have to wrap it by a function at all.
let style = Style(/* css */ `
.multimodal-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.multimodal-box {
border: 1px solid black;
border-radius: 0.5rem;
padding: 0.5rem;
}
.multimodal-title {
font-weight: bold;
font-size: 1.5rem;
}
.multimodal-title i {
font-size: 2rem;
}
.multimodal-items {
display: flex;
flex-wrap: wrap;
}
.multimodal-item {
margin: 0.2rem;
padding: 0.25rem 0.5rem;
font-size: 1.2rem;
}
.model-list,
.dataset-list {
}
.model-item,
.dataset-item {
margin: 0.5rem;
}
.time {
opacity: 0.7;
font-size: 0.9rem;
}
`)
let page = (
<>
{style}
<Main />
</>
)
function Main() {
return (
<div id="home">
<h1>AI Models</h1>
<h2>Create a Model</h2>
<div class="multimodal-list">
{mapArray(proxy.model_category, category => (
<div class="multimodal-box">
<div class="multimodal-title">
<i class={category.icon}></i> {category.title}
</div>
<div class="multimodal-items">
{mapArray(
filter(proxy.model_type, { model_category_id: category.id! }),
model_type => (
<Link
tagName="button"
href={toRouteUrl(
Model.routes,
'/model/:model_type_slug/add',
{
params: { model_type_slug: model_type.slug },
},
)}
class="multimodal-item"
>
{model_type.name}
</Link>
),
)}
</div>
</div>
))}
</div>
<h2>Existing Models</h2>
<div class="model-list">
{mapArray(
proxy.model.slice().sort((a, b) => b.id! - a.id!),
model => {
let times = getTimes(model)
return (
<div class="model-item">
<Link
href={toRouteUrl(Model.routes, '/editor', {
query: {
model_id: model.id,
},
})}
>
#{model.id} {getModelName(model)}{' '}
{model.is_classifier ? 'Classifier' : 'Regression Model'}
</Link>
<div class="time">
Created{' '}
<DateTimeText
time={times.created_at}
relativeTimeThreshold={7 * DAY}
/>
</div>
{times.created_at.getTime() != times.updated_at.getTime() ? (
<div class="time">
Updated{' '}
<DateTimeText
time={times.updated_at}
relativeTimeThreshold={7 * DAY}
/>
</div>
) : null}
</div>
)
},
)}
</div>
<h1>Datasets</h1>
<Button
url={toRouteUrl(editor.routes, '/dataset/add')}
class="add-button"
>
Create a Dataset
</Button>
<h2>Existing Datasets</h2>
<div class="dataset-list">
{mapArray(
proxy.dataset.slice().sort((a, b) => b.id! - a.id!),
dataset => {
let times = getTimes(dataset)
let used = count(proxy.model, { dataset_id: dataset.id })
return (
<div class="dataset-item">
<Link
href={toRouteUrl(Model.routes, '/editor', {
query: {
dataset_id: dataset.id,
},
})}
>
#{dataset.id} {dataset.name}{' '}
{dataset.is_classifier
? 'Classification Dataset'
: 'Regression Dataset'}
</Link>
<div>Used by {used} model(s)</div>
<div class="time">
Created{' '}
<DateTimeText
time={times.created_at}
relativeTimeThreshold={7 * DAY}
/>
</div>
{times.created_at.getTime() != times.updated_at.getTime() ? (
<div class="time">
Updated{' '}
<DateTimeText
time={times.updated_at}
relativeTimeThreshold={7 * DAY}
/>
</div>
) : null}
</div>
)
},
)}
</div>
<SourceCode page="home.tsx" />
</div>
)
}
let routes = {
'/': {
title: title('Home'),
description:
'Explore available AI models and datasets with the Feelings AI Builder editor. Clone existing models and apply transfer learning with your custom datasets to create tailored AI solutions.',
menuText: 'Home',
node: page,
},
} satisfies Routes
export default { routes }