@commonpub/layer 0.10.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/components/EventCard.vue +121 -0
  2. package/components/PollDisplay.vue +108 -0
  3. package/components/PostVoteButtons.vue +108 -0
  4. package/components/contest/ContestJudgeManager.vue +110 -0
  5. package/components/homepage/ContentGridSection.vue +133 -0
  6. package/components/homepage/ContestsSection.vue +39 -0
  7. package/components/homepage/CustomHtmlSection.vue +20 -0
  8. package/components/homepage/EditorialSection.vue +32 -0
  9. package/components/homepage/HeroSection.vue +73 -0
  10. package/components/homepage/HomepageSectionRenderer.vue +64 -0
  11. package/components/homepage/HubsSection.vue +66 -0
  12. package/components/homepage/StatsSection.vue +38 -0
  13. package/components/nav/MobileNavRenderer.vue +94 -0
  14. package/components/nav/NavDropdown.vue +101 -0
  15. package/components/nav/NavLink.vue +40 -0
  16. package/components/nav/NavRenderer.vue +51 -0
  17. package/composables/useFeatures.ts +2 -0
  18. package/layouts/admin.vue +3 -0
  19. package/layouts/default.vue +22 -86
  20. package/middleware/feature-gate.global.ts +1 -0
  21. package/package.json +6 -6
  22. package/pages/admin/features.vue +338 -0
  23. package/pages/admin/homepage.vue +292 -0
  24. package/pages/admin/navigation.vue +350 -0
  25. package/pages/events/[slug]/edit.vue +182 -0
  26. package/pages/events/[slug]/index.vue +249 -0
  27. package/pages/events/create.vue +140 -0
  28. package/pages/events/index.vue +47 -0
  29. package/pages/index.vue +34 -1
  30. package/server/api/admin/features/index.get.ts +32 -0
  31. package/server/api/admin/features/index.put.ts +56 -0
  32. package/server/api/admin/homepage/sections.get.ts +11 -0
  33. package/server/api/admin/homepage/sections.put.ts +52 -0
  34. package/server/api/admin/navigation/items.get.ts +11 -0
  35. package/server/api/admin/navigation/items.put.ts +51 -0
  36. package/server/api/contests/[slug]/entries/[entryId]/vote.delete.ts +20 -0
  37. package/server/api/contests/[slug]/entries/[entryId]/vote.post.ts +20 -0
  38. package/server/api/contests/[slug]/judge.post.ts +5 -7
  39. package/server/api/contests/[slug]/judges/[userId].delete.ts +26 -0
  40. package/server/api/contests/[slug]/judges/accept.post.ts +21 -0
  41. package/server/api/contests/[slug]/judges/index.get.ts +17 -0
  42. package/server/api/contests/[slug]/judges/index.post.ts +36 -0
  43. package/server/api/events/[slug]/attendees.get.ts +23 -0
  44. package/server/api/events/[slug]/rsvp.delete.ts +23 -0
  45. package/server/api/events/[slug]/rsvp.post.ts +23 -0
  46. package/server/api/events/[slug].delete.ts +22 -0
  47. package/server/api/events/[slug].get.ts +17 -0
  48. package/server/api/events/[slug].put.ts +38 -0
  49. package/server/api/events/index.get.ts +21 -0
  50. package/server/api/events/index.post.ts +40 -0
  51. package/server/api/features.get.ts +9 -0
  52. package/server/api/homepage/sections.get.ts +10 -0
  53. package/server/api/hubs/[slug]/posts/[postId]/poll-options.get.ts +18 -0
  54. package/server/api/hubs/[slug]/posts/[postId]/poll-vote.post.ts +27 -0
  55. package/server/api/hubs/[slug]/posts/[postId]/vote.post.ts +21 -0
  56. package/server/api/navigation/items.get.ts +10 -0
  57. package/server/middleware/features.ts +1 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * GET /api/features
