- added settings page and function

- add Role Ring for avatar and display role for user nav
This commit is contained in:
2026-01-06 21:37:53 +07:00
parent 8146565d2c
commit a4e96fe045
64 changed files with 2828 additions and 726 deletions

View File

@@ -1,10 +1,15 @@
import { createAuthClient } from 'better-auth/react'
import { adminClient, organizationClient } from 'better-auth/client/plugins'
import { ac, admin, user } from '@/lib/auth/permissions'
import { acOrg, adminOrg, member, owner } from './auth/organization-permissions'
import { ac, admin, user } from '@/lib/auth/permissions';
import { adminClient, organizationClient } from 'better-auth/client/plugins';
import { createAuthClient } from 'better-auth/react';
import {
acOrg,
adminOrg,
member,
owner,
} from './auth/organization-permissions';
export const authClient = createAuthClient({
baseURL: 'http://localhost:3000',
baseURL: process.env.BETTER_AUTH_URL || 'http://localhost:3000',
plugins: [
adminClient({
ac,
@@ -26,4 +31,8 @@ export const authClient = createAuthClient({
},
}),
],
})
});
export const { useSession, getSession } = authClient;
export type ClientSession = typeof authClient.$Infer.Session;

View File

@@ -12,12 +12,6 @@ import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { admin as adminPlugin, organization } from 'better-auth/plugins';
// export interface User {
// image?: string | null;
// name?: string | null;
// email?: string | null;
// }
export interface Session {
session: SessionModel | null | undefined;
user?: User;
@@ -33,6 +27,11 @@ export const auth = betterAuth({
requireEmailVerification: false,
},
trustedOrigins: ['http://localhost:3001'],
advanced: {
database: {
generateId: false,
},
},
plugins: [
adminPlugin({
ac,

View File

@@ -1,6 +1,7 @@
import { createServerFn } from '@tanstack/react-start';
import { getRequestHeaders } from '@tanstack/react-start/server';
import { auth } from '../auth';
import { authClient } from '../auth-client';
export type Session = typeof auth.$Infer.Session;
@@ -11,3 +12,8 @@ export const getSession = createServerFn({ method: 'GET' }).handler(
return session;
},
);
export const sessionPush = () => {
const session = authClient.getSession();
return session;
};

View File

@@ -1,10 +1,10 @@
import { createIsomorphicFn } from '@tanstack/react-start'
import { getCookie } from '@tanstack/react-start/server'
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'
import enTranslations from '../locales/en.json'
import viTranslations from '../locales/vi.json'
import { createIsomorphicFn } from '@tanstack/react-start';
import { getCookie } from '@tanstack/react-start/server';
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import enTranslations from '../locales/en.json';
import viTranslations from '../locales/vi.json';
export const resources = {
en: {
@@ -13,11 +13,11 @@ export const resources = {
vi: {
translation: viTranslations,
},
} as const
} as const;
export const defaultNS = 'translation'
export const defaultNS = 'translation';
const i18nCookieName = 'i18nextLng'
const i18nCookieName = 'i18nextLng';
i18n
.use(LanguageDetector)
@@ -34,11 +34,11 @@ i18n
cookieMinutes: 60 * 24 * 365,
},
interpolation: { escapeValue: false },
})
});
export const setSSRLanguage = createIsomorphicFn().server(async () => {
const language = getCookie(i18nCookieName)
await i18n.changeLanguage(language || 'vi')
})
const language = getCookie(i18nCookieName);
await i18n.changeLanguage(language || 'vi');
});
export default i18n
export default i18n;

12
src/lib/i18next.d.ts vendored
View File

@@ -1,12 +0,0 @@
import 'i18next'
import translation from '../locales/vi.json'
import { defaultNS } from './i18n'
declare module 'i18next' {
interface CustomTypeOptions {
defaultNS: typeof defaultNS
resources: {
translation: typeof translation
}
}
}

View File

@@ -1,15 +1,26 @@
import { createMiddleware } from '@tanstack/react-start'
import { auth } from './auth'
import { redirect } from '@tanstack/react-router'
import { redirect } from '@tanstack/react-router';
import { createMiddleware } from '@tanstack/react-start';
import { getRequestHeaders } from '@tanstack/react-start/server';
import { auth } from './auth';
export const authMiddleware = createMiddleware().server(
async ({ next, request }) => {
export const authMiddleware = createMiddleware({ type: 'function' }).server(
async ({ next }) => {
const headers = getRequestHeaders();
const session = await auth.api.getSession({
headers: request.headers,
})
headers,
});
if (!session) {
throw redirect({ to: '/sign-in' })
throw redirect({ to: '/sign-in' });
}
return await next()
return await next({
context: {
user: {
id: session?.user?.id,
name: session?.user?.name,
email: session?.user?.email,
image: session?.user?.image,
},
},
});
},
)
);