first commit

This commit is contained in:
Aji Setiaji
2025-05-27 21:43:01 +07:00
commit 8d984635af
30 changed files with 7314 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
<script>
let menuItems = [
{ name: "Beranda", icon: "🏠", url: "/" },
{ name: "Issues", icon: "📂", url: "/backoffice/issue" },
{ name: "Issue Member", icon: "📂", url: "/backoffice/issuemember" },
{ name: "Projects", icon: "📂", url: "/backoffice/project" },
{
name: "Purchase Orders",
icon: "📂",
url: "/backoffice/purchaseorder",
},
{ name: "Timesheets", icon: "📂", url: "/backoffice/timesheets" },
{ name: "Villa", icon: "📂", url: "/backoffice/villa" },
{ name: "Inventories", icon: "📂", url: "/backoffice/inventories" },
{ name: "Vendor", icon: "📂", url: "/backoffice/vendor" },
{ name: "Booking", icon: "📂", url: "/backoffice/booking" },
];
let active = "Purchase Orders";
</script>
<div class="w-64 h-screen bg-white border-r shadow-sm">
<div class=" p-8 border-b">
<h1 class="text-xl font-semibold text-gray-800">Backoffice</h1>
<p class="text-sm text-gray-500">Manage your application</p>
</div>
<ul class="p-2 space-y-1">
{#each menuItems as item}
<li>
<a
href={item.url}
class={`flex items-center gap-2 px-4 py-2 rounded transition-colors duration-150
${
active === item.name
? "bg-blue-100 text-blue-600 font-semibold"
: "text-gray-700 hover:bg-blue-50"
}`}
on:click={() => (active = item.name)}
>
<span class="text-xl">{item.icon}</span>
<span class="truncate">{item.name}</span>
</a>
</li>
{/each}
</ul>
</div>

View File

@@ -0,0 +1,57 @@
import { atom } from 'nanostores'
import {
type RowData,
type TableOptions,
type TableOptionsResolved,
createTable,
} from '@tanstack/table-core'
export const flexRender = <TProps extends object>(comp: any, props: TProps) => {
if (typeof comp === 'function') {
return comp(props)
}
return comp
}
export const useTable = <TData extends RowData>(
options: TableOptions<TData>
) => {
// Compose in the generic options to the user options
const resolvedOptions: TableOptionsResolved<TData> = {
state: {}, // Dummy state
onStateChange: () => { }, // noop
renderFallbackValue: null,
...options,
}
// Create a new table
const table = createTable<TData>(resolvedOptions)
// By default, manage table state here using the table's initial state
const state = atom(table.initialState)
// Subscribe to state changes
state.subscribe(currentState => {
table.setOptions(prev => ({
...prev,
...options,
state: {
...currentState,
...options.state,
},
// Similarly, we'll maintain both our internal state and any user-provided state
onStateChange: updater => {
if (typeof updater === 'function') {
const newState = updater(currentState)
state.set(newState)
} else {
state.set(updater)
}
options.onStateChange?.(updater)
},
}))
})
return table
}