mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 07:52:10 +01:00
feat: comprehensive UI improvements and new logo design
- Replace old logo with modern dashboard tiles design - Improve text selection styling using Tailwind selection variant - Fix session ID display with proper truncation classes - Clean up temporary logo files and showcase page - Enhance dark mode support across company settings and sessions pages - Remove obsolete Alert Configuration from company settings - Add collapsible filters and mobile-optimized view details buttons
This commit is contained in:
@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { ShieldX, Settings, Save, Database, Bell } from "lucide-react";
|
||||
import { ShieldX, Settings, Save, Database } from "lucide-react";
|
||||
|
||||
export default function CompanySettingsPage() {
|
||||
const { data: session, status } = useSession();
|
||||
@ -18,7 +18,6 @@ export default function CompanySettingsPage() {
|
||||
const [csvUrl, setCsvUrl] = useState<string>("");
|
||||
const [csvUsername, setCsvUsername] = useState<string>("");
|
||||
const [csvPassword, setCsvPassword] = useState<string>("");
|
||||
const [sentimentThreshold, setSentimentThreshold] = useState<string>("");
|
||||
const [message, setMessage] = useState<string>("");
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@ -32,7 +31,6 @@ export default function CompanySettingsPage() {
|
||||
setCompany(data.company);
|
||||
setCsvUrl(data.company.csvUrl || "");
|
||||
setCsvUsername(data.company.csvUsername || "");
|
||||
setSentimentThreshold(data.company.sentimentAlert?.toString() || "");
|
||||
if (data.company.csvPassword) {
|
||||
setCsvPassword(data.company.csvPassword);
|
||||
}
|
||||
@ -57,7 +55,6 @@ export default function CompanySettingsPage() {
|
||||
csvUrl,
|
||||
csvUsername,
|
||||
csvPassword,
|
||||
sentimentThreshold,
|
||||
}),
|
||||
});
|
||||
|
||||
@ -146,85 +143,54 @@ export default function CompanySettingsPage() {
|
||||
}}
|
||||
autoComplete="off"
|
||||
>
|
||||
<div className="grid gap-6 md:grid-cols-2">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Database className="h-5 w-5" />
|
||||
<CardTitle className="text-lg">Data Source Configuration</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvUrl">CSV Data Source URL</Label>
|
||||
<Input
|
||||
id="csvUrl"
|
||||
type="text"
|
||||
value={csvUrl}
|
||||
onChange={(e) => setCsvUrl(e.target.value)}
|
||||
placeholder="https://example.com/data.csv"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Database className="h-5 w-5" />
|
||||
<CardTitle className="text-lg">Data Source Configuration</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvUrl">CSV Data Source URL</Label>
|
||||
<Input
|
||||
id="csvUrl"
|
||||
type="text"
|
||||
value={csvUrl}
|
||||
onChange={(e) => setCsvUrl(e.target.value)}
|
||||
placeholder="https://example.com/data.csv"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvUsername">CSV Username</Label>
|
||||
<Input
|
||||
id="csvUsername"
|
||||
type="text"
|
||||
value={csvUsername}
|
||||
onChange={(e) => setCsvUsername(e.target.value)}
|
||||
placeholder="Username for CSV access (if needed)"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvUsername">CSV Username</Label>
|
||||
<Input
|
||||
id="csvUsername"
|
||||
type="text"
|
||||
value={csvUsername}
|
||||
onChange={(e) => setCsvUsername(e.target.value)}
|
||||
placeholder="Username for CSV access (if needed)"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvPassword">CSV Password</Label>
|
||||
<Input
|
||||
id="csvPassword"
|
||||
type="password"
|
||||
value={csvPassword}
|
||||
onChange={(e) => setCsvPassword(e.target.value)}
|
||||
placeholder="Password will be updated only if provided"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Leave blank to keep current password
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Bell className="h-5 w-5" />
|
||||
<CardTitle className="text-lg">Alert Configuration</CardTitle>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="sentimentThreshold">
|
||||
Sentiment Alert Threshold
|
||||
</Label>
|
||||
<Input
|
||||
id="sentimentThreshold"
|
||||
type="number"
|
||||
value={sentimentThreshold}
|
||||
onChange={(e) => setSentimentThreshold(e.target.value)}
|
||||
placeholder="Threshold value (0-100)"
|
||||
min="0"
|
||||
max="100"
|
||||
autoComplete="off"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Percentage of negative sentiment sessions to trigger alert (0-100)
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="csvPassword">CSV Password</Label>
|
||||
<Input
|
||||
id="csvPassword"
|
||||
type="password"
|
||||
value={csvPassword}
|
||||
onChange={(e) => setCsvPassword(e.target.value)}
|
||||
placeholder="Password will be updated only if provided"
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Leave blank to keep current password
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit" className="gap-2">
|
||||
|
||||
@ -339,19 +339,24 @@ export default function SessionsPage() {
|
||||
<Badge variant="outline" className="font-mono text-xs">
|
||||
ID
|
||||
</Badge>
|
||||
<code className="text-sm text-muted-foreground font-mono">
|
||||
{(session.sessionId || session.id).slice(0, 8)}...
|
||||
<code className="text-sm text-muted-foreground font-mono truncate max-w-24">
|
||||
{session.sessionId || session.id}
|
||||
</code>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<Clock className="h-4 w-4" />
|
||||
{new Date(session.startTime).toLocaleString()}
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="outline" className="text-xs">
|
||||
<Clock className="h-3 w-3 mr-1" />
|
||||
{new Date(session.startTime).toLocaleDateString()}
|
||||
</Badge>
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{new Date(session.startTime).toLocaleTimeString()}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<Link href={`/dashboard/sessions/${session.id}`}>
|
||||
<Button variant="outline" size="sm" className="gap-2">
|
||||
<Eye className="h-4 w-4" />
|
||||
View Details
|
||||
<span className="hidden sm:inline">View Details</span>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@ -163,23 +163,12 @@
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
@apply border-border outline-ring/50 selection:bg-primary/30 selection:text-primary-foreground;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
/* Custom text selection colors */
|
||||
::selection {
|
||||
background-color: hsl(var(--primary) / 0.3);
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: hsl(var(--primary) / 0.3);
|
||||
color: hsl(var(--primary-foreground));
|
||||
}
|
||||
|
||||
/* Line clamp utility */
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
|
||||
Reference in New Issue
Block a user