systemprompt_content/
branding_provider.rs1use std::sync::Arc;
2
3use anyhow::Result;
4use async_trait::async_trait;
5use serde_json::Value;
6use systemprompt_cloud::constants::storage;
7use systemprompt_models::ContentConfigRaw;
8use systemprompt_provider_contracts::{PageContext, PageDataProvider};
9
10#[derive(Debug, Clone, Copy, Default)]
11pub struct DefaultBrandingProvider;
12
13#[async_trait]
14impl PageDataProvider for DefaultBrandingProvider {
15 fn provider_id(&self) -> &'static str {
16 "default-branding"
17 }
18
19 async fn provide_page_data(&self, ctx: &PageContext<'_>) -> Result<Value> {
20 let content_config = ctx
21 .content_config::<ContentConfigRaw>()
22 .ok_or_else(|| anyhow::anyhow!("ContentConfigRaw not available in PageContext"))?;
23
24 let org = &content_config.metadata.structured_data.organization;
25 let branding = &ctx.web_config.branding;
26
27 Ok(serde_json::json!({
28 "ORG_NAME": org.name,
29 "ORG_URL": org.url,
30 "ORG_LOGO": org.logo,
31 "LOGO_PATH": branding.logo.primary.svg.as_deref().unwrap_or(""),
32 "FAVICON_PATH": &branding.favicon,
33 "TWITTER_HANDLE": &branding.twitter_handle,
34 "DISPLAY_SITENAME": branding.display_sitename,
35 "CSS_BASE_PATH": format!("/{}", storage::CSS),
36 "JS_BASE_PATH": format!("/{}", storage::JS),
37 "HEADER_CTA_URL": "/",
38 }))
39 }
40}
41
42pub fn default_branding_provider() -> Arc<dyn PageDataProvider> {
43 Arc::new(DefaultBrandingProvider)
44}