Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-4116Done

motir.co serves the five tabs — Board, Items, Tree, Roadmap and Changelog

The five tab routes under app/p/[identifier]/, rendered inside the shell the page card ships, each against its endpoint on motir-core's public contract:

routeendpointshape
boardGET /api/public/p/{identifier}/board (new)the public board's columns
itemsGET …/items?cursor= (shipped)the lazy list + "Load more"
treeGET …/tree?parentId=&offset= (shipped)one level at a time; expand fetches the next
roadmapGET …/roadmap for the four columns (new), ?bucket=&cursor= per column (shipped)four columns, each paging independently
changelogGET …/changelog?cursor= (shipped)the paged log

Paging must survive without JavaScript wherever the shipped precedent does. app/explore/_components/Gallery.tsx pages with <a href="?cursor=…"> deliberately; follow that for the flat lists. The tree's expand and the roadmap's per-column "Load more" are genuinely interactive — draw the line where the design asset draws it, and say in the code which side each control is on.

Every tab owes its empty, loading and error states, from the design. The error state is the unreachable-public-API case (public-surface-hosts.md §8 cost 1), and it is per-tab: a roadmap column that fails to page must not blank the page.

Plan for real data, not a demo. The items list, the changelog and each roadmap column page; the tree levels page; a project with two thousand work items is the case the mirror products design for, and the endpoints already return cursors precisely so this surface can. A tab that loads everything is mis-built even where it currently looks fine.

Scope boundary: this card renders and pages. It adds no control that writes — the roadmap's VOTE is the act affordances card's, even though it appears on the roadmap. Where the design draws a vote control, this card renders the surface it will attach to and nothing else, and says so.

Acceptance criteria

  • /p/<identifier>/{board,items,tree,roadmap,changelog} each render for a logged-out visitor, inside the shell, with the correct tab marked current.
  • Each tab pages against its endpoint: Items and Changelog by cursor, the Tree one level at a time with expand, the Roadmap per column. A project with more rows than one page returns more on the next request, asserted in a test per tab.
  • The flat-list pagers work with JavaScript disabled, matching the /explore precedent, and the interactive ones are the ones the design asset marks interactive.
  • Each tab renders its empty, loading and API-unreachable states as the design draws them, and a failure inside one roadmap column does not blank the page.
  • Every read goes through lib/publicProject.ts; no direct fetch of APP_ORIGIN is written into a component, and no database client appears.
  • No write control ships in this card — a grep of the diff finds no POST — and the surfaces the vote will attach to are rendered.
  • Each tab's canonical and og:url name SITE_ORIGIN and its own path.
  • No file outside motir-marketing is touched.

Context refs

  • motir-marketing/app/explore/_components/Gallery.tsx — no-JS cursor paging, the precedent for the flat lists
  • motir-marketing/lib/explore.ts — the params/href model and the failed state
  • motir-core/app/api/public/p/[identifier]/{items,tree,roadmap,changelog}/route.ts — the shipped reads and their cursor errors
  • motir-core/lib/dto/publicProjects.tsPublicBoardDto, PublicRoadmapDto, PUBLIC_ROADMAP_BUCKET_KEYS, the item/changelog page shapes
  • motir-core/app/(public)/p/[identifier]/{board,items,tree,roadmap,changelog}/page.tsx @ 95a2d4468^ — prior art only
  • motir-marketing/design/public-projects/ — the five tab boards and their states