@nexttylabs/echo 0.5.0 → 0.7.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.
- package/CHANGELOG.md +29 -0
- package/app/(auth)/login/page.tsx +1 -1
- package/app/(auth)/register/page.tsx +1 -1
- package/app/(auth)/sign-in/page.tsx +1 -1
- package/app/(dashboard)/admin/feedback/[id]/edit/page.tsx +13 -7
- package/app/(dashboard)/admin/feedback/[id]/page.tsx +1 -1
- package/app/(dashboard)/admin/feedback/new/page.tsx +20 -18
- package/app/(dashboard)/admin/feedback/page.tsx +1 -1
- package/app/(dashboard)/admin/layout.tsx +17 -7
- package/app/(dashboard)/analytics/portal/page.tsx +1 -1
- package/app/(dashboard)/dashboard/page.tsx +1 -1
- package/app/(dashboard)/layout.tsx +5 -3
- package/app/(dashboard)/no-access/page.tsx +1 -1
- package/app/(dashboard)/settings/access/page.tsx +1 -1
- package/app/(dashboard)/settings/api-keys/page.tsx +14 -4
- package/app/(dashboard)/settings/appearance/page.tsx +1 -1
- package/app/(dashboard)/settings/branding/page.tsx +1 -1
- package/app/(dashboard)/settings/changelog/page.tsx +1 -1
- package/app/(dashboard)/settings/danger-zone/page.tsx +1 -1
- package/app/(dashboard)/settings/feedback/page.tsx +1 -1
- package/app/(dashboard)/settings/integrations/page.tsx +1 -1
- package/app/(dashboard)/settings/layout.tsx +26 -3
- package/app/(dashboard)/settings/modules/page.tsx +1 -1
- package/app/(dashboard)/settings/notifications/page.tsx +1 -1
- package/app/(dashboard)/settings/organization/page.tsx +9 -10
- package/app/(dashboard)/settings/organization/portal/access/page.tsx +1 -1
- package/app/(dashboard)/settings/organization/portal/experience/page.tsx +1 -1
- package/app/(dashboard)/settings/organization/portal/growth/page.tsx +1 -1
- package/app/(dashboard)/settings/organization/portal/layout.tsx +1 -1
- package/app/(dashboard)/settings/organization/portal/page.tsx +1 -1
- package/app/(dashboard)/settings/organizations/[orgId]/members/page.tsx +1 -1
- package/app/(dashboard)/settings/organizations/new/page.tsx +1 -1
- package/app/(dashboard)/settings/page.tsx +1 -1
- package/app/(dashboard)/settings/portal-access/page.tsx +1 -1
- package/app/(dashboard)/settings/portal-branding/page.tsx +1 -1
- package/app/(dashboard)/settings/portal-growth/page.tsx +1 -1
- package/app/(dashboard)/settings/portal-modules/page.tsx +1 -1
- package/app/(dashboard)/settings/portal-resources/page.tsx +1 -1
- package/app/(dashboard)/settings/profile/page.tsx +1 -1
- package/app/(dashboard)/settings/widgets/page.tsx +1 -1
- package/app/(public)/[organizationSlug]/changelog/page.tsx +1 -1
- package/app/(public)/[organizationSlug]/feedback/[id]/page.tsx +1 -1
- package/app/(public)/[organizationSlug]/page.tsx +1 -1
- package/app/(public)/[organizationSlug]/roadmap/page.tsx +1 -1
- package/app/(public)/docs/page.tsx +1 -1
- package/app/(public)/feedback/[id]/not-found.tsx +1 -1
- package/app/(public)/feedback/[id]/page.tsx +1 -1
- package/app/(public)/invite/[token]/page.tsx +1 -1
- package/app/(public)/page.tsx +1 -1
- package/app/(public)/widget/[organizationId]/page.tsx +1 -1
- package/app/api/_utils.ts +1 -1
- package/app/api/admin/backup/route.ts +1 -1
- package/app/api/api-keys/[keyId]/route.ts +1 -1
- package/app/api/api-keys/route.ts +1 -1
- package/app/api/auth/[...all]/route.ts +1 -1
- package/app/api/auth/clear-session/route.ts +1 -1
- package/app/api/auth/register/handler.ts +1 -1
- package/app/api/auth/register/route.ts +1 -1
- package/app/api/docs/route.ts +1 -1
- package/app/api/feedback/[id]/comments/[commentId]/route.ts +14 -5
- package/app/api/feedback/[id]/comments/route.ts +1 -1
- package/app/api/feedback/[id]/duplicates/route.ts +1 -1
- package/app/api/feedback/[id]/handler.ts +1 -1
- package/app/api/feedback/[id]/processing-status/route.ts +1 -1
- package/app/api/feedback/[id]/reclassify/route.ts +5 -5
- package/app/api/feedback/[id]/route.ts +1 -1
- package/app/api/feedback/[id]/suggest-tags/route.ts +1 -1
- package/app/api/feedback/[id]/sync-github/route.ts +1 -1
- package/app/api/feedback/[id]/vote/route.ts +1 -1
- package/app/api/feedback/bulk/route.ts +1 -1
- package/app/api/feedback/handler.ts +1 -1
- package/app/api/feedback/route.ts +1 -1
- package/app/api/feedback/similar/route.ts +1 -1
- package/app/api/health/route.test.ts +1 -1
- package/app/api/health/route.ts +1 -1
- package/app/api/identify/jwt/route.ts +1 -1
- package/app/api/integrations/github/route.ts +1 -1
- package/app/api/invitations/accept/handler.ts +1 -1
- package/app/api/invitations/accept/route.ts +1 -1
- package/app/api/notifications/preferences/route.ts +1 -1
- package/app/api/organizations/[orgId]/handler.ts +1 -1
- package/app/api/organizations/[orgId]/invitations/handler.ts +1 -1
- package/app/api/organizations/[orgId]/invitations/route.ts +1 -1
- package/app/api/organizations/[orgId]/members/[memberId]/handler.ts +1 -1
- package/app/api/organizations/[orgId]/members/[memberId]/route.ts +1 -1
- package/app/api/organizations/[orgId]/members/handler.ts +1 -1
- package/app/api/organizations/[orgId]/members/route.ts +1 -1
- package/app/api/organizations/[orgId]/route.ts +1 -1
- package/app/api/organizations/handler.ts +3 -5
- package/app/api/organizations/route.ts +1 -1
- package/app/api/tags/sync/route.ts +1 -1
- package/app/api/upload/handler.ts +1 -1
- package/app/api/upload/route.ts +1 -1
- package/app/api/v1/feedback/[id]/route.ts +1 -1
- package/app/api/v1/feedback/route.ts +1 -1
- package/app/api/v1/spec/route.ts +1 -1
- package/app/api/webhooks/[webhookId]/route.ts +1 -1
- package/app/api/webhooks/github/route.ts +1 -1
- package/app/api/webhooks/route.ts +1 -1
- package/app/health/route.ts +1 -1
- package/app/layout.tsx +11 -3
- package/components/api/rate-limit-info.tsx +1 -1
- package/components/api-keys/api-key-manager.tsx +1 -1
- package/components/auth/login-form.tsx +1 -1
- package/components/auth/register-form.tsx +1 -1
- package/components/comment/comment-form.tsx +1 -1
- package/components/comment/internal-notes.tsx +1 -1
- package/components/comment/public-comments.tsx +1 -1
- package/components/component-example-client-only.tsx +1 -1
- package/components/component-example.tsx +1 -1
- package/components/dashboard/index.ts +1 -1
- package/components/dashboard/organization-switcher.tsx +1 -1
- package/components/dashboard/quick-actions.tsx +1 -1
- package/components/dashboard/recent-feedback-list.tsx +1 -1
- package/components/dashboard/stats-cards.tsx +1 -1
- package/components/dashboard/status-chart.tsx +1 -1
- package/components/example.tsx +1 -1
- package/components/feedback/attachment-list.tsx +1 -1
- package/components/feedback/auto-classification-badge.tsx +1 -1
- package/components/feedback/classification-override.tsx +1 -1
- package/components/feedback/duplicate-suggestions-inline.tsx +1 -1
- package/components/feedback/duplicate-suggestions.tsx +1 -1
- package/components/feedback/embedded-feedback-form.tsx +1 -1
- package/components/feedback/feedback-actions.tsx +1 -1
- package/components/feedback/feedback-bulk-actions.tsx +1 -1
- package/components/feedback/feedback-detail-view.tsx +1 -1
- package/components/feedback/feedback-detail.tsx +1 -1
- package/components/feedback/feedback-edit-form.tsx +1 -1
- package/components/feedback/feedback-filters.tsx +1 -1
- package/components/feedback/feedback-list-controls.tsx +1 -1
- package/components/feedback/feedback-list-item.tsx +1 -1
- package/components/feedback/feedback-list-skeleton.tsx +1 -1
- package/components/feedback/feedback-list.tsx +1 -1
- package/components/feedback/feedback-sorter.tsx +1 -1
- package/components/feedback/feedback-stats.tsx +1 -1
- package/components/feedback/file-upload.tsx +1 -1
- package/components/feedback/processing-status.tsx +1 -1
- package/components/feedback/status-history.tsx +1 -1
- package/components/feedback/status-selector.tsx +1 -1
- package/components/feedback/submit-on-behalf-form.tsx +1 -1
- package/components/feedback/tag-suggestions.tsx +1 -1
- package/components/feedback/vote-button.tsx +1 -1
- package/components/feedback/vote-list.tsx +1 -1
- package/components/integrations/github-config.tsx +1 -1
- package/components/landing/hero.tsx +1 -1
- package/components/layout/dashboard-layout.tsx +1 -1
- package/components/layout/index.ts +1 -1
- package/components/layout/language-switcher.tsx +1 -1
- package/components/layout/mobile-sidebar.tsx +1 -1
- package/components/layout/sidebar.tsx +1 -1
- package/components/portal/changelog-entry.tsx +1 -1
- package/components/portal/changelog-list.tsx +1 -1
- package/components/portal/contributor-badge.tsx +1 -1
- package/components/portal/contributors-sidebar.tsx +1 -1
- package/components/portal/create-post-dialog.tsx +1 -1
- package/components/portal/feedback-board.tsx +1 -1
- package/components/portal/feedback-post-card.tsx +1 -1
- package/components/portal/help-center.tsx +1 -1
- package/components/portal/leaderboard.tsx +1 -1
- package/components/portal/portal-header.tsx +1 -1
- package/components/portal/portal-layout.tsx +1 -1
- package/components/portal/portal-modules-panel.tsx +1 -1
- package/components/portal/portal-nav.tsx +1 -1
- package/components/portal/portal-overview.tsx +1 -1
- package/components/portal/portal-settings-nav.tsx +1 -1
- package/components/portal/portal-settings-shell.tsx +1 -1
- package/components/portal/portal-shell.tsx +1 -1
- package/components/portal/portal-tab-nav.tsx +1 -1
- package/components/portal/roadmap-board.tsx +1 -1
- package/components/portal/roadmap-card.tsx +1 -1
- package/components/portal/roadmap-column.tsx +1 -1
- package/components/portal/settings-forms/access-form.tsx +1 -1
- package/components/portal/settings-forms/copy-form.tsx +1 -1
- package/components/portal/settings-forms/index.ts +1 -1
- package/components/portal/settings-forms/languages-form.tsx +1 -1
- package/components/portal/settings-forms/seo-form.tsx +1 -1
- package/components/portal/settings-forms/sharing-form.tsx +1 -1
- package/components/portal/settings-forms/theme-form.tsx +1 -1
- package/components/settings/api-keys-list.tsx +1 -1
- package/components/settings/appearance-form.tsx +4 -6
- package/components/settings/index.ts +1 -1
- package/components/settings/invite-member-form.tsx +1 -1
- package/components/settings/notification-preferences.tsx +1 -1
- package/components/settings/organization-form.tsx +1 -1
- package/components/settings/organization-members-list.tsx +1 -1
- package/components/settings/profile-form.tsx +1 -1
- package/components/settings/role-selector.tsx +1 -1
- package/components/settings/settings-sidebar.tsx +5 -5
- package/components/shared/pagination.tsx +1 -1
- package/components/theme-provider.tsx +28 -0
- package/components/ui/alert-dialog.tsx +1 -1
- package/components/ui/alert.tsx +1 -1
- package/components/ui/avatar.tsx +1 -1
- package/components/ui/badge.tsx +1 -1
- package/components/ui/button.tsx +1 -1
- package/components/ui/card.tsx +1 -1
- package/components/ui/combobox.tsx +1 -1
- package/components/ui/dialog.tsx +1 -1
- package/components/ui/dropdown-menu.tsx +1 -1
- package/components/ui/field.tsx +1 -1
- package/components/ui/input-group.tsx +1 -1
- package/components/ui/input.tsx +1 -1
- package/components/ui/label.tsx +1 -1
- package/components/ui/pagination.tsx +1 -1
- package/components/ui/select.tsx +1 -1
- package/components/ui/separator.tsx +1 -1
- package/components/ui/sheet.tsx +1 -1
- package/components/ui/skeleton.tsx +1 -1
- package/components/ui/switch.tsx +1 -1
- package/components/ui/table.tsx +1 -1
- package/components/ui/tabs.tsx +1 -1
- package/components/ui/textarea.tsx +1 -1
- package/components/ui/tooltip.tsx +1 -1
- package/components/widget/widget-form.tsx +1 -1
- package/drizzle.config.ts +1 -1
- package/hooks/use-organization.tsx +116 -0
- package/hooks/use-permissions.ts +25 -12
- package/i18n/config.ts +1 -1
- package/i18n/request.ts +1 -1
- package/i18n/resolve-locale.ts +1 -1
- package/lib/api/errors.ts +1 -1
- package/lib/auth/cli-config.ts +1 -1
- package/lib/auth/client.ts +1 -1
- package/lib/auth/config.ts +1 -1
- package/lib/auth/jwt-identity.ts +1 -1
- package/lib/auth/org-context.ts +1 -1
- package/lib/auth/organization.ts +21 -1
- package/lib/auth/permissions.ts +11 -1
- package/lib/auth/session.ts +1 -1
- package/lib/config/rate-limits.ts +1 -1
- package/lib/dashboard/get-dashboard-stats.ts +1 -1
- package/lib/db/index.ts +1 -1
- package/lib/db/migrate.test.ts +1 -1
- package/lib/db/migrate.ts +1 -1
- package/lib/db/schema/ai-processing.ts +1 -1
- package/lib/db/schema/api-keys.ts +1 -1
- package/lib/db/schema/attachments.ts +1 -1
- package/lib/db/schema/auth.ts +1 -1
- package/lib/db/schema/comments.ts +1 -1
- package/lib/db/schema/duplicates.ts +1 -1
- package/lib/db/schema/feedback.ts +1 -1
- package/lib/db/schema/github-integrations.ts +1 -1
- package/lib/db/schema/index.ts +1 -1
- package/lib/db/schema/invitations.ts +1 -1
- package/lib/db/schema/notifications.ts +1 -1
- package/lib/db/schema/organization-members.ts +1 -1
- package/lib/db/schema/organization-settings.ts +1 -1
- package/lib/db/schema/organizations.ts +1 -1
- package/lib/db/schema/status-history.ts +1 -1
- package/lib/db/schema/tags.ts +1 -1
- package/lib/db/schema/votes.ts +1 -1
- package/lib/db/schema/webhooks.ts +1 -1
- package/lib/feedback/filters.ts +1 -1
- package/lib/feedback/find-similar.ts +1 -1
- package/lib/feedback/get-feedback-by-id.ts +1 -1
- package/lib/feedback/prefill.ts +1 -1
- package/lib/http/get-request-url.ts +1 -1
- package/lib/integrations/github.ts +1 -1
- package/lib/invitations.ts +1 -1
- package/lib/logger.test.ts +1 -1
- package/lib/logger.ts +1 -1
- package/lib/middleware/api-key.ts +1 -1
- package/lib/middleware/rate-limit-keys.ts +1 -1
- package/lib/middleware/rate-limit.ts +1 -1
- package/lib/middleware/rbac.ts +1 -1
- package/lib/middleware/request-id.test.ts +1 -1
- package/lib/middleware/request-id.ts +1 -1
- package/lib/middleware/request-logger.test.ts +1 -1
- package/lib/middleware/request-logger.ts +1 -1
- package/lib/middleware/with-rate-limit.ts +1 -1
- package/lib/portal/analytics.ts +1 -1
- package/lib/portal/contributors.ts +1 -1
- package/lib/portal/i18n.ts +1 -1
- package/lib/portal/leaderboard-settings.ts +1 -1
- package/lib/portal/modules.ts +1 -1
- package/lib/portal/portal-copy.ts +1 -1
- package/lib/portal/public-context.tsx +1 -1
- package/lib/portal/seo.ts +1 -1
- package/lib/portal/settings-context.ts +1 -1
- package/lib/portal/sharing.ts +1 -1
- package/lib/portal/sorting.ts +1 -1
- package/lib/portal/theme.ts +1 -1
- package/lib/services/ai/classifier.ts +1 -1
- package/lib/services/ai/duplicate-detector.ts +1 -1
- package/lib/services/ai/tag-suggester.ts +1 -1
- package/lib/services/api-keys.ts +1 -1
- package/lib/services/backup.ts +1 -1
- package/lib/services/email/templates.ts +1 -1
- package/lib/services/email.ts +1 -1
- package/lib/services/github-sync.ts +1 -1
- package/lib/services/notifications/index.ts +1 -1
- package/lib/services/portal-settings.ts +1 -1
- package/lib/swagger/config.ts +1 -1
- package/lib/swagger/generate.ts +1 -1
- package/lib/upload/file-validator.ts +1 -1
- package/lib/upload/storage.ts +1 -1
- package/lib/utils/format.ts +1 -1
- package/lib/utils/slug.ts +1 -1
- package/lib/utils.ts +1 -1
- package/lib/validations/auth.ts +1 -1
- package/lib/validations/comment.ts +1 -1
- package/lib/validations/feedback.ts +1 -1
- package/lib/validations/invitations.ts +1 -1
- package/lib/validations/organizations.ts +1 -1
- package/lib/validators/feedback.ts +1 -1
- package/lib/validators/index.ts +1 -1
- package/lib/webhooks/events.ts +1 -1
- package/lib/webhooks/index.ts +1 -1
- package/lib/webhooks/retry.ts +1 -1
- package/lib/webhooks/sender.ts +1 -1
- package/lib/webhooks/verify.ts +1 -1
- package/lib/workers/feedback-processor.ts +1 -1
- package/next.config.ts +1 -1
- package/package.json +2 -1
- package/types/bun-test.d.ts +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
|
-
* Copyright (c) 2026
|
|
5
|
+
* Copyright (c) 2026 Nexttylabs Team
|
|
6
6
|
*
|
|
7
7
|
* This program is free software: you can redistribute it and/or modify
|
|
8
8
|
* it under the terms of the GNU Affero General Public License as published by
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
21
|
+
import { useTheme } from "next-themes";
|
|
22
22
|
import { useTranslations } from "next-intl";
|
|
23
23
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
24
24
|
import { Label } from "@/components/ui/label";
|
|
@@ -28,7 +28,7 @@ import { Monitor, Moon, Sun } from "lucide-react";
|
|
|
28
28
|
type Theme = "light" | "dark" | "system";
|
|
29
29
|
|
|
30
30
|
export function AppearanceForm() {
|
|
31
|
-
const
|
|
31
|
+
const { theme, setTheme } = useTheme();
|
|
32
32
|
const t = useTranslations("settings.appearance");
|
|
33
33
|
|
|
34
34
|
const themes: { value: Theme; label: string; icon: React.ElementType }[] = [
|
|
@@ -61,11 +61,9 @@ export function AppearanceForm() {
|
|
|
61
61
|
</button>
|
|
62
62
|
))}
|
|
63
63
|
</div>
|
|
64
|
-
<p className="text-xs text-muted-foreground">
|
|
65
|
-
{t("themeComingSoon")}
|
|
66
|
-
</p>
|
|
67
64
|
</div>
|
|
68
65
|
</CardContent>
|
|
69
66
|
</Card>
|
|
70
67
|
);
|
|
71
68
|
}
|
|
69
|
+
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
|
-
* Copyright (c) 2026
|
|
5
|
+
* Copyright (c) 2026 Nexttylabs Team
|
|
6
6
|
*
|
|
7
7
|
* This program is free software: you can redistribute it and/or modify
|
|
8
8
|
* it under the terms of the GNU Affero General Public License as published by
|
|
@@ -32,15 +32,15 @@ interface SettingsSidebarProps {
|
|
|
32
32
|
export function SettingsSidebar({ userRole }: SettingsSidebarProps) {
|
|
33
33
|
const pathname = usePathname();
|
|
34
34
|
const t = useTranslations("settings");
|
|
35
|
-
const
|
|
36
|
-
const isAdminOrPM =
|
|
35
|
+
const isOwnerOrAdmin = userRole === "owner" || userRole === "admin";
|
|
36
|
+
const isAdminOrPM = isOwnerOrAdmin || userRole === "product_manager";
|
|
37
37
|
|
|
38
38
|
const groupedItems = [
|
|
39
39
|
{
|
|
40
40
|
title: t("groups.general"),
|
|
41
41
|
items: [
|
|
42
42
|
{ href: "/settings/profile", label: t("items.profile"), icon: User },
|
|
43
|
-
{ href: "/settings/organization", label: t("items.organization"), icon: Users, show:
|
|
43
|
+
{ href: "/settings/organization", label: t("items.organization"), icon: Users, show: isOwnerOrAdmin },
|
|
44
44
|
],
|
|
45
45
|
},
|
|
46
46
|
{
|
|
@@ -71,7 +71,7 @@ export function SettingsSidebar({ userRole }: SettingsSidebarProps) {
|
|
|
71
71
|
{ href: "/settings/widgets", label: t("items.widgetsEmbeds"), icon: LayoutGrid, show: isAdminOrPM },
|
|
72
72
|
{ href: "/settings/integrations", label: t("items.integrations"), icon: Plug, show: isAdminOrPM },
|
|
73
73
|
|
|
74
|
-
{ href: "/settings/danger-zone", label: t("items.dangerZone"), icon: AlertTriangle, show:
|
|
74
|
+
{ href: "/settings/danger-zone", label: t("items.dangerZone"), icon: AlertTriangle, show: isOwnerOrAdmin },
|
|
75
75
|
],
|
|
76
76
|
},
|
|
77
77
|
];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Nexttylabs Team
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
"use client";
|
|
19
|
+
|
|
20
|
+
import * as React from "react";
|
|
21
|
+
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
|
22
|
+
|
|
23
|
+
export function ThemeProvider({
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof NextThemesProvider>) {
|
|
27
|
+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
|
28
|
+
}
|
package/components/ui/alert.tsx
CHANGED
package/components/ui/avatar.tsx
CHANGED
package/components/ui/badge.tsx
CHANGED
package/components/ui/button.tsx
CHANGED
package/components/ui/card.tsx
CHANGED
package/components/ui/dialog.tsx
CHANGED
package/components/ui/field.tsx
CHANGED
package/components/ui/input.tsx
CHANGED
package/components/ui/label.tsx
CHANGED
package/components/ui/select.tsx
CHANGED
package/components/ui/sheet.tsx
CHANGED
package/components/ui/switch.tsx
CHANGED
package/components/ui/table.tsx
CHANGED
package/components/ui/tabs.tsx
CHANGED
package/drizzle.config.ts
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Nexttylabs Team
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
"use client";
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
createContext,
|
|
22
|
+
useContext,
|
|
23
|
+
useState,
|
|
24
|
+
useCallback,
|
|
25
|
+
type ReactNode,
|
|
26
|
+
} from "react";
|
|
27
|
+
import type { UserRole } from "@/lib/auth/permissions";
|
|
28
|
+
|
|
29
|
+
export interface Organization {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
slug: string;
|
|
33
|
+
role: UserRole;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface OrganizationContextValue {
|
|
37
|
+
currentOrganization: Organization | null;
|
|
38
|
+
organizations: Organization[];
|
|
39
|
+
setOrganizations: (orgs: Organization[], currentId?: string | null) => void;
|
|
40
|
+
setCurrentOrganization: (orgId: string) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const OrganizationContext = createContext<OrganizationContextValue | null>(
|
|
44
|
+
null
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
interface OrganizationProviderProps {
|
|
48
|
+
children: ReactNode;
|
|
49
|
+
initialOrganizations?: Organization[];
|
|
50
|
+
initialCurrentOrgId?: string | null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function OrganizationProvider({
|
|
54
|
+
children,
|
|
55
|
+
initialOrganizations = [],
|
|
56
|
+
initialCurrentOrgId,
|
|
57
|
+
}: OrganizationProviderProps) {
|
|
58
|
+
const [organizations, setOrganizationsState] =
|
|
59
|
+
useState<Organization[]>(initialOrganizations);
|
|
60
|
+
const [currentOrganization, setCurrentOrganizationState] =
|
|
61
|
+
useState<Organization | null>(() => {
|
|
62
|
+
if (initialCurrentOrgId) {
|
|
63
|
+
return (
|
|
64
|
+
initialOrganizations.find((o) => o.id === initialCurrentOrgId) || null
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return initialOrganizations[0] || null;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const setOrganizations = useCallback(
|
|
71
|
+
(orgs: Organization[], currentId?: string | null) => {
|
|
72
|
+
setOrganizationsState(orgs);
|
|
73
|
+
const current = currentId ? orgs.find((o) => o.id === currentId) : orgs[0];
|
|
74
|
+
setCurrentOrganizationState(current || null);
|
|
75
|
+
},
|
|
76
|
+
[]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const setCurrentOrganization = useCallback(
|
|
80
|
+
(orgId: string) => {
|
|
81
|
+
const org = organizations.find((o) => o.id === orgId);
|
|
82
|
+
if (org) {
|
|
83
|
+
setCurrentOrganizationState(org);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
[organizations]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<OrganizationContext.Provider
|
|
91
|
+
value={{
|
|
92
|
+
currentOrganization,
|
|
93
|
+
organizations,
|
|
94
|
+
setOrganizations,
|
|
95
|
+
setCurrentOrganization,
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
{children}
|
|
99
|
+
</OrganizationContext.Provider>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function useOrganization(): OrganizationContextValue {
|
|
104
|
+
const context = useContext(OrganizationContext);
|
|
105
|
+
if (!context) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
"useOrganization must be used within an OrganizationProvider"
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return context;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function useCurrentRole(): UserRole | null {
|
|
114
|
+
const { currentOrganization } = useOrganization();
|
|
115
|
+
return currentOrganization?.role || null;
|
|
116
|
+
}
|