Nuxt

1. Setup JamAIBase project.

  • Create a new project.

  • Get the Project ID.

  • Create JamAI API Key at Organization > Secrets > Create API Key.

2. Create a Nuxt app

npx nuxi init jamai-example-app
cd jamai-example-app
npm install

3. Install the JamAI Base client library, jamaibase

npm install jamaibase

4. Create a .env file at the root or your project and add the keys

PUBLIC_JAMAI_BASEURL=http://api.jamaibase.com/
JAMAI_API_KEY=your_jamai_sk_api_key
JAMAI_PROJECT_ID=your_proj_id

5. In the nuxt.config.ts file add runtimeConfig to use the environment variables

runtimeConfig: {
        JAMAI_API_KEY: process.env.JAMAI_API_KEY,
        public: {
            JAMAI_BASEURL: process.env.JAMAI_BASEURL,
            JAMAI_PROJECT_ID: process.env.JAMAI_PROJECT_ID,
        },
    },

6. Create a page to list tables

We will create a page to list the tables from the project.

Create a new file pages/index.vue and add the following code:

<template>
    <main>
        <div class="container">
            <label>Choose Table Type:</label>
            <select v-model="tableType" @change="fetchTables">
                <option value="action">Action</option>
                <option value="chat">Chat</option>
                <option value="knowledge">Knowledge</option>
            </select>
        </div>

        <div class="container">
            <h1>List of Tables</h1>
            <table>
                <thead>
                    <tr>
                        <th>Table ID</th>
                        <th>Columns</th>
                        <th>Column Type</th>
                        <th>Number of Rows</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="table in tableData.items" :key="table.id">
                        <td>{{ table.id }}</td>
                        <td>
                            <ul>
                                <li
                                    v-for="column in table.cols"
                                    :key="column.id"
                                >
                                    {{ column.id }}: {{ column.dtype }}
                                </li>
                            </ul>
                        </td>
                        <td>
                            <ul>
                                <li
                                    v-for="column in table.cols"
                                    :key="column.id"
                                >
                                    {{ column.gen_config ? "Output" : "Input" }}
                                </li>
                            </ul>
                        </td>
                        <td>{{ table.num_rows }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </main>
</template>

<script setup>
import { ref, onMounted } from "vue";

const tableType = ref("action");
const tableData = ref({ items: [] });

async function fetchTables() {
    const response = await $fetch(`/api/list-tables?type=${tableType.value}`);

    if (response.success) {
        tableData.value = response.data;
    } else {
        console.error("Failed to fetch data");
    }
}

onMounted(() => {
    fetchTables();
});
</script>

Add the following CSS to make the UI look better:

<style scoped>
/* Main layout styling */
main {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: 24px;
}

/* Container styling */
.container {
    max-width: 600px;
    margin: 40px auto;
    padding: 20px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* Label and select input styling */
label {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: #333;
}

select {
    display: block;
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #fff;
    margin-bottom: 20px;
    font-size: 14px;
}

/* Table styling */
table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
}

th,
td {
    padding: 12px;
    border: 1px solid #ddd;
    text-align: left;
}

th {
    background-color: #f4f4f4;
    font-weight: 600;
}

tr:nth-child(even) {
    background-color: #f9f9f9;
}

tr:hover {
    background-color: #f1f1f1;
}

/* Responsive styling */
@media (max-width: 600px) {
    .container {
        padding: 10px;
    }

    table,
    th,
    td {
        font-size: 12px;
    }

    th,
    td {
        padding: 8px;
    }
}
</style>

7. Create server handler to fetch tables:

create a new handler at server/api/list-tables.js and add the following code:

import JamAI from "jamaibase";

const {
    JAMAI_API_KEY,
    public: { JAMAI_BASEURL, JAMAI_PROJECT_ID },
} = useRuntimeConfig();

const jamai = new JamAI({
    baseURL: JAMAI_BASEURL,
    apiKey: JAMAI_API_KEY,
    projectId: JAMAI_PROJECT_ID,
});

export default defineEventHandler(async (event) => {
    const { type = "action" } = getQuery(event);

    try {
        const data = await jamai.listTables({ table_type: type });
        return { success: true, data: data };
    } catch (error) {
        console.error("Error fetching tables:", error);
        return { success: false, data: "Something went wrong" };
    }
});

8. Create a page to create new action table

We will create a UI that will create a new action table.

Create a new file server/api/create-table.js and add the following code:

<template>
    <main>
        <h1>Create Action Table</h1>

        <div v-if="form.success">
            <p>Successfully created the table.</p>
        </div>
        <div v-else-if="form.error">
            <p>Sorry, something went wrong!</p>
        </div>

        <form @submit.prevent="submitForm">
            <label>
                Table ID
                <input v-model="tableId" />
            </label>
            <label>
                Column Name
                <input v-model="columnName" />
            </label>
            <label>
                Column Data Type
                <select v-model="columnDType">
                    <option value="str">str</option>
                    <option value="int">int</option>
                    <option value="float">float</option>
                    <option value="bool">bool</option>
                </select>
            </label>
            <button type="submit">Create</button>
        </form>
    </main>
</template>

<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";

const tableId = ref("");
const columnName = ref("");
const columnDType = ref("str");
const form = ref({ success: false, error: false });
const router = useRouter();

async function submitForm() {
    const { data } = useFetch("/api/create-table", {
        method: "post",
        headers: {
            "Content-Type": "application/json",
        },
        body: {
            table_id: tableId.value,
            column_name: columnName.value,
            column_d_type: columnDType.value,
        },
    });

    if (data.value?.success) {
        form.value.success = true;
        form.value.error = false;
    } else {
        form.value.success = false;
        form.value.error = true;
    }
}
</script>

9. Create an API to create a new table

Create a server handler at server/api/create-table.js to accept the request and create a new table:

import JamAI from "jamaibase";

const {
    JAMAI_API_KEY,
    public: { JAMAI_BASEURL, JAMAI_PROJECT_ID },
} = useRuntimeConfig();

const jamai = new JamAI({
    baseURL: JAMAI_BASEURL,
    apiKey: JAMAI_API_KEY,
    projectId: JAMAI_PROJECT_ID,
});

export default defineEventHandler(async (event) => {
    const { table_id, column_name, column_d_type } = await readBody(event);

    try {
        const response = await jamai.createActionTable({
            id: table_id,
            cols: [{ id: column_name, dtype: column_d_type }],
        });

        return { success: true, data: response };
    } catch (error) {
        console.error("error: ", error.response);
        return { success: false, message: "Something went wrong!" };
    }
});

10. Add default layout

Finally, create a defalut layout (layouts/defalut.vue) to navigate between pages:

<template>
    <div>
        <nav>
            <ul>
                <li><NuxtLink to="/">Home</NuxtLink></li>
                <li><NuxtLink to="/create-table">Create Table</NuxtLink></li>
            </ul>
        </nav>
        <slot />
    </div>
</template>

<script setup></script>

<style scoped>
nav {
    background-color: #f8f9fa;
    padding: 10px;
}

nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    gap: 20px;
}

nav ul li {
    display: inline;
}

nav a {
    text-decoration: none;
    color: #007bff;
}

nav a:hover {
    text-decoration: underline;
}
</style>

12. Start the app

Start the app and go to http://localhost:3000 in a browser and you should see the list of tables in your project.

npm run dev

Last updated