forked from manifoldmarkets/manifold
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dashboard starting (manifoldmarkets#2018)
* dashboard starting
- Loading branch information
Showing
14 changed files
with
358 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { createSupabaseDirectClient } from 'shared/supabase/init' | ||
import { log } from 'shared/utils' | ||
import { z } from 'zod' | ||
import { APIError, authEndpoint, validate } from './helpers' | ||
import { contentSchema } from 'shared/zod-types' | ||
import { slugify } from 'common/util/slugify' | ||
import { randomString } from 'common/util/random' | ||
|
||
const schema = z.object({ | ||
title: z.string(), | ||
description: contentSchema.optional(), | ||
}) | ||
|
||
export const createdashboard = authEndpoint(async (req, auth) => { | ||
const { title, description } = validate(schema, req.body) | ||
|
||
log('creating dashboard') | ||
const pg = createSupabaseDirectClient() | ||
|
||
let slug = slugify(title) | ||
const data = await pg.manyOrNone( | ||
`select slug from dashboards where slug = $1`, | ||
[slug] | ||
) | ||
|
||
if (data && data.length > 0) { | ||
slug = `${slug}-${randomString(8)}` | ||
} | ||
|
||
// create if not exists the group invite link row | ||
const { id } = await pg.one( | ||
`insert into dashboards(slug, creator_id, description, title) | ||
values ($1, $2, $3,$4) | ||
returning id, slug`, | ||
[slug, auth.uid, description, title] | ||
) | ||
|
||
// return something | ||
return { id: id, slug: slug } | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
create table if not exists | ||
dashboards ( | ||
id text not null primary key default random_alphanumeric (12), | ||
slug text not null unique, | ||
creator_id text not null, | ||
foreign key (creator_id) references users (id), | ||
created_time timestamptz not null default now(), | ||
views numeric not null default 0, | ||
description json, | ||
title text not null | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { JSONContent } from '@tiptap/core' | ||
|
||
export type Dashboard = { | ||
id: string | ||
slug: string | ||
creator_id: string | ||
created_time: number | ||
views: number | ||
description: JSONContent | ||
title: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { SupabaseClient } from '@supabase/supabase-js' | ||
import { run } from './utils' | ||
|
||
export async function getDashboardFromSlug(slug: string, db: SupabaseClient) { | ||
const { data: dashboard } = await run( | ||
db.from('dashboards').select('*').eq('slug', slug).limit(1) | ||
) | ||
|
||
if (dashboard && dashboard.length > 0) { | ||
return dashboard[0] | ||
} | ||
return null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import clsx from 'clsx' | ||
import Link from 'next/link' | ||
import { buttonClass } from '../buttons/button' | ||
|
||
export function CreateDashboardButton() { | ||
return ( | ||
<> | ||
<Link | ||
href="/dashboard/create" | ||
className={clsx(buttonClass('md', 'indigo'))} | ||
> | ||
Create a dashboard | ||
</Link> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { JSONContent } from '@tiptap/core' | ||
import { JSONEmpty } from '../contract/contract-description' | ||
import { Col } from '../layout/col' | ||
import { Content } from '../widgets/editor' | ||
import clsx from 'clsx' | ||
|
||
export const DashboardSidebar = (props: { | ||
description?: JSONContent | ||
inSidebar?: boolean | ||
}) => { | ||
const { description, inSidebar } = props | ||
|
||
if (!description || JSONEmpty(description)) return <></> | ||
|
||
return ( | ||
<Col className={clsx(inSidebar ? 'hidden xl:inline-flex' : 'xl:hidden')}> | ||
{description && ( | ||
<Col className=" text-primary-700 mb-2 hidden xl:inline-flex"> | ||
Additional Context | ||
</Col> | ||
)} | ||
{description && ( | ||
<> | ||
<Col className="bg-canvas-0 mb-4 gap-2 py-2 px-4 xl:px-6 xl:py-4"> | ||
<Content content={description} /> | ||
</Col> | ||
</> | ||
)} | ||
</Col> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Dashboard } from 'common/dashboard' | ||
import { getDashboardFromSlug } from 'common/supabase/dashboard' | ||
import { DashboardSidebar } from 'web/components/dashboard/dashboard-sidebar' | ||
import { Col } from 'web/components/layout/col' | ||
import { Page } from 'web/components/layout/page' | ||
import { NewsSidebar } from 'web/components/news/news-dashboard' | ||
import { Content } from 'web/components/widgets/editor' | ||
import { Title } from 'web/components/widgets/title' | ||
import { db } from 'web/lib/supabase/db' | ||
|
||
export async function getStaticProps(ctx: { | ||
params: { dashboardSlug: string } | ||
}) { | ||
const { dashboardSlug } = ctx.params | ||
|
||
try { | ||
const dashboard: Dashboard = await getDashboardFromSlug(dashboardSlug, db) | ||
return { props: { dashboard } } | ||
} catch (e) { | ||
if (typeof e === 'object' && e !== null && 'code' in e && e.code === 404) { | ||
return { | ||
props: { state: 'not found' }, | ||
revalidate: 60, | ||
} | ||
} | ||
throw e | ||
} | ||
} | ||
|
||
export async function getStaticPaths() { | ||
return { paths: [], fallback: 'blocking' } | ||
} | ||
|
||
export default function DashboardPage(props: { dashboard: Dashboard }) { | ||
const { dashboard } = props | ||
return ( | ||
<Page | ||
rightSidebar={ | ||
<DashboardSidebar description={dashboard.description} inSidebar /> | ||
} | ||
> | ||
<Col className="items-center"> | ||
<Col className="w-full max-w-2xl px-1 sm:px-2"> | ||
<Title className="mt-4">{dashboard.title}</Title> | ||
<DashboardSidebar description={dashboard.description} /> | ||
</Col> | ||
</Col> | ||
</Page> | ||
) | ||
} |
Oops, something went wrong.