wip 8
This commit is contained in:
@@ -68,7 +68,11 @@ export function Toast({ id, type, message, duration = 5000, onClose }: ToastProp
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${baseStyles} ${typeStyles[type]} ${isAnimatingOut ? 'opacity-0 translate-x-full' : 'opacity-100 translate-x-0'}`}
|
className={`${baseStyles} ${typeStyles[type]} ${
|
||||||
|
isAnimatingOut
|
||||||
|
? 'opacity-0 translate-x-full'
|
||||||
|
: 'animate-slideInRight opacity-100'
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{icons[type]}
|
{icons[type]}
|
||||||
<p className={`flex-1 text-sm font-medium ${textStyles[type]}`}>
|
<p className={`flex-1 text-sm font-medium ${textStyles[type]}`}>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function ToastContainer({ toasts }: ToastContainerProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed top-4 right-4 z-50 flex flex-col gap-2 max-w-sm w-full pointer-events-none">
|
<div className="fixed bottom-4 right-4 z-50 flex flex-col gap-2 max-w-sm w-full pointer-events-none">
|
||||||
<div className="pointer-events-auto">
|
<div className="pointer-events-auto">
|
||||||
{toasts.map((toast) => (
|
{toasts.map((toast) => (
|
||||||
<Toast key={toast.id} {...toast} />
|
<Toast key={toast.id} {...toast} />
|
||||||
|
|||||||
@@ -130,3 +130,19 @@ main {
|
|||||||
);
|
);
|
||||||
background-size: 200% 100%;
|
background-size: 200% 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Toast Slide In Animation */
|
||||||
|
@keyframes slideInRight {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slideInRight {
|
||||||
|
animation: slideInRight 0.3s ease-out forwards;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useState, FormEvent } from 'react';
|
import { useState, useEffect, FormEvent } from 'react';
|
||||||
import { useGetSettings, useUpdateSettings } from '../generated/anthoLumeAPIV1';
|
import { useGetSettings, useUpdateSettings } from '../generated/anthoLumeAPIV1';
|
||||||
import { User, Lock, Clock } from 'lucide-react';
|
import { User, Lock, Clock } from 'lucide-react';
|
||||||
import { Button } from '../components/Button';
|
import { Button } from '../components/Button';
|
||||||
@@ -7,12 +7,18 @@ import { useToasts } from '../components/ToastContext';
|
|||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const { data, isLoading } = useGetSettings();
|
const { data, isLoading } = useGetSettings();
|
||||||
const updateSettings = useUpdateSettings();
|
const updateSettings = useUpdateSettings();
|
||||||
const settingsData = data?.data;
|
const settingsData = data;
|
||||||
const { showInfo, showError } = useToasts();
|
const { showInfo, showError } = useToasts();
|
||||||
|
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [newPassword, setNewPassword] = useState('');
|
const [newPassword, setNewPassword] = useState('');
|
||||||
const [timezone, setTimezone] = useState(settingsData?.timezone || '');
|
const [timezone, setTimezone] = useState('UTC');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (settingsData?.data.timezone && settingsData.data.timezone.trim() !== '') {
|
||||||
|
setTimezone(settingsData.data.timezone);
|
||||||
|
}
|
||||||
|
}, [settingsData]);
|
||||||
|
|
||||||
const handlePasswordSubmit = async (e: FormEvent) => {
|
const handlePasswordSubmit = async (e: FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -99,7 +105,7 @@ export default function SettingsPage() {
|
|||||||
className="flex flex-col p-4 items-center rounded shadow-lg md:w-60 lg:w-80 bg-white dark:bg-gray-700 text-gray-500 dark:text-white"
|
className="flex flex-col p-4 items-center rounded shadow-lg md:w-60 lg:w-80 bg-white dark:bg-gray-700 text-gray-500 dark:text-white"
|
||||||
>
|
>
|
||||||
<User size={60} />
|
<User size={60} />
|
||||||
<p className="text-lg">{settingsData?.user?.username}</p>
|
<p className="text-lg">{settingsData?.data.user.username || "N/A"}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -167,7 +173,7 @@ export default function SettingsPage() {
|
|||||||
<Clock size={15} />
|
<Clock size={15} />
|
||||||
</span>
|
</span>
|
||||||
<select
|
<select
|
||||||
value={timezone}
|
value={timezone || 'UTC'}
|
||||||
onChange={(e) => setTimezone(e.target.value)}
|
onChange={(e) => setTimezone(e.target.value)}
|
||||||
className="flex-1 appearance-none rounded-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-purple-600 focus:border-transparent"
|
className="flex-1 appearance-none rounded-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-purple-600 focus:border-transparent"
|
||||||
>
|
>
|
||||||
@@ -215,12 +221,12 @@ export default function SettingsPage() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="text-black dark:text-white">
|
<tbody className="text-black dark:text-white">
|
||||||
{!settingsData?.devices || settingsData.devices.length === 0 ? (
|
{!settingsData?.data.devices || settingsData.data.devices.length === 0 ? (
|
||||||
<tr>
|
<tr>
|
||||||
<td className="text-center p-3" colSpan={3}>No Results</td>
|
<td className="text-center p-3" colSpan={3}>No Results</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : (
|
) : (
|
||||||
settingsData.devices.map((device: any) => (
|
settingsData.data.devices.map((device: any) => (
|
||||||
<tr key={device.id}>
|
<tr key={device.id}>
|
||||||
<td className="p-3 pl-0">
|
<td className="p-3 pl-0">
|
||||||
<p>{device.device_name || 'Unknown'}</p>
|
<p>{device.device_name || 'Unknown'}</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user