Add network map UX and theme support.

Introduce network map view/components with filtering and positioning, expand contacts/map backend fields and migrations, and add a persistent light/dark theme toggle with graph label color updates for readability.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-28 13:24:48 +03:00
co-authored by Cursor
parent 81ba6cd076
commit b668ee8507
49 changed files with 4679 additions and 129 deletions
@@ -0,0 +1,68 @@
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contacts', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='contact',
name='importance',
field=models.PositiveSmallIntegerField(
default=3,
validators=[
django.core.validators.MinValueValidator(1),
django.core.validators.MaxValueValidator(5),
],
verbose_name='Важность (15)',
),
),
migrations.AddField(
model_name='contact',
name='life_sphere',
field=models.CharField(
choices=[
('work', 'Работа'),
('study', 'Учёба'),
('hobby', 'Хобби'),
('family', 'Семья'),
('health', 'Здоровье'),
('other', 'Другое'),
],
default='other',
max_length=32,
verbose_name='Сфера жизни',
),
),
migrations.AddField(
model_name='contact',
name='network_circle',
field=models.CharField(
choices=[
('support', 'Круг поддержки'),
('productivity', 'Круг продуктивности'),
('development', 'Круг развития'),
],
default='productivity',
max_length=32,
verbose_name='Круг сети',
),
),
migrations.AddField(
model_name='relation',
name='interaction_intensity',
field=models.CharField(
choices=[
('intense', 'Интенсивные контакты'),
('sparse', 'Редкие контакты'),
],
default='intense',
max_length=32,
verbose_name='Интенсивность общения',
),
),
]
@@ -0,0 +1,29 @@
from django.db import migrations, models
def set_map_true_for_existing(apps, schema_editor):
Contact = apps.get_model('contacts', 'Contact')
Contact.objects.all().update(include_on_network_map=True)
def noop_reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('contacts', '0002_contact_importance_contact_life_sphere_and_more'),
]
operations = [
migrations.AddField(
model_name='contact',
name='include_on_network_map',
field=models.BooleanField(
default=False,
verbose_name='Показывать на карте сети',
),
),
migrations.RunPython(set_map_true_for_existing, noop_reverse),
]
@@ -0,0 +1,21 @@
from django.db import migrations
def set_map_false_for_all(apps, schema_editor):
Contact = apps.get_model('contacts', 'Contact')
Contact.objects.all().update(include_on_network_map=False)
def noop_reverse(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('contacts', '0003_contact_include_on_network_map'),
]
operations = [
migrations.RunPython(set_map_false_for_all, noop_reverse),
]
@@ -0,0 +1,27 @@
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contacts', '0004_contact_map_default_off'),
]
operations = [
migrations.AddField(
model_name='contact',
name='map_angle',
field=models.FloatField(blank=True, null=True, verbose_name='Угол позиции на карте'),
),
migrations.AddField(
model_name='contact',
name='map_radius_ratio',
field=models.FloatField(
blank=True,
null=True,
validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)],
verbose_name='Радиус позиции на карте (доля)',
),
),
]