RTSDA-Website/church-core/src/models/config.rs

253 lines
7.7 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Coordinates {
pub lat: f64,
pub lng: f64,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ChurchConfig {
pub church_name: Option<String>,
pub church_address: Option<String>,
pub po_box: Option<String>,
pub contact_phone: Option<String>,
pub contact_email: Option<String>,
pub website_url: Option<String>,
pub google_maps_url: Option<String>,
pub facebook_url: Option<String>,
pub youtube_url: Option<String>,
pub instagram_url: Option<String>,
pub about_text: Option<String>,
pub mission_statement: Option<String>,
pub tagline: Option<String>,
pub brand_color: Option<String>,
pub donation_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service_times: Option<Vec<ServiceTime>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pastoral_staff: Option<Vec<StaffMember>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ministries: Option<Vec<Ministry>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub app_settings: Option<AppSettings>,
#[serde(skip_serializing_if = "Option::is_none")]
pub emergency_contacts: Option<Vec<EmergencyContact>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub coordinates: Option<Coordinates>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ServiceTime {
pub day: String,
pub service: String,
pub time: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ServiceTimes {
pub sabbath_school: Option<String>,
pub divine_worship: Option<String>,
pub prayer_meeting: Option<String>,
pub youth_service: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub special_services: Option<Vec<SpecialService>>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SpecialService {
pub name: String,
pub time: String,
pub frequency: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct StaffMember {
pub name: String,
pub title: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub photo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub responsibilities: Option<Vec<String>>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Ministry {
pub name: String,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub leader: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contact_email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contact_phone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub meeting_time: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub meeting_location: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub website: Option<String>,
pub category: MinistryCategory,
#[serde(default)]
pub is_active: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct EmergencyContact {
pub name: String,
pub title: String,
pub phone: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
pub priority: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub availability: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AppSettings {
pub enable_notifications: bool,
pub enable_calendar_sync: bool,
pub enable_offline_mode: bool,
pub theme: AppTheme,
pub default_language: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub owncast_server: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bible_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hymnal_version: Option<String>,
pub cache_duration_minutes: u32,
pub auto_refresh_interval_minutes: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum MinistryCategory {
#[serde(rename = "worship")]
Worship,
#[serde(rename = "education")]
Education,
#[serde(rename = "youth")]
Youth,
#[serde(rename = "children")]
Children,
#[serde(rename = "outreach")]
Outreach,
#[serde(rename = "health")]
Health,
#[serde(rename = "music")]
Music,
#[serde(rename = "fellowship")]
Fellowship,
#[serde(rename = "prayer")]
Prayer,
#[serde(rename = "stewardship")]
Stewardship,
#[serde(rename = "other")]
Other,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum AppTheme {
#[serde(rename = "light")]
Light,
#[serde(rename = "dark")]
Dark,
#[serde(rename = "system")]
System,
}
impl Default for AppSettings {
fn default() -> Self {
Self {
enable_notifications: true,
enable_calendar_sync: true,
enable_offline_mode: true,
theme: AppTheme::System,
default_language: "en".to_string(),
owncast_server: None,
bible_version: Some("KJV".to_string()),
hymnal_version: Some("1985".to_string()),
cache_duration_minutes: 60,
auto_refresh_interval_minutes: 15,
}
}
}
impl ChurchConfig {
pub fn get_display_name(&self) -> String {
self.church_name
.as_ref()
.cloned()
.unwrap_or_else(|| "Church".to_string())
}
pub fn has_social_media(&self) -> bool {
self.facebook_url.is_some() || self.youtube_url.is_some() || self.instagram_url.is_some()
}
pub fn get_contact_info(&self) -> Vec<(String, String)> {
let mut contacts = Vec::new();
if let Some(phone) = &self.contact_phone {
contacts.push(("Phone".to_string(), phone.clone()));
}
if let Some(email) = &self.contact_email {
contacts.push(("Email".to_string(), email.clone()));
}
if let Some(address) = &self.church_address {
contacts.push(("Address".to_string(), address.clone()));
}
if let Some(po_box) = &self.po_box {
contacts.push(("PO Box".to_string(), po_box.clone()));
}
contacts
}
pub fn active_ministries(&self) -> Vec<&Ministry> {
self.ministries
.as_ref()
.map(|ministries| {
ministries
.iter()
.filter(|ministry| ministry.is_active)
.collect()
})
.unwrap_or_default()
}
pub fn ministries_by_category(&self, category: MinistryCategory) -> Vec<&Ministry> {
self.ministries
.as_ref()
.map(|ministries| {
ministries
.iter()
.filter(|ministry| ministry.category == category && ministry.is_active)
.collect()
})
.unwrap_or_default()
}
pub fn emergency_contacts_by_priority(&self) -> Vec<&EmergencyContact> {
self.emergency_contacts
.as_ref()
.map(|contacts| {
let mut sorted = contacts.iter().collect::<Vec<_>>();
sorted.sort_by_key(|contact| contact.priority);
sorted
})
.unwrap_or_default()
}
}