253 lines
7.7 KiB
Rust
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()
|
|
}
|
|
} |