3
+ * Returns the current merged feature flags (build-time + env + DB overrides).
4
+ * Public endpoint — used by client-side useFeatures() for runtime reactivity.
5
+ */
6
+ export default defineEventHandler(() => {
7
+ const config = useConfig();
8
+ return config.features;
9
+ });
@@ -0,0 +1,10 @@
1
+ import { getHomepageSections } from '@commonpub/server';
2
+
3
+ /**
4
+ * GET /api/homepage/sections
5
+ * Returns the homepage section configuration (public).
6
+ */
7
+ export default defineEventHandler(async () => {
8
+ const db = useDB();
9
+ return getHomepageSections(db);
10
+ });
@@ -0,0 +1,18 @@
1
+ import { getPollOptions, getUserPollVote } from '@commonpub/server';
2
+
3
+ /**
4
+ * GET /api/hubs/:slug/posts/:postId/poll-options
5
+ * Get poll options and the user's vote (if authenticated).
6
+ */
7
+ export default defineEventHandler(async (event) => {
8
+ requireFeature('hubs');
9
+ const db = useDB();
10
+ const postId = getRouterParam(event, 'postId');
11
+ if (!postId) throw createError({ statusCode: 400, statusMessage: 'Missing postId' });
12
+
13
+ const options = await getPollOptions(db, postId);
14
+ const user = getOptionalUser(event);
15
+ const userVote = user ? await getUserPollVote(db, postId, user.id) : null;
16
+
17
+ return { options, userVote };
18
+ });
@@ -0,0 +1,27 @@
1
+ import { voteOnPoll } from '@commonpub/server';
2
+ import { z } from 'zod';
3
+
4
+ const pollVoteSchema = z.object({
5
+ optionId: z.string().uuid(),
6
+ });
7
+
8
+ /**
9
+ * POST /api/hubs/:slug/posts/:postId/poll-vote
10
+ * Vote on a poll option.
11
+ */
12
+ export default defineEventHandler(async (event) => {
13
+ requireFeature('hubs');
14
+ const user = requireAuth(event);
15
+ const db = useDB();
16
+ const postId = getRouterParam(event, 'postId');
17
+ if (!postId) throw createError({ statusCode: 400, statusMessage: 'Missing postId' });
18
+
19
+ const body = await parseBody(event, pollVoteSchema);
20
+ const result = await voteOnPoll(db, postId, body.optionId, user.id);
21
+
22
+ if (!result.voted) {
23
+ throw createError({ statusCode: 400, statusMessage: result.error ?? 'Vote failed' });
24
+ }
25
+
26
+ return { voted: true };
27
+ });
@@ -0,0 +1,21 @@
1
+ import { voteOnPost } from '@commonpub/server';
2
+ import { z } from 'zod';
3
+
4
+ const voteSchema = z.object({
5
+ direction: z.enum(['up', 'down']),
6
+ });
7
+
8
+ /**
9
+ * POST /api/hubs/:slug/posts/:postId/vote
10
+ * Upvote or downvote a hub post. Toggles off if same direction, flips if different.
11
+ */
12
+ export default defineEventHandler(async (event) => {
13
+ requireFeature('hubs');
14
+ const user = requireAuth(event);
15
+ const db = useDB();
16
+ const postId = getRouterParam(event, 'postId');
17
+ if (!postId) throw createError({ statusCode: 400, statusMessage: 'Missing postId' });
18
+
19
+ const body = await parseBody(event, voteSchema);
20
+ return voteOnPost(db, postId, user.id, body.direction);
21
+ });
@@ -0,0 +1,10 @@
1
+ import { getNavItems } from '@commonpub/server';
2
+
3
+ /**
4
+ * GET /api/navigation/items
5
+ * Returns the navigation item configuration (public).
6
+ */
7
+ export default defineEventHandler(async () => {
8
+ const db = useDB();
9
+ return getNavItems(db);
10
+ });
@@ -7,6 +7,7 @@ const ROUTE_FEATURE_MAP: Record<string, string> = {
7
7
  '/videos': 'video',
8
8
  '/admin': 'admin',
9
9
  '/contests': 'contests',
10
+ '/events': 'events',
10
11
  '/explainer': 'explainers',
11
12
  };
12
13