187 lines
6.5 KiB
Rust
187 lines
6.5 KiB
Rust
use gpui::{Entity, Render};
|
|
use ui::{ProgressBar, prelude::*};
|
|
|
|
#[derive(RegisterComponent)]
|
|
pub struct UserSpending {
|
|
free_tier_current: u32,
|
|
free_tier_cap: u32,
|
|
over_tier_current: u32,
|
|
over_tier_cap: u32,
|
|
free_tier_progress: Entity<ProgressBar>,
|
|
over_tier_progress: Entity<ProgressBar>,
|
|
}
|
|
|
|
impl UserSpending {
|
|
pub fn new(
|
|
free_tier_current: u32,
|
|
free_tier_cap: u32,
|
|
over_tier_current: u32,
|
|
over_tier_cap: u32,
|
|
cx: &mut App,
|
|
) -> Self {
|
|
let free_tier_capped = free_tier_current == free_tier_cap;
|
|
let free_tier_near_capped =
|
|
free_tier_current as f32 / 100.0 >= free_tier_cap as f32 / 100.0 * 0.9;
|
|
let over_tier_capped = over_tier_current == over_tier_cap;
|
|
let over_tier_near_capped =
|
|
over_tier_current as f32 / 100.0 >= over_tier_cap as f32 / 100.0 * 0.9;
|
|
|
|
let free_tier_progress = cx.new(|cx| {
|
|
ProgressBar::new(
|
|
"free_tier",
|
|
free_tier_current as f32,
|
|
free_tier_cap as f32,
|
|
cx,
|
|
)
|
|
});
|
|
let over_tier_progress = cx.new(|cx| {
|
|
ProgressBar::new(
|
|
"over_tier",
|
|
over_tier_current as f32,
|
|
over_tier_cap as f32,
|
|
cx,
|
|
)
|
|
});
|
|
|
|
if free_tier_capped {
|
|
free_tier_progress.update(cx, |progress_bar, cx| {
|
|
progress_bar.fg_color(cx.theme().status().error);
|
|
});
|
|
} else if free_tier_near_capped {
|
|
free_tier_progress.update(cx, |progress_bar, cx| {
|
|
progress_bar.fg_color(cx.theme().status().warning);
|
|
});
|
|
}
|
|
|
|
if over_tier_capped {
|
|
over_tier_progress.update(cx, |progress_bar, cx| {
|
|
progress_bar.fg_color(cx.theme().status().error);
|
|
});
|
|
} else if over_tier_near_capped {
|
|
over_tier_progress.update(cx, |progress_bar, cx| {
|
|
progress_bar.fg_color(cx.theme().status().warning);
|
|
});
|
|
}
|
|
|
|
Self {
|
|
free_tier_current,
|
|
free_tier_cap,
|
|
over_tier_current,
|
|
over_tier_cap,
|
|
free_tier_progress,
|
|
over_tier_progress,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Render for UserSpending {
|
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
|
let formatted_free_tier = format!(
|
|
"${} / ${}",
|
|
self.free_tier_current as f32 / 100.0,
|
|
self.free_tier_cap as f32 / 100.0
|
|
);
|
|
let formatted_over_tier = format!(
|
|
"${} / ${}",
|
|
self.over_tier_current as f32 / 100.0,
|
|
self.over_tier_cap as f32 / 100.0
|
|
);
|
|
|
|
v_group()
|
|
.elevation_2(cx)
|
|
.py_1p5()
|
|
.px_2p5()
|
|
.w(px(360.))
|
|
.child(
|
|
v_flex()
|
|
.child(
|
|
v_flex()
|
|
.p_1p5()
|
|
.gap_0p5()
|
|
.child(
|
|
h_flex()
|
|
.justify_between()
|
|
.child(Label::new("Free Tier Usage").size(LabelSize::Small))
|
|
.child(
|
|
Label::new(formatted_free_tier)
|
|
.size(LabelSize::Small)
|
|
.color(Color::Muted),
|
|
),
|
|
)
|
|
.child(self.free_tier_progress.clone()),
|
|
)
|
|
.child(
|
|
v_flex()
|
|
.p_1p5()
|
|
.gap_0p5()
|
|
.child(
|
|
h_flex()
|
|
.justify_between()
|
|
.child(Label::new("Current Spending").size(LabelSize::Small))
|
|
.child(
|
|
Label::new(formatted_over_tier)
|
|
.size(LabelSize::Small)
|
|
.color(Color::Muted),
|
|
),
|
|
)
|
|
.child(self.over_tier_progress.clone()),
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl Component for UserSpending {
|
|
fn scope() -> ComponentScope {
|
|
ComponentScope::None
|
|
}
|
|
|
|
fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
|
|
let new_user = cx.new(|cx| UserSpending::new(0, 2000, 0, 2000, cx));
|
|
let free_capped = cx.new(|cx| UserSpending::new(2000, 2000, 0, 2000, cx));
|
|
let free_near_capped = cx.new(|cx| UserSpending::new(1800, 2000, 0, 2000, cx));
|
|
let over_near_capped = cx.new(|cx| UserSpending::new(2000, 2000, 1800, 2000, cx));
|
|
let over_capped = cx.new(|cx| UserSpending::new(1000, 2000, 2000, 2000, cx));
|
|
|
|
Some(
|
|
v_flex()
|
|
.gap_6()
|
|
.p_4()
|
|
.children(vec![example_group(vec![
|
|
single_example(
|
|
"New User",
|
|
div().size_full().child(new_user.clone()).into_any_element(),
|
|
),
|
|
single_example(
|
|
"Free Tier Capped",
|
|
div()
|
|
.size_full()
|
|
.child(free_capped.clone())
|
|
.into_any_element(),
|
|
),
|
|
single_example(
|
|
"Free Tier Near Capped",
|
|
div()
|
|
.size_full()
|
|
.child(free_near_capped.clone())
|
|
.into_any_element(),
|
|
),
|
|
single_example(
|
|
"Over Tier Near Capped",
|
|
div()
|
|
.size_full()
|
|
.child(over_near_capped.clone())
|
|
.into_any_element(),
|
|
),
|
|
single_example(
|
|
"Over Tier Capped",
|
|
div()
|
|
.size_full()
|
|
.child(over_capped.clone())
|
|
.into_any_element(),
|
|
),
|
|
])])
|
|
.into_any_element(),
|
|
)
|
|
}
|
|
}
|