1use std::sync::Arc;
2
3use ai_onboarding::{AgentPanelOnboardingCard, BulletItem};
4use client::zed_urls;
5use gpui::{AnyElement, App, IntoElement, RenderOnce, Window};
6use ui::{Divider, List, prelude::*};
7
8#[derive(IntoElement, RegisterComponent)]
9pub struct EndTrialUpsell {
10 dismiss_upsell: Arc<dyn Fn(&mut Window, &mut App)>,
11}
12
13impl EndTrialUpsell {
14 pub fn new(dismiss_upsell: Arc<dyn Fn(&mut Window, &mut App)>) -> Self {
15 Self { dismiss_upsell }
16 }
17}
18
19impl RenderOnce for EndTrialUpsell {
20 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
21 let pro_section = v_flex()
22 .gap_1()
23 .child(
24 h_flex()
25 .gap_2()
26 .child(
27 Label::new("Pro")
28 .size(LabelSize::Small)
29 .color(Color::Accent)
30 .buffer_font(cx),
31 )
32 .child(Divider::horizontal()),
33 )
34 .child(
35 List::new()
36 .child(BulletItem::new("500 prompts per month with Claude models"))
37 .child(BulletItem::new("Unlimited edit predictions")),
38 )
39 .child(
40 Button::new("cta-button", "Upgrade to Zed Pro")
41 .full_width()
42 .style(ButtonStyle::Tinted(ui::TintColor::Accent))
43 .on_click(|_, _, cx| cx.open_url(&zed_urls::upgrade_to_zed_pro_url(cx))),
44 );
45
46 let free_section = v_flex()
47 .mt_1p5()
48 .gap_1()
49 .child(
50 h_flex()
51 .gap_2()
52 .child(
53 Label::new("Free")
54 .size(LabelSize::Small)
55 .color(Color::Muted)
56 .buffer_font(cx),
57 )
58 .child(Divider::horizontal()),
59 )
60 .child(
61 List::new()
62 .child(BulletItem::new(
63 "50 prompts per month with the Claude models",
64 ))
65 .child(BulletItem::new(
66 "2000 accepted edit predictions using our open-source Zeta model",
67 )),
68 )
69 .child(
70 Button::new("dismiss-button", "Stay on Free")
71 .full_width()
72 .style(ButtonStyle::Outlined)
73 .on_click({
74 let callback = self.dismiss_upsell.clone();
75 move |_, window, cx| callback(window, cx)
76 }),
77 );
78
79 AgentPanelOnboardingCard::new()
80 .child(Headline::new("Your Zed Pro trial has expired."))
81 .child(
82 Label::new("You've been automatically reset to the Free plan.")
83 .size(LabelSize::Small)
84 .color(Color::Muted)
85 .mb_1(),
86 )
87 .child(pro_section)
88 .child(free_section)
89 }
90}
91
92impl Component for EndTrialUpsell {
93 fn scope() -> ComponentScope {
94 ComponentScope::Agent
95 }
96
97 fn sort_name() -> &'static str {
98 "AgentEndTrialUpsell"
99 }
100
101 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
102 Some(
103 v_flex()
104 .p_4()
105 .gap_4()
106 .child(EndTrialUpsell {
107 dismiss_upsell: Arc::new(|_, _| {}),
108 })
109 .into_any_element(),
110 )
111 }
112}