diff --git a/src/components/common/ColorIcon.jsx b/src/components/Layout/ColorIcon.jsx
similarity index 100%
rename from src/components/common/ColorIcon.jsx
rename to src/components/Layout/ColorIcon.jsx
diff --git a/src/components/Layout/Header.jsx b/src/components/Layout/Header.jsx
index 56f0ce3..e72814b 100644
--- a/src/components/Layout/Header.jsx
+++ b/src/components/Layout/Header.jsx
@@ -3,8 +3,7 @@ import { Layout, Switch, Button, Dropdown } from 'antd';
import { UserOutlined, LogoutOutlined } from '@ant-design/icons';
import { useTheme } from '@/contexts/ThemeContext';
import { useAuth } from '@/contexts/AuthContext';
-import { MenuTrigger } from '../common/MenuTrigger';
-
+import { MenuTrigger } from '../Layout/MenuTrigger';
const { Header: AntHeader } = Layout;
const Header = ({ collapsed, setCollapsed }) => {
diff --git a/src/components/Layout/Logo.jsx b/src/components/Layout/Logo.jsx
index 6f263bd..510b329 100644
--- a/src/components/Layout/Logo.jsx
+++ b/src/components/Layout/Logo.jsx
@@ -1,18 +1,17 @@
import React from 'react';
import { RocketOutlined } from '@ant-design/icons';
+import { Typography } from 'antd';
+
+const { Text } = Typography;
export const Logo = ({ collapsed, isDarkMode }) => (
{!collapsed && (
-
+
Uppeta
-
+
)}
diff --git a/src/components/common/MenuTrigger.jsx b/src/components/Layout/MenuTrigger.jsx
similarity index 100%
rename from src/components/common/MenuTrigger.jsx
rename to src/components/Layout/MenuTrigger.jsx
diff --git a/src/components/Layout/Sidebar.jsx b/src/components/Layout/Sidebar.jsx
index 06d22ef..241c061 100644
--- a/src/components/Layout/Sidebar.jsx
+++ b/src/components/Layout/Sidebar.jsx
@@ -3,7 +3,7 @@ import { Layout, Menu } from 'antd';
import { useNavigate, useLocation } from 'react-router-dom';
import { useTheme } from '@/contexts/ThemeContext';
import { getMenuItems } from '@/utils/menuUtils';
-import { Logo } from '@/components/common/Logo';
+import { Logo } from '@/components/Layout/Logo';
const { Sider } = Layout;
diff --git a/src/components/common/BaseTable.jsx b/src/components/common/BaseTable.jsx
deleted file mode 100644
index 9c4a1c6..0000000
--- a/src/components/common/BaseTable.jsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Table } from 'antd';
-
-export const BaseTable = ({
- columns,
- dataSource,
- loading = false,
- rowKey = 'id',
- ...props
-}) => (
-
-);
\ No newline at end of file
diff --git a/src/components/common/Icon.jsx b/src/components/common/Icon.jsx
deleted file mode 100644
index 722702e..0000000
--- a/src/components/common/Icon.jsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-
-export const Icon = ({ name, className = '', style = {} }) => (
-
- {name}
-
-);
\ No newline at end of file
diff --git a/src/components/common/Logo.jsx b/src/components/common/Logo.jsx
deleted file mode 100644
index 8667cc6..0000000
--- a/src/components/common/Logo.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-export const Logo = ({ collapsed, isDarkMode }) => (
-
-
-
- rocket_launch
-
-
- Uppeta
-
-
-
-);
diff --git a/src/components/common/PageHeader.jsx b/src/components/common/PageHeader.jsx
deleted file mode 100644
index 631787a..0000000
--- a/src/components/common/PageHeader.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import { Button } from 'antd';
-import { PlusOutlined } from '@ant-design/icons';
-
-export const PageHeader = ({ title, onAdd, addButtonText = '新增' }) => (
-
-
{title}
- {onAdd && (
- } onClick={onAdd}>
- {addButtonText}
-
- )}
-
-);
\ No newline at end of file
diff --git a/src/config/supabase.js b/src/config/supabase.js
index 5f7b4fa..6a073da 100644
--- a/src/config/supabase.js
+++ b/src/config/supabase.js
@@ -21,7 +21,7 @@ export const createSupabase = () => {
detectSessionInUrl: false,
},
db: {
- schema: 'limq'
+ schema: 'limq_dev'
}
}
);
diff --git a/src/hooks/supabaseService.js b/src/hooks/supabaseService.js
index 8395c97..a2c9fdc 100644
--- a/src/hooks/supabaseService.js
+++ b/src/hooks/supabaseService.js
@@ -1,7 +1,7 @@
import { supabase } from '@/config/supabase'
class SupabaseService {
- async get(table, options = {}) {
+ async select(table, options = {}) {
try {
let query = supabase
.from(table)
@@ -96,6 +96,26 @@ class SupabaseService {
throw error
}
}
+ // 通用 UPSERT 请求
+ async upsert(table, data, onConflict) {
+ try {
+ let query = supabase
+ .from(table)
+ .upsert(data)
+ .select()
+
+ if (onConflict) {
+ query = query.onConflict(onConflict)
+ }
+
+ const { data: result, error } = await query
+ if (error) throw error
+ return result
+ } catch (error) {
+ console.error(`Error upserting into ${table}:`, error.message)
+ throw error
+ }
+ }
}
export const supabaseService = new SupabaseService()
\ No newline at end of file
diff --git a/src/hooks/team/useTeamMemberships.js b/src/hooks/team/useTeamMemberships.js
index 4804116..dcd4fea 100644
--- a/src/hooks/team/useTeamMemberships.js
+++ b/src/hooks/team/useTeamMemberships.js
@@ -10,7 +10,7 @@ export const useTeamMembership = (teamId) => {
setLoading(true);
try {
- const result = await supabaseService.get('team_memberships', {
+ const result = await SupabaseService.select('team_memberships', {
select: '*',
relations: {
user: 'id, email, name'
diff --git a/src/hooks/team/useTeams.js b/src/hooks/team/useTeams.js
index b4d8f80..a995438 100644
--- a/src/hooks/team/useTeams.js
+++ b/src/hooks/team/useTeams.js
@@ -4,7 +4,7 @@ export const useTeams = () => {
// 获取团队列表
const fetchTeams = async (params = {}) => {
try {
- const result = await supabaseService.get('teams', {
+ const result = await SupabaseService.select('teams', {
select: `
id,
name,
diff --git a/src/pages/auth/Login.jsx b/src/pages/auth/Login.jsx
index 1e7a064..4549bcf 100644
--- a/src/pages/auth/Login.jsx
+++ b/src/pages/auth/Login.jsx
@@ -7,7 +7,7 @@ import { supabaseService } from "@/hooks/supabaseService";
const Login = () => {
const navigate = useNavigate();
- const { login, signInWithGoogle, loading } = useAuth();
+ const { login, signInWithGoogle, emailLoading, googleLoading } = useAuth();
const [form] = Form.useForm();
const handleLogin = async (values) => {
@@ -75,6 +75,8 @@ const Login = () => {
type="primary"
htmlType="submit"
block
+ loading={emailLoading}
+ disabled={googleLoading}
className="h-12 rounded-xl text-base font-medium bg-gradient-to-r from-blue-600 to-cyan-500 border-0 hover:from-blue-700 hover:to-cyan-600"
>
登录
@@ -89,7 +91,8 @@ const Login = () => {
icon={}
block
onClick={signInWithGoogle}
- loading={loading}
+ loading={googleLoading}
+ disabled={emailLoading}
className="h-12 rounded-xl text-base font-medium mb-6 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 border border-gray-200 dark:border-gray-600"
>
使用 Google 账号登录
diff --git a/src/pages/company/customer/index.jsx b/src/pages/company/customer/index.jsx
index 0691b2c..630c006 100644
--- a/src/pages/company/customer/index.jsx
+++ b/src/pages/company/customer/index.jsx
@@ -92,7 +92,6 @@ const CustomerPage = () => {
dataIndex: 'created_at',
key: 'created_at',
sorter: true,
- width: 180,
render: (text) => (
{new Date(text).toLocaleString('zh-CN', {
year: 'numeric',
@@ -106,7 +105,7 @@ const CustomerPage = () => {
{
title: '操作',
key: 'action',
- width: 150,
+ fixed: 'right',
render: (_, record) => (