Skip to main content

Code your first feature

Prerequisite

We assume you created successfuly your first project on Marblism, you cloned the API and Client repos and the API and Client are running on your computer. If not, it's time to Get Started.

Generated pages

When you clone your generated codebase, you have already all the API functions generated for all your database entities + a few pages developed. The best way to get comfortable with your new codebase and make it yours is to explore the generated pages in the front-end /src/app/(authenticated)/ and start playing with them.

info

The AI-generated pages usually work well, but occasionally they might do something surprising. Fortunately, this tutorial is here to help you effortlessly address any little quirks you come across.

Quick tutorials

Using our twitter-like generated app as an example, let's go through quick tutorials to get you up and running fast.

Create a new page

As an example, we are going to code the profile feed page to show all the tweets from a specific user:

  • Create a new folder /users in /web/app/(authenticated)
  • Create a new folder /[id] in /users
  • Create a new page page.tsx in the /users/[:id] directory
/src
/app
/(authenticated)
/users
/[id]
page.tsx

This page will be accessible from this URL https://localhost/users/[id], replacing the [id] by any user id.

Layout

Let's display a Hello World.

// 'use client' is mandatory for nextJS to work
'use client'

import { PageLayout } from '@/layouts/Page.layout'
import { Typography } from 'antd'

const { Title } = Typography

export default function UserFeedPage() {
return (
// PageLayout is the main layout with the nav bar, you can set it to full-width, narrow or super-narrow
<PageLayout variant="narrow">
<Title level={1}>Hello World!</Title>
</PageLayout>
)
}

Fetch URL params

import { useParams } from 'next/navigation'

const params = useParams<any>()

// access the :id in the url /users/[:id]
console.log(params.id)

Fetch the data

Let's now fetch the tweets and include the comments and the associated users in one query.

const [tweets, setTweets] = useState<Tweet[]>([])

useEffect(() => {
async function fetchTweets() {
try {
const tweetsData = await Api.Tweet.findManyByUserId(params.id, {
includes: ['comments', 'comments.user'],
})
setTweets(tweetsData)
} catch (error) {
console.log('Failed to fetch the tweets.')
}
}

fetchTweets()
}, [userId])

To know more about all the available endpoints and how to query, read this tutorial.

info

By default we generate all the basic Endpoint you need per entity, to create additional API endpoints, read this tutorial.

Display the tweets

Let's use a few components from the design system to display the tweets.

export default function UserFeedPage() {
return (
<PageLayout layout="narrow">
<Row gutter={[16, 16]}>
{tweets.map(tweet => (
<Col key={tweet.id} xs={24}>
<Card>
<Card.Header>
<Row align="middle" gutter={8}>
<Col span={6}>
<Avatar src={tweet.user?.pictureUrl || ''}>
{tweet.user?.name[0]}
</Avatar>
</Col>
<Col flex="auto">
<Typography.Title level={3}>
{dayjs(user.dateCreated).format('DD/MM/YYYY HH:mm')}
</Typography.Title>
</Col>
</Row>
</Card.Header>
<Card.Body>
<Typography.Text>{tweet.content}</Typography.Text>
</Card.Body>
</Card>
</Col>
))}
</Row>
</PageLayout>
)
}

Display a date

Display a date in a human-friendly format.

{
dayjs(user.dateCreated).format('DD/MM/YYYY HH:mm')
}
<Button onClick={() => router.push(`/user/${tweet.user?.id}`)}>
User profile
</Button>

Create a form

const [form] = Form.useForm()

<Form
onFinish={handleCommentSubmit}
form={form}
>
<Form.Item>
<TextArea rows={4} name="comment" />
</Form.Item>
<Form.Item>
<Button htmlType="submit" type="primary">
Add Comment
</Button>
</Form.Item>
</Form>

Send data to the API

const handleCommentSubmit = async (values: any) => {
try {
await Api.Comment.createOneByTweetId(item.id, {
content: values.comment,
userId: authentication.user?.id,
})
} catch (error) {
console.log('Failed to add comment')
}
}