fixes
This commit is contained in:
@@ -27,8 +27,8 @@ export default function ConfirmModal({
|
||||
switch (variant) {
|
||||
case 'danger':
|
||||
return {
|
||||
icon: 'bg-red-100 text-red-600',
|
||||
confirmButton: 'bg-gradient-to-r from-red-500 to-red-600 hover:shadow-lg',
|
||||
icon: 'btn-danger',
|
||||
confirmButton: 'btn-danger hover:shadow-lg',
|
||||
};
|
||||
case 'warning':
|
||||
return {
|
||||
@@ -37,8 +37,8 @@ export default function ConfirmModal({
|
||||
};
|
||||
case 'info':
|
||||
return {
|
||||
icon: 'bg-blue-100 text-blue-600',
|
||||
confirmButton: 'bg-gradient-to-r from-blue-500 to-blue-600 hover:shadow-lg',
|
||||
icon: 'btn-primary',
|
||||
confirmButton: 'btn-primary hover:shadow-lg',
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -47,10 +47,10 @@ export default function ConfirmModal({
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-[60] p-4">
|
||||
<div className="bg-white rounded-3xl shadow-2xl max-w-md w-full overflow-hidden animate-scale-in">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl max-w-md w-full overflow-hidden animate-scale-in">
|
||||
<div className="p-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className={`p-3 rounded-2xl ${styles.icon}`}>
|
||||
<div className={`p-3 rounded-2xl ${styles.icon} text-white`}>
|
||||
<AlertTriangle className="w-6 h-6" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
|
||||
@@ -189,8 +189,8 @@ export default function ShoppingListModal({ familyId, onClose }: ShoppingListMod
|
||||
return (
|
||||
<>
|
||||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-3xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-hidden flex flex-col">
|
||||
<div className="bg-gradient-to-r from-green-500 to-emerald-600 p-6 flex items-center justify-between">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-hidden flex flex-col">
|
||||
<div className="btn-success p-6 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 bg-white/20 backdrop-blur-md rounded-2xl">
|
||||
<ShoppingCart className="w-8 h-8 text-white" />
|
||||
@@ -218,7 +218,7 @@ export default function ShoppingListModal({ familyId, onClose }: ShoppingListMod
|
||||
/>
|
||||
<button
|
||||
onClick={handleAddItem}
|
||||
className="px-6 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white rounded-2xl hover:shadow-lg transition-all font-semibold flex items-center gap-2"
|
||||
className="px-6 py-3 btn-success text-white rounded-2xl hover:shadow-lg transition-all font-semibold flex items-center gap-2"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
<span className="hidden sm:inline">{t('common.add')}</span>
|
||||
@@ -342,14 +342,14 @@ export default function ShoppingListModal({ familyId, onClose }: ShoppingListMod
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={handleMarkAllPurchased}
|
||||
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-green-500 to-green-600 text-white rounded-2xl hover:shadow-lg transition-all font-semibold"
|
||||
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 btn-success text-white rounded-2xl hover:shadow-lg transition-all font-semibold"
|
||||
>
|
||||
<Check className="w-5 h-5" />
|
||||
{t('shopping.allPurchased')}
|
||||
</button>
|
||||
<button
|
||||
onClick={handleClearAll}
|
||||
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-red-500 to-red-600 text-white rounded-2xl hover:shadow-lg transition-all font-semibold"
|
||||
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 btn-danger text-white rounded-2xl hover:shadow-lg transition-all font-semibold"
|
||||
>
|
||||
<Trash2 className="w-5 h-5" />
|
||||
{t('shopping.clear')}
|
||||
|
||||
@@ -159,6 +159,14 @@
|
||||
"leaveConfirm": "Are you sure you want to leave the family?",
|
||||
"leaving": "Leaving...",
|
||||
"leaveError": "Error leaving family",
|
||||
"renameError": "Error renaming family"
|
||||
"renameError": "Error renaming family",
|
||||
"themes": {
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"sunset": "Sunset",
|
||||
"ocean": "Ocean",
|
||||
"forest": "Forest",
|
||||
"purple": "Purple"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,14 @@
|
||||
"leaveConfirm": "Вы уверены, что хотите покинуть семью?",
|
||||
"leaving": "Выход...",
|
||||
"leaveError": "Ошибка при выходе из семьи",
|
||||
"renameError": "Ошибка при переименовании семьи"
|
||||
"renameError": "Ошибка при переименовании семьи",
|
||||
"themes": {
|
||||
"light": "Светлая",
|
||||
"dark": "Тёмная",
|
||||
"sunset": "Закат",
|
||||
"ocean": "Океан",
|
||||
"forest": "Лес",
|
||||
"purple": "Фиолетовая"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,14 +7,32 @@
|
||||
--glass-bg: rgba(255, 255, 255, 0.8);
|
||||
--text-primary: #1f2937;
|
||||
--text-secondary: #6b7280;
|
||||
--category-from: #8b5cf6;
|
||||
--category-to: #3b82f6;
|
||||
--btn-primary-from: #8b5cf6;
|
||||
--btn-primary-to: #6366f1;
|
||||
--btn-success-from: #22c55e;
|
||||
--btn-success-to: #16a34a;
|
||||
--btn-danger-from: #ef4444;
|
||||
--btn-danger-to: #ec4899;
|
||||
--card-bg: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
[data-theme="dark"] {
|
||||
--gradient-start: #1f2937;
|
||||
--gradient-end: #111827;
|
||||
--glass-bg: rgba(31, 41, 55, 0.9);
|
||||
--gradient-start: #000000;
|
||||
--gradient-end: #000000;
|
||||
--glass-bg: rgba(17, 17, 17, 0.95);
|
||||
--text-primary: #f9fafb;
|
||||
--text-secondary: #d1d5db;
|
||||
--category-from: #6366f1;
|
||||
--category-to: #8b5cf6;
|
||||
--btn-primary-from: #6366f1;
|
||||
--btn-primary-to: #8b5cf6;
|
||||
--btn-success-from: #059669;
|
||||
--btn-success-to: #10b981;
|
||||
--btn-danger-from: #dc2626;
|
||||
--btn-danger-to: #be185d;
|
||||
--card-bg: rgba(31, 31, 31, 0.9);
|
||||
}
|
||||
|
||||
[data-theme="sunset"] {
|
||||
@@ -23,6 +41,15 @@
|
||||
--glass-bg: rgba(255, 255, 255, 0.85);
|
||||
--text-primary: #1f2937;
|
||||
--text-secondary: #6b7280;
|
||||
--category-from: #f97316;
|
||||
--category-to: #ec4899;
|
||||
--btn-primary-from: #f97316;
|
||||
--btn-primary-to: #ea580c;
|
||||
--btn-success-from: #22c55e;
|
||||
--btn-success-to: #16a34a;
|
||||
--btn-danger-from: #ef4444;
|
||||
--btn-danger-to: #dc2626;
|
||||
--card-bg: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
[data-theme="ocean"] {
|
||||
@@ -31,6 +58,15 @@
|
||||
--glass-bg: rgba(255, 255, 255, 0.85);
|
||||
--text-primary: #1f2937;
|
||||
--text-secondary: #6b7280;
|
||||
--category-from: #3b82f6;
|
||||
--category-to: #06b6d4;
|
||||
--btn-primary-from: #3b82f6;
|
||||
--btn-primary-to: #2563eb;
|
||||
--btn-success-from: #22c55e;
|
||||
--btn-success-to: #16a34a;
|
||||
--btn-danger-from: #ef4444;
|
||||
--btn-danger-to: #dc2626;
|
||||
--card-bg: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
[data-theme="forest"] {
|
||||
@@ -39,6 +75,15 @@
|
||||
--glass-bg: rgba(255, 255, 255, 0.85);
|
||||
--text-primary: #1f2937;
|
||||
--text-secondary: #6b7280;
|
||||
--category-from: #22c55e;
|
||||
--category-to: #14b8a6;
|
||||
--btn-primary-from: #22c55e;
|
||||
--btn-primary-to: #16a34a;
|
||||
--btn-success-from: #22c55e;
|
||||
--btn-success-to: #16a34a;
|
||||
--btn-danger-from: #ef4444;
|
||||
--btn-danger-to: #dc2626;
|
||||
--card-bg: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
[data-theme="purple"] {
|
||||
@@ -47,6 +92,15 @@
|
||||
--glass-bg: rgba(255, 255, 255, 0.85);
|
||||
--text-primary: #1f2937;
|
||||
--text-secondary: #6b7280;
|
||||
--category-from: #8b5cf6;
|
||||
--category-to: #ec4899;
|
||||
--btn-primary-from: #8b5cf6;
|
||||
--btn-primary-to: #7c3aed;
|
||||
--btn-success-from: #22c55e;
|
||||
--btn-success-to: #16a34a;
|
||||
--btn-danger-from: #ef4444;
|
||||
--btn-danger-to: #dc2626;
|
||||
--card-bg: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
.gradient-bg {
|
||||
@@ -67,10 +121,66 @@
|
||||
}
|
||||
|
||||
.glass-effect {
|
||||
background: rgb(255 255 255 / 0.8);
|
||||
background: var(--glass-bg);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.category-icon {
|
||||
background: linear-gradient(135deg, var(--category-from) 0%, var(--category-to) 100%);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--btn-primary-from) 0%, var(--btn-primary-to) 100%);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: linear-gradient(135deg, var(--btn-success-from) 0%, var(--btn-success-to) 100%);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: linear-gradient(135deg, var(--btn-danger-from) 0%, var(--btn-danger-to) 100%);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .glass-effect {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .text-gray-800,
|
||||
[data-theme="dark"] .text-gray-900 {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .text-gray-600,
|
||||
[data-theme="dark"] .text-gray-500 {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .bg-gray-100,
|
||||
[data-theme="dark"] .bg-gray-50 {
|
||||
background-color: rgba(55, 55, 55, 0.5);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .bg-gray-200 {
|
||||
background-color: rgba(75, 75, 75, 0.5);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .border-gray-200,
|
||||
[data-theme="dark"] .border-gray-300 {
|
||||
border-color: rgba(75, 75, 75, 0.8);
|
||||
}
|
||||
|
||||
[data-theme="dark"] input,
|
||||
[data-theme="dark"] textarea {
|
||||
background-color: rgba(40, 40, 40, 0.9);
|
||||
color: var(--text-primary);
|
||||
border-color: rgba(75, 75, 75, 0.8);
|
||||
}
|
||||
|
||||
[data-theme="dark"] input::placeholder,
|
||||
[data-theme="dark"] textarea::placeholder {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.animate-fadeIn {
|
||||
animation: fadeIn 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function AdminPanel() {
|
||||
<div className="max-w-md w-full">
|
||||
<div className="glass-effect rounded-2xl shadow-2xl p-6 sm:p-8 text-center">
|
||||
<div className="flex items-center justify-center mb-6">
|
||||
<div className="p-4 bg-linear-to-br from-red-500 to-orange-500 text-white rounded-2xl">
|
||||
<div className="p-4 btn-danger text-white rounded-2xl">
|
||||
<Shield className="w-10 h-10 sm:w-12 sm:h-12" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -137,7 +137,7 @@ export default function AdminPanel() {
|
||||
|
||||
<div className="glass-effect rounded-3xl shadow-xl p-6 sm:p-10 mb-6 max-w-2xl mx-auto">
|
||||
<div className="flex items-center justify-center gap-3 mb-8">
|
||||
<div className="p-3 bg-linear-to-br from-green-500 to-green-600 rounded-2xl">
|
||||
<div className="p-3 btn-success rounded-2xl">
|
||||
<Plus className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h2 className="text-2xl sm:text-3xl font-bold text-gray-800">
|
||||
@@ -174,7 +174,7 @@ export default function AdminPanel() {
|
||||
</div>
|
||||
<button
|
||||
onClick={handleCreateFamily}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 bg-linear-to-r from-green-500 to-green-600 text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold text-lg"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 btn-success text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold text-lg"
|
||||
>
|
||||
<Plus className="w-6 h-6" />
|
||||
{t('admin.createButton')}
|
||||
@@ -184,7 +184,7 @@ export default function AdminPanel() {
|
||||
|
||||
<div className="glass-effect rounded-3xl shadow-xl p-6 sm:p-10 max-w-3xl mx-auto">
|
||||
<div className="flex items-center justify-center gap-3 mb-8">
|
||||
<div className="p-3 bg-linear-to-br from-purple-500 to-blue-500 rounded-2xl">
|
||||
<div className="p-3 category-icon rounded-2xl">
|
||||
<Users className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h2 className="text-2xl sm:text-3xl font-bold text-gray-800">
|
||||
@@ -194,8 +194,8 @@ export default function AdminPanel() {
|
||||
|
||||
{families.length === 0 ? (
|
||||
<div className="text-center py-16 sm:py-20">
|
||||
<div className="inline-flex p-6 bg-linear-to-br from-purple-100 to-blue-100 rounded-3xl mb-6">
|
||||
<Users className="w-20 h-20 text-purple-400" />
|
||||
<div className="inline-flex p-6 bg-gray-100 rounded-3xl mb-6">
|
||||
<Users className="w-20 h-20 text-gray-400" />
|
||||
</div>
|
||||
<p className="text-gray-600 text-lg sm:text-xl mb-2 font-semibold">
|
||||
{t('admin.noFamilies')}
|
||||
@@ -209,10 +209,10 @@ export default function AdminPanel() {
|
||||
{families.map((family) => (
|
||||
<div
|
||||
key={family.id}
|
||||
className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-5 bg-linear-to-r from-purple-50 to-blue-50 rounded-2xl border-2 border-purple-200 card-hover"
|
||||
className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-3 p-5 bg-gray-50 rounded-2xl border-2 border-gray-200 card-hover"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 bg-linear-to-br from-purple-500 to-blue-500 text-white rounded-xl shadow-md">
|
||||
<div className="p-3 category-icon text-white rounded-xl shadow-md">
|
||||
<Users className="w-6 h-6" />
|
||||
</div>
|
||||
<span className="text-lg sm:text-xl font-bold text-gray-900">
|
||||
@@ -221,7 +221,7 @@ export default function AdminPanel() {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleDeleteFamily(family.id)}
|
||||
className="w-full sm:w-auto flex items-center justify-center gap-2 px-5 py-3 bg-red-500 hover:bg-red-600 text-white rounded-xl transition-all font-semibold shadow-md hover:shadow-lg"
|
||||
className="w-full sm:w-auto flex items-center justify-center gap-2 px-5 py-3 btn-danger text-white rounded-xl transition-all font-semibold shadow-md hover:shadow-lg"
|
||||
>
|
||||
<Trash2 className="w-5 h-5" />
|
||||
{t('common.delete')}
|
||||
|
||||
@@ -308,7 +308,7 @@ export default function FamilyView() {
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowShoppingList(true)}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-3 bg-gradient-to-r from-green-500 to-emerald-600 text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-3 btn-success text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold"
|
||||
>
|
||||
<ShoppingCart className="w-5 h-5" />
|
||||
{t('family.shoppingList')}
|
||||
@@ -339,7 +339,7 @@ export default function FamilyView() {
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3 mb-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-2 bg-linear-to-br from-purple-500 to-blue-500 text-white rounded-xl shadow-lg">
|
||||
<div className="p-2 category-icon text-white rounded-xl shadow-lg">
|
||||
<Tag className="w-6 h-6" />
|
||||
</div>
|
||||
<h2 className="text-xl sm:text-2xl font-bold text-gray-900">
|
||||
@@ -350,7 +350,7 @@ export default function FamilyView() {
|
||||
{showAddExpense !== category.id && (
|
||||
<button
|
||||
onClick={() => setShowAddExpense(category.id)}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-linear-to-r from-red-500 to-pink-500 text-white rounded-xl hover:shadow-lg transition-all duration-300 font-semibold whitespace-nowrap text-sm"
|
||||
className="flex items-center gap-2 px-4 py-2 btn-danger text-white rounded-xl hover:shadow-lg transition-all duration-300 font-semibold whitespace-nowrap text-sm"
|
||||
>
|
||||
<TrendingDown className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">{t('category.addExpense')}</span>
|
||||
@@ -407,7 +407,7 @@ export default function FamilyView() {
|
||||
</div>
|
||||
|
||||
{showHistory === category.id && (
|
||||
<div className="mt-4 bg-linear-to-br from-blue-50 to-purple-50 p-4 rounded-2xl border-2 border-blue-200">
|
||||
<div className="mt-4 glass-effect p-4 rounded-2xl border-2 border-gray-200">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="font-semibold text-gray-800 text-lg flex items-center gap-2">
|
||||
<History className="w-5 h-5" />
|
||||
@@ -458,7 +458,7 @@ export default function FamilyView() {
|
||||
)}
|
||||
|
||||
{showAddExpense === category.id && (
|
||||
<div className="bg-linear-to-br from-purple-50 to-blue-50 p-6 rounded-2xl border-2 border-purple-200">
|
||||
<div className="glass-effect p-6 rounded-2xl border-2 border-gray-200 mt-4">
|
||||
<h3 className="font-semibold text-gray-800 mb-4 text-center">
|
||||
{t('expense.addTitle')}
|
||||
</h3>
|
||||
@@ -490,7 +490,7 @@ export default function FamilyView() {
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={() => handleAddExpense(category.id)}
|
||||
className="flex-1 flex items-center justify-center gap-2 px-5 py-3 bg-linear-to-r from-green-500 to-green-600 text-white rounded-2xl hover:shadow-xl transition-all font-semibold"
|
||||
className="flex-1 flex items-center justify-center gap-2 px-5 py-3 btn-success text-white rounded-2xl hover:shadow-xl transition-all font-semibold"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
{t('common.add')}
|
||||
@@ -512,7 +512,7 @@ export default function FamilyView() {
|
||||
|
||||
<div className="glass-effect rounded-3xl shadow-xl p-6 sm:p-8 max-w-3xl mx-auto">
|
||||
<div className="flex items-center justify-center gap-3 mb-8">
|
||||
<div className="p-3 bg-linear-to-br from-purple-500 to-blue-500 rounded-2xl">
|
||||
<div className="p-3 category-icon rounded-2xl">
|
||||
<DollarSign className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h2 className="text-2xl sm:text-3xl font-bold text-gray-800">
|
||||
@@ -521,7 +521,7 @@ export default function FamilyView() {
|
||||
</div>
|
||||
|
||||
{showAddCategory ? (
|
||||
<div className="mb-8 p-6 bg-linear-to-br from-purple-50 to-blue-50 rounded-2xl border-2 border-purple-200">
|
||||
<div className="mb-8 p-6 glass-effect rounded-2xl border-2 border-gray-200">
|
||||
<h3 className="font-bold text-gray-800 mb-5 text-center text-lg">
|
||||
{t('category.newCategory')}
|
||||
</h3>
|
||||
@@ -543,7 +543,7 @@ export default function FamilyView() {
|
||||
<div className="flex gap-3">
|
||||
<button
|
||||
onClick={handleAddCategory}
|
||||
className="flex-1 flex items-center justify-center gap-2 px-6 py-4 bg-linear-to-r from-green-500 to-green-600 text-white rounded-2xl hover:shadow-xl transition-all font-semibold"
|
||||
className="flex-1 flex items-center justify-center gap-2 px-6 py-4 btn-success text-white rounded-2xl hover:shadow-xl transition-all font-semibold"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
{t('common.create')}
|
||||
@@ -560,7 +560,7 @@ export default function FamilyView() {
|
||||
) : (
|
||||
<button
|
||||
onClick={() => setShowAddCategory(true)}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 bg-linear-to-r from-purple-600 to-blue-600 text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 btn-primary text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold"
|
||||
>
|
||||
<Plus className="w-5 h-5" />
|
||||
{t('category.addCategory')}
|
||||
@@ -578,10 +578,10 @@ export default function FamilyView() {
|
||||
|
||||
{showInviteModal && (
|
||||
<div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-center justify-center z-50 p-4">
|
||||
<div className="bg-white rounded-3xl shadow-2xl w-full max-w-md p-6 sm:p-8">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl w-full max-w-md p-6 sm:p-8">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 bg-gradient-to-br from-purple-500 to-blue-500 rounded-2xl">
|
||||
<div className="p-3 category-icon rounded-2xl">
|
||||
<UserPlus className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-gray-800">{t('invite.title')}</h2>
|
||||
@@ -602,7 +602,7 @@ export default function FamilyView() {
|
||||
<button
|
||||
onClick={handleCreateInviteLink}
|
||||
disabled={inviteLoading}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded-2xl hover:shadow-xl transition-all font-semibold disabled:opacity-50"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 btn-primary text-white rounded-2xl hover:shadow-xl transition-all font-semibold disabled:opacity-50"
|
||||
>
|
||||
{inviteLoading ? (
|
||||
<>
|
||||
@@ -631,8 +631,8 @@ export default function FamilyView() {
|
||||
onClick={handleCopyInviteLink}
|
||||
className={`w-full flex items-center justify-center gap-2 px-6 py-4 rounded-2xl transition-all font-semibold ${
|
||||
copied
|
||||
? 'bg-green-500 text-white'
|
||||
: 'bg-gradient-to-r from-purple-600 to-blue-600 text-white hover:shadow-xl'
|
||||
? 'btn-success text-white'
|
||||
: 'btn-primary text-white hover:shadow-xl'
|
||||
}`}
|
||||
>
|
||||
{copied ? (
|
||||
|
||||
@@ -109,15 +109,15 @@ export default function InvitePage() {
|
||||
if (error) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center gradient-bg px-4">
|
||||
<div className="bg-white rounded-3xl shadow-2xl p-8 max-w-md w-full text-center">
|
||||
<div className="p-4 bg-red-100 rounded-2xl inline-block mb-6">
|
||||
<AlertCircle className="w-12 h-12 text-red-500" />
|
||||
<div className="glass-effect rounded-3xl shadow-2xl p-8 max-w-md w-full text-center">
|
||||
<div className="p-4 btn-danger rounded-2xl inline-block mb-6">
|
||||
<AlertCircle className="w-12 h-12 text-white" />
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-4">{t('common.error')}</h1>
|
||||
<p className="text-gray-600 mb-6">{error}</p>
|
||||
<button
|
||||
onClick={() => navigate('/')}
|
||||
className="px-6 py-3 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded-2xl font-semibold hover:shadow-xl transition-all"
|
||||
className="px-6 py-3 btn-primary text-white rounded-2xl font-semibold hover:shadow-xl transition-all"
|
||||
>
|
||||
{t('common.toHome')}
|
||||
</button>
|
||||
@@ -128,14 +128,14 @@ export default function InvitePage() {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center gradient-bg px-4">
|
||||
<div className="bg-white rounded-3xl shadow-2xl p-8 max-w-md w-full text-center">
|
||||
<div className="p-4 bg-gradient-to-br from-purple-500 to-blue-500 rounded-2xl inline-block mb-6">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl p-8 max-w-md w-full text-center">
|
||||
<div className="p-4 category-icon rounded-2xl inline-block mb-6">
|
||||
<Users className="w-12 h-12 text-white" />
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-gray-800 mb-2">
|
||||
{t('invite.pageTitle')}
|
||||
</h1>
|
||||
<p className="text-3xl font-bold text-purple-600 mb-6">
|
||||
<p className="text-3xl font-bold text-gray-800 mb-6">
|
||||
{familyName}
|
||||
</p>
|
||||
<p className="text-gray-600 mb-8">
|
||||
@@ -143,7 +143,7 @@ export default function InvitePage() {
|
||||
</p>
|
||||
<button
|
||||
onClick={handleGoogleLogin}
|
||||
className="w-full flex items-center justify-center gap-3 px-6 py-4 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded-2xl font-semibold hover:shadow-xl transition-all"
|
||||
className="w-full flex items-center justify-center gap-3 px-6 py-4 btn-primary text-white rounded-2xl font-semibold hover:shadow-xl transition-all"
|
||||
>
|
||||
<UserPlus className="w-5 h-5" />
|
||||
{t('invite.loginAndJoin')}
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function Login() {
|
||||
<div className="w-full max-w-md">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl p-8 sm:p-10">
|
||||
<div className="flex flex-col items-center text-center mb-8">
|
||||
<div className="p-4 bg-linear-to-br from-purple-500 to-blue-500 text-white rounded-2xl mb-4 shadow-lg">
|
||||
<div className="p-4 category-icon text-white rounded-2xl mb-4 shadow-lg">
|
||||
<Wallet className="w-12 h-12" />
|
||||
</div>
|
||||
<h1 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-2">
|
||||
|
||||
@@ -118,7 +118,7 @@ export default function NoFamily() {
|
||||
<div className="w-full max-w-md">
|
||||
<div className="glass-effect rounded-3xl shadow-2xl p-8 sm:p-10">
|
||||
<div className="flex flex-col items-center text-center mb-6">
|
||||
<div className="p-4 bg-linear-to-br from-purple-500 to-blue-500 text-white rounded-2xl mb-4 shadow-lg">
|
||||
<div className="p-4 category-icon text-white rounded-2xl mb-4 shadow-lg">
|
||||
<Users className="w-12 h-12" />
|
||||
</div>
|
||||
<h1 className="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">
|
||||
@@ -186,7 +186,7 @@ export default function NoFamily() {
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !familyName.trim()}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 bg-linear-to-r from-purple-600 to-blue-600 text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-4 btn-primary text-white rounded-2xl hover:shadow-xl transition-all duration-300 font-semibold disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{loading ? (
|
||||
<Loader2 className="w-5 h-5 animate-spin" />
|
||||
|
||||
@@ -20,13 +20,13 @@ import {
|
||||
X,
|
||||
} from 'lucide-react';
|
||||
|
||||
const THEMES: { id: Theme; name: string; gradient: string }[] = [
|
||||
{ id: 'light', name: 'Light', gradient: 'bg-gradient-to-r from-gray-100 to-gray-200' },
|
||||
{ id: 'dark', name: 'Dark', gradient: 'bg-gradient-to-r from-gray-800 to-gray-900' },
|
||||
{ id: 'sunset', name: 'Sunset', gradient: 'bg-gradient-to-r from-orange-400 to-pink-500' },
|
||||
{ id: 'ocean', name: 'Ocean', gradient: 'bg-gradient-to-r from-blue-400 to-cyan-500' },
|
||||
{ id: 'forest', name: 'Forest', gradient: 'bg-gradient-to-r from-green-400 to-teal-500' },
|
||||
{ id: 'purple', name: 'Purple', gradient: 'bg-gradient-to-r from-purple-500 to-pink-500' },
|
||||
const THEMES: { id: Theme; gradient: string }[] = [
|
||||
{ id: 'light', gradient: 'bg-gradient-to-r from-gray-100 to-gray-200' },
|
||||
{ id: 'dark', gradient: 'bg-gradient-to-r from-black to-gray-900' },
|
||||
{ id: 'sunset', gradient: 'bg-gradient-to-r from-orange-400 to-pink-500' },
|
||||
{ id: 'ocean', gradient: 'bg-gradient-to-r from-blue-400 to-cyan-500' },
|
||||
{ id: 'forest', gradient: 'bg-gradient-to-r from-green-400 to-teal-500' },
|
||||
{ id: 'purple', gradient: 'bg-gradient-to-r from-purple-500 to-pink-500' },
|
||||
];
|
||||
|
||||
export default function Profile() {
|
||||
@@ -140,7 +140,7 @@ export default function Profile() {
|
||||
<div className="space-y-6">
|
||||
<div className="glass-effect rounded-2xl shadow-lg p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 bg-gradient-to-br from-blue-500 to-purple-500 text-white rounded-xl">
|
||||
<div className="p-2 category-icon text-white rounded-xl">
|
||||
<UserIcon className="w-6 h-6" />
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-gray-800">{t('profile.info')}</h2>
|
||||
@@ -160,7 +160,7 @@ export default function Profile() {
|
||||
{selectedFamily && (
|
||||
<div className="glass-effect rounded-2xl shadow-lg p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 bg-gradient-to-br from-green-500 to-teal-500 text-white rounded-xl">
|
||||
<div className="p-2 btn-success text-white rounded-xl">
|
||||
<Users className="w-6 h-6" />
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-gray-800">{t('profile.family')}</h2>
|
||||
@@ -220,7 +220,7 @@ export default function Profile() {
|
||||
className={`flex items-center justify-between p-3 rounded-xl ${member.id === user?.id ? 'bg-purple-50 border border-purple-200' : 'bg-gray-50'}`}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 bg-gradient-to-br from-purple-400 to-blue-400 rounded-full flex items-center justify-center text-white text-sm font-medium">
|
||||
<div className="w-8 h-8 category-icon rounded-full flex items-center justify-center text-white text-sm font-medium">
|
||||
{(member.username || member.email || '?')[0].toUpperCase()}
|
||||
</div>
|
||||
<span className="font-medium text-gray-800">
|
||||
@@ -247,7 +247,7 @@ export default function Profile() {
|
||||
|
||||
<div className="glass-effect rounded-2xl shadow-lg p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 bg-gradient-to-br from-purple-500 to-pink-500 text-white rounded-xl">
|
||||
<div className="p-2 btn-primary text-white rounded-xl">
|
||||
<Settings className="w-6 h-6" />
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-gray-800">{t('profile.settings')}</h2>
|
||||
@@ -264,7 +264,7 @@ export default function Profile() {
|
||||
onClick={() => handleLocaleChange('ru')}
|
||||
className={`flex-1 py-3 px-4 rounded-xl font-medium transition-all ${
|
||||
preferences.locale === 'ru'
|
||||
? 'bg-purple-500 text-white shadow-lg'
|
||||
? 'btn-primary text-white shadow-lg'
|
||||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||||
}`}
|
||||
>
|
||||
@@ -276,7 +276,7 @@ export default function Profile() {
|
||||
onClick={() => handleLocaleChange('en')}
|
||||
className={`flex-1 py-3 px-4 rounded-xl font-medium transition-all ${
|
||||
preferences.locale === 'en'
|
||||
? 'bg-purple-500 text-white shadow-lg'
|
||||
? 'btn-primary text-white shadow-lg'
|
||||
: 'bg-gray-100 text-gray-700 hover:bg-gray-200'
|
||||
}`}
|
||||
>
|
||||
@@ -304,7 +304,7 @@ export default function Profile() {
|
||||
}`}
|
||||
>
|
||||
<div className={`h-12 rounded-lg ${theme.gradient}`} />
|
||||
<span className="text-xs text-gray-600 mt-1 block">{theme.name}</span>
|
||||
<span className="text-xs text-gray-600 mt-1 block">{t(`profile.themes.${theme.id}`)}</span>
|
||||
{preferences.theme === theme.id && (
|
||||
<div className="absolute top-2 right-2 w-5 h-5 bg-white rounded-full flex items-center justify-center shadow">
|
||||
<Check className="w-3 h-3 text-purple-600" />
|
||||
@@ -320,7 +320,7 @@ export default function Profile() {
|
||||
{selectedFamily && (
|
||||
<div className="glass-effect rounded-2xl shadow-lg p-6 border-2 border-red-200">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="p-2 bg-gradient-to-br from-red-500 to-orange-500 text-white rounded-xl">
|
||||
<div className="p-2 btn-danger text-white rounded-xl">
|
||||
<AlertTriangle className="w-6 h-6" />
|
||||
</div>
|
||||
<h2 className="text-xl font-bold text-gray-800">{t('profile.dangerZone')}</h2>
|
||||
@@ -331,7 +331,7 @@ export default function Profile() {
|
||||
<button
|
||||
onClick={handleLeaveFamily}
|
||||
disabled={leavingFamily}
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-3 bg-red-500 hover:bg-red-600 text-white rounded-xl transition-all font-semibold disabled:opacity-50"
|
||||
className="w-full flex items-center justify-center gap-2 px-6 py-3 btn-danger text-white rounded-xl transition-all font-semibold disabled:opacity-50"
|
||||
>
|
||||
{leavingFamily ? (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user