feat(privacy): Dodanie preferencji kanałów kontaktu

Użytkownicy mogą teraz wskazać preferowane kanały komunikacji:
- Email, telefon, wiadomości w portalu (toggle)
- Dodatkowa notatka (np. najlepsze godziny kontaktu)

Migracja: 031_add_contact_preferences.sql

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-28 21:06:15 +01:00
parent c09a622463
commit e2ceba4310
4 changed files with 87 additions and 0 deletions

7
app.py
View File

@ -4103,6 +4103,13 @@ def settings_privacy():
# Update privacy settings
user.privacy_show_phone = request.form.get('show_phone') == 'on'
user.privacy_show_email = request.form.get('show_email') == 'on'
# Update contact preferences
user.contact_prefer_email = request.form.get('prefer_email') == 'on'
user.contact_prefer_phone = request.form.get('prefer_phone') == 'on'
user.contact_prefer_portal = request.form.get('prefer_portal') == 'on'
user.contact_note = request.form.get('contact_note', '').strip() or None
db.commit()
logger.info(f"Privacy settings updated for user: {user.email}")

View File

@ -219,6 +219,12 @@ class User(Base, UserMixin):
privacy_show_phone = Column(Boolean, default=True) # If FALSE, phone hidden from other users
privacy_show_email = Column(Boolean, default=True) # If FALSE, email hidden from other users
# Contact preferences
contact_prefer_email = Column(Boolean, default=True) # User prefers email contact
contact_prefer_phone = Column(Boolean, default=True) # User prefers phone contact
contact_prefer_portal = Column(Boolean, default=True) # User prefers portal messages
contact_note = Column(Text, nullable=True) # Additional note (e.g. best hours)
# Relationships
conversations = relationship('AIChatConversation', back_populates='user', cascade='all, delete-orphan')
forum_topics = relationship('ForumTopic', back_populates='author', cascade='all, delete-orphan', primaryjoin='User.id == ForumTopic.author_id')

View File

@ -0,0 +1,18 @@
-- Migration: Add contact channel preferences to users
-- Date: 2026-01-28
-- Description: Users can choose preferred contact methods and visibility
-- Add contact preference columns
ALTER TABLE users ADD COLUMN IF NOT EXISTS contact_prefer_email BOOLEAN DEFAULT TRUE;
ALTER TABLE users ADD COLUMN IF NOT EXISTS contact_prefer_phone BOOLEAN DEFAULT TRUE;
ALTER TABLE users ADD COLUMN IF NOT EXISTS contact_prefer_portal BOOLEAN DEFAULT TRUE;
ALTER TABLE users ADD COLUMN IF NOT EXISTS contact_note TEXT;
-- Comments
COMMENT ON COLUMN users.contact_prefer_email IS 'User prefers contact via email';
COMMENT ON COLUMN users.contact_prefer_phone IS 'User prefers contact via phone';
COMMENT ON COLUMN users.contact_prefer_portal IS 'User prefers contact via portal messages';
COMMENT ON COLUMN users.contact_note IS 'Additional note about contact preferences (e.g. best hours)';
-- Grant permissions
GRANT SELECT, UPDATE ON users TO nordabiz_app;

View File

@ -227,6 +227,62 @@
</div>
</div>
<div class="settings-card">
<h2>Preferowane kanały kontaktu</h2>
<p style="color: var(--text-secondary); font-size: var(--font-size-sm); margin-bottom: var(--spacing-md);">
Zaznacz, jakimi kanałami preferujesz otrzymywać kontakt od innych członków.
</p>
<div class="setting-item">
<div class="setting-info">
<div class="setting-label">Email</div>
<div class="setting-description">
Preferuję kontakt przez email
</div>
</div>
<label class="toggle-switch">
<input type="checkbox" name="prefer_email" {% if user.contact_prefer_email != False %}checked{% endif %}>
<span class="toggle-slider"></span>
</label>
</div>
<div class="setting-item">
<div class="setting-info">
<div class="setting-label">Telefon</div>
<div class="setting-description">
Preferuję kontakt telefoniczny
</div>
</div>
<label class="toggle-switch">
<input type="checkbox" name="prefer_phone" {% if user.contact_prefer_phone != False %}checked{% endif %}>
<span class="toggle-slider"></span>
</label>
</div>
<div class="setting-item">
<div class="setting-info">
<div class="setting-label">Wiadomości w portalu</div>
<div class="setting-description">
Preferuję kontakt przez system wiadomości w portalu
</div>
</div>
<label class="toggle-switch">
<input type="checkbox" name="prefer_portal" {% if user.contact_prefer_portal != False %}checked{% endif %}>
<span class="toggle-slider"></span>
</label>
</div>
<div class="setting-item" style="flex-direction: column; align-items: stretch;">
<div class="setting-info" style="margin-bottom: var(--spacing-sm);">
<div class="setting-label">Dodatkowe informacje</div>
<div class="setting-description">
Np. najlepsze godziny kontaktu, preferowany dzień tygodnia
</div>
</div>
<textarea name="contact_note" rows="2" style="width: 100%; padding: var(--spacing-sm); border: 1px solid var(--border-color); border-radius: var(--radius-md); font-size: var(--font-size-sm); resize: vertical;">{{ user.contact_note or '' }}</textarea>
</div>
</div>
<button type="submit" class="btn btn-primary btn-save">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" style="margin-right: 6px;">
<path d="M5 13l4 4L19 7"/>