227 lines
8.2 KiB
Plaintext
227 lines
8.2 KiB
Plaintext
// Profiles Page - Configuration profiles management
|
||
import { Theme, Typography, SpacingSystem } from "../theme/theme.slint";
|
||
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "../components/card.slint";
|
||
import { Button } from "../components/button.slint";
|
||
import { Badge } from "../components/badge.slint";
|
||
import { Empty } from "../components/empty.slint";
|
||
import { Profile } from "../types.slint";
|
||
|
||
export component ProfilesPage inherits Rectangle {
|
||
in property <[Profile]> profiles;
|
||
|
||
callback load-profiles();
|
||
callback select-profile(string /* profile-id */);
|
||
callback update-profile(string /* profile-id */);
|
||
callback delete-profile(string /* profile-id */);
|
||
callback add-profile();
|
||
|
||
background: Theme.colors.background;
|
||
|
||
VerticalLayout {
|
||
// Fixed header
|
||
Rectangle {
|
||
height: 48px;
|
||
background: Theme.colors.background;
|
||
|
||
HorizontalLayout {
|
||
padding: SpacingSystem.spacing.s4;
|
||
spacing: SpacingSystem.spacing.s4;
|
||
alignment: space-between;
|
||
|
||
Text {
|
||
text: "Profiles";
|
||
font-size: Typography.sizes.xl;
|
||
font-weight: Typography.weights.bold;
|
||
color: Theme.colors.foreground;
|
||
vertical-alignment: center;
|
||
}
|
||
|
||
// Action buttons
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
|
||
Button {
|
||
text: "➕";
|
||
variant: "ghost";
|
||
size: "sm";
|
||
|
||
clicked => {
|
||
root.add-profile();
|
||
}
|
||
}
|
||
|
||
Button {
|
||
text: "🔄";
|
||
variant: "ghost";
|
||
size: "sm";
|
||
|
||
clicked => {
|
||
root.load-profiles();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Scrollable content
|
||
Flickable {
|
||
viewport-height: content-layout.preferred-height + SpacingSystem.spacing.s4 * 2;
|
||
|
||
content-layout := VerticalLayout {
|
||
padding: SpacingSystem.spacing.s4;
|
||
spacing: SpacingSystem.spacing.s4;
|
||
|
||
// Empty state
|
||
if profiles.length == 0: Empty {
|
||
height: 300px;
|
||
icon: "📋";
|
||
title: "No Profiles";
|
||
description: "Click + to add a new profile";
|
||
}
|
||
|
||
// Profile list
|
||
for profile in profiles: Card {
|
||
hoverable: true;
|
||
|
||
CardHeader {
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
alignment: space-between;
|
||
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
|
||
Text {
|
||
text: "☁";
|
||
font-size: Typography.sizes.xl;
|
||
vertical-alignment: center;
|
||
}
|
||
|
||
VerticalLayout {
|
||
spacing: SpacingSystem.spacing.s1;
|
||
|
||
CardTitle {
|
||
text: profile.name;
|
||
}
|
||
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s1;
|
||
|
||
Badge {
|
||
text: profile.type;
|
||
variant: "outline";
|
||
}
|
||
|
||
if profile.selected: Badge {
|
||
text: "Active";
|
||
variant: "default";
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Button {
|
||
text: "🔄";
|
||
variant: "ghost";
|
||
size: "sm";
|
||
|
||
clicked => {
|
||
root.update-profile(profile.id);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
CardContent {
|
||
VerticalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
|
||
// Usage
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
alignment: space-between;
|
||
|
||
Text {
|
||
text: "Usage:";
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.muted-foreground;
|
||
}
|
||
|
||
Text {
|
||
text: profile.usage;
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.foreground;
|
||
font-weight: Typography.weights.medium;
|
||
}
|
||
}
|
||
|
||
// Expire date
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
alignment: space-between;
|
||
|
||
Text {
|
||
text: "Expires:";
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.muted-foreground;
|
||
}
|
||
|
||
Text {
|
||
text: profile.expire-at;
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.foreground;
|
||
font-weight: Typography.weights.medium;
|
||
}
|
||
}
|
||
|
||
// Updated date
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
alignment: space-between;
|
||
|
||
Text {
|
||
text: "Updated:";
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.muted-foreground;
|
||
}
|
||
|
||
Text {
|
||
text: profile.updated-at;
|
||
font-size: Typography.sizes.xs;
|
||
color: Theme.colors.muted-foreground;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
CardFooter {
|
||
HorizontalLayout {
|
||
spacing: SpacingSystem.spacing.s2;
|
||
|
||
if !profile.selected: Button {
|
||
text: "Select";
|
||
variant: "default";
|
||
size: "sm";
|
||
|
||
clicked => {
|
||
root.select-profile(profile.id);
|
||
}
|
||
}
|
||
|
||
Button {
|
||
text: "Delete";
|
||
variant: "destructive";
|
||
size: "sm";
|
||
|
||
clicked => {
|
||
root.delete-profile(profile.id);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|