mirror of https://github.com/snachodog/mybuddy.git
commit
22536f88cd
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
- [Contributions](#contributions)
|
- [Contributions](#contributions)
|
||||||
- [Pull request process](#pull-request-process)
|
- [Pull request process](#pull-request-process)
|
||||||
|
- [Translation](#translation)
|
||||||
- [Development](#development)
|
- [Development](#development)
|
||||||
- [Installation](#installation)
|
- [Installation](#installation)
|
||||||
- [Gulp Commands](#gulp-commands)
|
- [Gulp Commands](#gulp-commands)
|
||||||
|
@ -34,6 +35,33 @@ Gitter.
|
||||||
New pull requests will be reviewed by project maintainers as soon as possible
|
New pull requests will be reviewed by project maintainers as soon as possible
|
||||||
and we will do our best to provide feedback and support potential contributors.
|
and we will do our best to provide feedback and support potential contributors.
|
||||||
|
|
||||||
|
### Translation
|
||||||
|
|
||||||
|
Baby Buddy has support for translation/localization to any language. A general
|
||||||
|
translation process will look something like this:
|
||||||
|
|
||||||
|
1. Set up a development environment (see [Development](#development) below).
|
||||||
|
1. Run `gulp makemessages -l xx` where `xx` is a specific locale code (e.g. "fr"
|
||||||
|
for French or "es" for Spanish). This create a new translation file at
|
||||||
|
`locale/xx/LC_MESSAGES/django.po`, or update one if it exits.
|
||||||
|
1. Open the created/updated `django.po` file and update the header template with
|
||||||
|
license and contact info.
|
||||||
|
1. Start translating! Each translatable string will have a `msgid` value with
|
||||||
|
the string in English and a corresponding (empty) `msgstr` value where a
|
||||||
|
translated string can be filled in.
|
||||||
|
1. Once all strings have been translated, run `gulp compilemessages -l xx` to
|
||||||
|
compile an optimized translation file (`locale/xx/LC_MESSAGES/django.mo`).
|
||||||
|
1. To expose the new translation as a user setting, add the locale code to the
|
||||||
|
`LANGUAGES` array in the base settings file (`babybuddy/settings/base.py`).
|
||||||
|
1. Run the development server, log in, and update the user language to test the
|
||||||
|
newly translated strings.
|
||||||
|
|
||||||
|
Once the translation is complete, commit the new files and changes to a fork and
|
||||||
|
[create a pull request](#pull-request-process) for review.
|
||||||
|
|
||||||
|
For more information on the Django translation process, see Django's
|
||||||
|
documentation section: [Translation](https://docs.djangoproject.com/en/dev/topics/i18n/translation/).
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
@ -92,10 +120,12 @@ in the [`babybuddy/management/commands`](babybuddy/management/commands) folder.
|
||||||
- [`gulp build`](#build)
|
- [`gulp build`](#build)
|
||||||
- [`gulp clean`](#clean)
|
- [`gulp clean`](#clean)
|
||||||
- [`gulp collectstatic`](#collectstatic)
|
- [`gulp collectstatic`](#collectstatic)
|
||||||
|
- [`gulp compilemessages`](#compilemessages)
|
||||||
- [`gulp coverage`](#coverage)
|
- [`gulp coverage`](#coverage)
|
||||||
- [`gulp extras`](#extras)
|
- [`gulp extras`](#extras)
|
||||||
- [`gulp fake`](#fake)
|
- [`gulp fake`](#fake)
|
||||||
- [`gulp lint`](#lint)
|
- [`gulp lint`](#lint)
|
||||||
|
- [`gulp makemessages`](#makemessages)
|
||||||
- [`gulp makemigrations`](#makemigrations)
|
- [`gulp makemigrations`](#makemigrations)
|
||||||
- [`gulp migrate`](#migrate)
|
- [`gulp migrate`](#migrate)
|
||||||
- [`gulp reset`](#reset)
|
- [`gulp reset`](#reset)
|
||||||
|
@ -126,6 +156,11 @@ the `babybuddy/static` folder, so generally `gulp build` should be run before
|
||||||
this command for production deployments. Gulp also passes along
|
this command for production deployments. Gulp also passes along
|
||||||
non-overlapping arguments for this command, e.g. `--no-input`.
|
non-overlapping arguments for this command, e.g. `--no-input`.
|
||||||
|
|
||||||
|
#### `compilemessages`
|
||||||
|
|
||||||
|
Executes Django's `compilemessages` management task. See [django-admin compilemessages](https://docs.djangoproject.com/en/dev/ref/django-admin/#compilemessages)
|
||||||
|
for more details about other options and functionality of this command.
|
||||||
|
|
||||||
#### `coverage`
|
#### `coverage`
|
||||||
|
|
||||||
Create a test coverage report. See [`.coveragerc`](.coveragerc) for default
|
Create a test coverage report. See [`.coveragerc`](.coveragerc) for default
|
||||||
|
@ -147,6 +182,14 @@ children and seven days of data for each.
|
||||||
|
|
||||||
Executes Python and SASS linting for all relevant source files.
|
Executes Python and SASS linting for all relevant source files.
|
||||||
|
|
||||||
|
#### `makemessages`
|
||||||
|
|
||||||
|
Executes Django's `makemessages` management task. See [django-admin makemessages](https://docs.djangoproject.com/en/dev/ref/django-admin/#makemessages)
|
||||||
|
for more details about other options and functionality of this command. When
|
||||||
|
working on a single translation, the `-l` flag is useful to make message for
|
||||||
|
only that language, e.g. `gulp makemessages -l fr` to make only a French
|
||||||
|
language translation file.
|
||||||
|
|
||||||
#### `makemigrations`
|
#### `makemigrations`
|
||||||
|
|
||||||
Executes Django's `makemigrations` management task. Gulp also passes along
|
Executes Django's `makemigrations` management task. Gulp also passes along
|
||||||
|
|
|
@ -2,16 +2,18 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from babybuddy import models
|
from babybuddy import models
|
||||||
|
|
||||||
|
|
||||||
class SettingsInline(admin.StackedInline):
|
class SettingsInline(admin.StackedInline):
|
||||||
model = models.Settings
|
model = models.Settings
|
||||||
verbose_name_plural = 'Settings'
|
verbose_name = _('Settings')
|
||||||
|
verbose_name_plural = _('Settings')
|
||||||
can_delete = False
|
can_delete = False
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('Dashboard', {
|
(_('Dashboard'), {
|
||||||
'fields': ('dashboard_refresh_rate',)
|
'fields': ('dashboard_refresh_rate',)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
|
@ -41,4 +41,4 @@ class UserPasswordForm(PasswordChangeForm):
|
||||||
class UserSettingsForm(forms.ModelForm):
|
class UserSettingsForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Settings
|
model = Settings
|
||||||
fields = ['dashboard_refresh_rate']
|
fields = ['dashboard_refresh_rate', 'language']
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2 on 2019-04-17 04:02
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('babybuddy', '0003_add_refresh_help_text'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='settings',
|
||||||
|
name='language',
|
||||||
|
field=models.CharField(choices=[], default='en', max_length=255, verbose_name='Language'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,9 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.signals import user_logged_in
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.timezone import timedelta
|
from django.utils.timezone import timedelta
|
||||||
|
from django.utils.text import format_lazy
|
||||||
|
from django.utils import translation
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
|
@ -11,26 +16,32 @@ from rest_framework.authtoken.models import Token
|
||||||
class Settings(models.Model):
|
class Settings(models.Model):
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
dashboard_refresh_rate = models.DurationField(
|
dashboard_refresh_rate = models.DurationField(
|
||||||
verbose_name='Refresh rate',
|
verbose_name=_('Refresh rate'),
|
||||||
help_text='This setting will only be used when a browser does not '
|
help_text=_('This setting will only be used when a browser does not '
|
||||||
'support refresh on focus.',
|
'support refresh on focus.'),
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
default=timedelta(minutes=1),
|
default=timedelta(minutes=1),
|
||||||
choices=[
|
choices=[
|
||||||
(None, 'disabled'),
|
(None, _('disabled')),
|
||||||
(timedelta(minutes=1), '1 min.'),
|
(timedelta(minutes=1), _('1 min.')),
|
||||||
(timedelta(minutes=2), '2 min.'),
|
(timedelta(minutes=2), _('2 min.')),
|
||||||
(timedelta(minutes=3), '3 min.'),
|
(timedelta(minutes=3), _('3 min.')),
|
||||||
(timedelta(minutes=4), '4 min.'),
|
(timedelta(minutes=4), _('4 min.')),
|
||||||
(timedelta(minutes=5), '5 min.'),
|
(timedelta(minutes=5), _('5 min.')),
|
||||||
(timedelta(minutes=10), '10 min.'),
|
(timedelta(minutes=10), _('10 min.')),
|
||||||
(timedelta(minutes=15), '15 min.'),
|
(timedelta(minutes=15), _('15 min.')),
|
||||||
(timedelta(minutes=30), '30 min.'),
|
(timedelta(minutes=30), _('30 min.')),
|
||||||
])
|
])
|
||||||
|
language = models.CharField(
|
||||||
|
choices=settings.LANGUAGES,
|
||||||
|
default=settings.LANGUAGE_CODE,
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_('Language')
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{}\'s Settings'.format(self.user)
|
return str(format_lazy(_('{user}\'s Settings'), user=self.user))
|
||||||
|
|
||||||
def api_key(self, reset=False):
|
def api_key(self, reset=False):
|
||||||
"""
|
"""
|
||||||
|
@ -63,3 +74,9 @@ def create_user_settings(sender, instance, created, **kwargs):
|
||||||
@receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
def save_user_settings(sender, instance, **kwargs):
|
def save_user_settings(sender, instance, **kwargs):
|
||||||
instance.settings.save()
|
instance.settings.save()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(user_logged_in)
|
||||||
|
def user_logged_in_callback(sender, request, user, **kwargs):
|
||||||
|
translation.activate(user.settings.language)
|
||||||
|
request.session[translation.LANGUAGE_SESSION_KEY] = user.settings.language
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
from dotenv import load_dotenv, find_dotenv
|
from dotenv import load_dotenv, find_dotenv
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
@ -53,10 +54,9 @@ INSTALLED_APPS = [
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
|
||||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||||
|
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
@ -110,7 +110,7 @@ LOGOUT_REDIRECT_URL = '/login/'
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.11/topics/i18n/
|
# https://docs.djangoproject.com/en/1.11/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en'
|
||||||
|
|
||||||
TIME_ZONE = os.environ.get('TIME_ZONE', 'Etc/UTC')
|
TIME_ZONE = os.environ.get('TIME_ZONE', 'Etc/UTC')
|
||||||
|
|
||||||
|
@ -120,6 +120,15 @@ USE_L10N = True
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
LOCALE_PATHS = [
|
||||||
|
os.path.join(BASE_DIR, "locale"),
|
||||||
|
]
|
||||||
|
|
||||||
|
LANGUAGES = [
|
||||||
|
('en', _('English')),
|
||||||
|
('fr', _('French')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/1.11/howto/static-files/
|
# https://docs.djangoproject.com/en/1.11/howto/static-files/
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}403 Permission Denied{% endblock %}
|
{% block title %}403 {% trans "Permission Denied" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Permission Denied</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Permission Denied" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
You do not have permission to access this resource. Contact a site
|
{% blocktrans %}You do not have permission to access this resource.
|
||||||
administrator for assistance.
|
Contact a site administrator for assistance.{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% load static %}
|
{% load i18n static %}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
{% block breadcrumb_nav %}
|
{% block breadcrumb_nav %}
|
||||||
<nav aria-label="breadcrumb" role="navigation">
|
<nav aria-label="breadcrumb" role="navigation">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
<li class="breadcrumb-item"><a href="/">{% trans "Home" %}</a></li>
|
||||||
{% block breadcrumbs %}{% endblock %}
|
{% block breadcrumbs %}{% endblock %}
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
<form id="filter_form" role="form" action="" method="get" class="collapse{% if request.GET.filtered %} show{% endif %}">
|
<form id="filter_form" role="form" action="" method="get" class="collapse{% if request.GET.filtered %} show{% endif %}">
|
||||||
<div class="form-group form-row">
|
<div class="form-group form-row">
|
||||||
|
@ -15,8 +15,8 @@
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="col-xs-12 col-sm-auto mt-3 mt-sm-0">
|
<div class="col-xs-12 col-sm-auto mt-3 mt-sm-0">
|
||||||
<button type="submit" class="btn btn-sm btn-primary mr-2">Filter</button>
|
<button type="submit" class="btn btn-sm btn-primary mr-2">{% trans "Filter" %}</button>
|
||||||
<a href="{{ request.path }}" class="btn btn-sm btn-error">Reset</a>
|
<a href="{{ request.path }}" class="btn btn-sm btn-error">{% trans "Reset" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" name="filtered" value="1"/>
|
<input type="hidden" name="filtered" value="1"/>
|
||||||
|
@ -29,6 +29,6 @@
|
||||||
role="button"
|
role="button"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-controls="filter_form">
|
aria-controls="filter_form">
|
||||||
Filters
|
{% trans "Filters" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form role="form" method="post" enctype="multipart/form-data">
|
<form role="form" method="post" enctype="multipart/form-data">
|
||||||
|
@ -8,6 +8,6 @@
|
||||||
{% include 'babybuddy/form_field.html' %}
|
{% include 'babybuddy/form_field.html' %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block messages %}
|
{% block messages %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
|
@ -13,12 +15,12 @@
|
||||||
{% if form.non_field_errors %}
|
{% if form.non_field_errors %}
|
||||||
{% for error in form.non_field_errors %}
|
{% for error in form.non_field_errors %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
<strong>Error:</strong> {{ error }}
|
{% blocktrans %}<strong>Error:</strong> {{ error }}{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif form.errors %}
|
{% elif form.errors %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
<strong>Error:</strong> Some fields have errors. See below for details.
|
{% blocktrans %}<strong>Error:</strong> Some fields have errors. See below for details. {% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends 'babybuddy/base.html' %}
|
{% extends 'babybuddy/base.html' %}
|
||||||
{% load babybuddy_tags static timers %}
|
{% load babybuddy_tags i18n static timers %}
|
||||||
|
|
||||||
{% block nav %}
|
{% block nav %}
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||||
|
@ -23,32 +23,38 @@
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="nav-quick-add-link">
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="nav-quick-add-link">
|
||||||
{% if perms.core.add_diaperchange %}
|
{% if perms.core.add_diaperchange %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:diaperchange-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:diaperchange-add' %}">
|
||||||
<i class="icon icon-diaperchange" aria-hidden="true"></i> Diaper Change
|
<i class="icon icon-diaperchange" aria-hidden="true"></i>
|
||||||
|
{% trans "Diaper Change" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_feeding %}
|
{% if perms.core.add_feeding %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:feeding-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:feeding-add' %}">
|
||||||
<i class="icon icon-feeding" aria-hidden="true"></i> Feeding
|
<i class="icon icon-feeding" aria-hidden="true"></i>
|
||||||
|
{% trans "Feeding" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_note %}
|
{% if perms.core.add_note %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:note-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:note-add' %}">
|
||||||
<i class="icon icon-note" aria-hidden="true"></i> Note
|
<i class="icon icon-note" aria-hidden="true"></i>
|
||||||
|
{% trans "Note" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_sleep %}
|
{% if perms.core.add_sleep %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:sleep-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:sleep-add' %}">
|
||||||
<i class="icon icon-sleep" aria-hidden="true"></i> Sleep
|
<i class="icon icon-sleep" aria-hidden="true"></i>
|
||||||
|
{% trans "Sleep" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_tummytime %}
|
{% if perms.core.add_tummytime %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:tummytime-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:tummytime-add' %}">
|
||||||
<i class="icon icon-tummytime" aria-hidden="true"></i> Tummy Time
|
<i class="icon icon-tummytime" aria-hidden="true"></i>
|
||||||
|
{% trans "Tummy Time" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_weight %}
|
{% if perms.core.add_weight %}
|
||||||
<a class="dropdown-item p-2" href="{% url 'core:weight-add' %}">
|
<a class="dropdown-item p-2" href="{% url 'core:weight-add' %}">
|
||||||
<i class="icon icon-weight" aria-hidden="true"></i> Weight
|
<i class="icon icon-weight" aria-hidden="true"></i>
|
||||||
|
{% trans "Weight" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -66,7 +72,8 @@
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<li class="nav-item{% if request.path == '/' %} active{% endif %}">
|
<li class="nav-item{% if request.path == '/' %} active{% endif %}">
|
||||||
<a class="nav-link" href="{% url 'dashboard:dashboard' %}">
|
<a class="nav-link" href="{% url 'dashboard:dashboard' %}">
|
||||||
<i class="icon icon-dashboard" aria-hidden="true"></i> Dashboard
|
<i class="icon icon-dashboard" aria-hidden="true"></i>
|
||||||
|
{% trans "Dashboard" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
@ -76,40 +83,51 @@
|
||||||
href="#"
|
href="#"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"><i class="icon icon-child" aria-hidden="true"></i> Children</a>
|
aria-expanded="false"><i class="icon icon-child" aria-hidden="true"></i>
|
||||||
|
{% trans "Children" %}
|
||||||
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="nav-children-menu-link">
|
<div class="dropdown-menu" aria-labelledby="nav-children-menu-link">
|
||||||
|
|
||||||
{% if perms.core.view_child %}
|
{% if perms.core.view_child %}
|
||||||
<a class="dropdown-item{% if request.path == '/children/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/children/' %} active{% endif %}"
|
||||||
href="{% url 'core:child-list' %}">
|
href="{% url 'core:child-list' %}">
|
||||||
<i class="icon icon-child" aria-hidden="true"></i> Children
|
<i class="icon icon-child" aria-hidden="true"></i>
|
||||||
|
{% trans "Children" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_child %}
|
{% if perms.core.add_child %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/children/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/children/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:child-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Child</a>
|
href="{% url 'core:child-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Child" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.view_note %}
|
{% if perms.core.view_note %}
|
||||||
<a class="dropdown-item{% if request.path == '/notes/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/notes/' %} active{% endif %}"
|
||||||
href="{% url 'core:note-list' %}">
|
href="{% url 'core:note-list' %}">
|
||||||
<i class="icon icon-note" aria-hidden="true"></i> Notes
|
<i class="icon icon-note" aria-hidden="true"></i>
|
||||||
|
{% trans "Notes" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_note %}
|
{% if perms.core.add_note %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/notes/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/notes/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:note-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Note</a>
|
href="{% url 'core:note-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Note" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.view_weight %}
|
{% if perms.core.view_weight %}
|
||||||
<a class="dropdown-item{% if request.path == '/weight/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/weight/' %} active{% endif %}"
|
||||||
href="{% url 'core:weight-list' %}">
|
href="{% url 'core:weight-list' %}">
|
||||||
<i class="icon icon-weight" aria-hidden="true"></i> Weight
|
<i class="icon icon-weight" aria-hidden="true"></i>
|
||||||
|
{% trans "Weight" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_weight %}
|
{% if perms.core.add_weight %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/weight/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/weight/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:weight-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Weight entry</a>
|
href="{% url 'core:weight-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Weight entry" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,43 +139,61 @@
|
||||||
href="#"
|
href="#"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"><i class="icon icon-activities" aria-hidden="true"></i> Activities</a>
|
aria-expanded="false"><i class="icon icon-activities" aria-hidden="true"></i>
|
||||||
|
{% trans "Activities" %}
|
||||||
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="nav-activity-menu-link">
|
<div class="dropdown-menu" aria-labelledby="nav-activity-menu-link">
|
||||||
|
|
||||||
{% if perms.core.view_diaperchange %}
|
{% if perms.core.view_diaperchange %}
|
||||||
<a class="dropdown-item{% if request.path == '/changes/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/changes/' %} active{% endif %}"
|
||||||
href="{% url 'core:diaperchange-list' %}"><i class="icon icon-diaperchange" aria-hidden="true"></i> Changes</a>
|
href="{% url 'core:diaperchange-list' %}"><i class="icon icon-diaperchange" aria-hidden="true"></i>
|
||||||
|
{% trans "Changes" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_diaperchange %}
|
{% if perms.core.add_diaperchange %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/changes/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/changes/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:diaperchange-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Change</a>
|
href="{% url 'core:diaperchange-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Change" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.view_feeding %}
|
{% if perms.core.view_feeding %}
|
||||||
<a class="dropdown-item{% if request.path == '/feedings/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/feedings/' %} active{% endif %}"
|
||||||
href="{% url 'core:feeding-list' %}"><i class="icon icon-feeding" aria-hidden="true"></i> Feedings</a>
|
href="{% url 'core:feeding-list' %}"><i class="icon icon-feeding" aria-hidden="true"></i>
|
||||||
|
{% trans "Feedings" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_diaperchange %}
|
{% if perms.core.add_diaperchange %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/feedings/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/feedings/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:feeding-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Feeding</a>
|
href="{% url 'core:feeding-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Feeding" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.view_sleep %}
|
{% if perms.core.view_sleep %}
|
||||||
<a class="dropdown-item{% if request.path == '/sleep/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/sleep/' %} active{% endif %}"
|
||||||
href="{% url 'core:sleep-list' %}"><i class="icon icon-sleep" aria-hidden="true"></i> Sleep</a>
|
href="{% url 'core:sleep-list' %}"><i class="icon icon-sleep" aria-hidden="true"></i>
|
||||||
|
{% trans "Sleep" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_sleep %}
|
{% if perms.core.add_sleep %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/sleep/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/sleep/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:sleep-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Sleep entry</a>
|
href="{% url 'core:sleep-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Sleep entry" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.view_tummytime %}
|
{% if perms.core.view_tummytime %}
|
||||||
<a class="dropdown-item{% if request.path == '/tummy-time/' %} active{% endif %}"
|
<a class="dropdown-item{% if request.path == '/tummy-time/' %} active{% endif %}"
|
||||||
href="{% url 'core:tummytime-list' %}"><i class="icon icon-tummytime" aria-hidden="true"></i> Tummy Time</a>
|
href="{% url 'core:tummytime-list' %}"><i class="icon icon-tummytime" aria-hidden="true"></i>
|
||||||
|
{% trans "Tummy Time" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.add_tummytime %}
|
{% if perms.core.add_tummytime %}
|
||||||
<a class="dropdown-item pl-5{% if request.path == '/tummy-time/add/' %} active{% endif %}"
|
<a class="dropdown-item pl-5{% if request.path == '/tummy-time/add/' %} active{% endif %}"
|
||||||
href="{% url 'core:tummytime-add' %}"><i class="icon icon-add" aria-hidden="true"></i> Tummy Time entry</a>
|
href="{% url 'core:tummytime-add' %}"><i class="icon icon-add" aria-hidden="true"></i>
|
||||||
|
{% trans "Tummy Time entry" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -179,29 +215,29 @@
|
||||||
aria-expanded="false"><i class="icon icon-user" aria-hidden="true"></i> {{ request.user }}
|
aria-expanded="false"><i class="icon icon-user" aria-hidden="true"></i> {{ request.user }}
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="nav-user-menu-link">
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="nav-user-menu-link">
|
||||||
<h6 class="dropdown-header">User</h6>
|
<h6 class="dropdown-header">{% trans "User" %}</h6>
|
||||||
<a href="{% url 'babybuddy:user-settings' %}" class="dropdown-item">Settings</a>
|
<a href="{% url 'babybuddy:user-settings' %}" class="dropdown-item">{% trans "Settings" %}</a>
|
||||||
<a href="{% url 'babybuddy:user-password' %}" class="dropdown-item">Password</a>
|
<a href="{% url 'babybuddy:user-password' %}" class="dropdown-item">{% trans "Password" %}</a>
|
||||||
<a href="{% url 'babybuddy:logout' %}" class="dropdown-item">Logout</a>
|
<a href="{% url 'babybuddy:logout' %}" class="dropdown-item">{% trans "Logout" %}</a>
|
||||||
<h6 class="dropdown-header">Site</h6>
|
<h6 class="dropdown-header">{% trans "Site" %}</h6>
|
||||||
<a href="{% url 'api:api-root' %}"
|
<a href="{% url 'api:api-root' %}"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
target="_blank">API Browser</a>
|
target="_blank">{% trans "API Browser" %}</a>
|
||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
<a href="{% url 'babybuddy:user-list' %}" class="dropdown-item">Users</a>
|
<a href="{% url 'babybuddy:user-list' %}" class="dropdown-item">{% trans "Users" %}</a>
|
||||||
<a href="{% url 'admin:index' %}"
|
<a href="{% url 'admin:index' %}"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
target="_blank">Backend Admin</a>
|
target="_blank">{% trans "Backend Admin" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h6 class="dropdown-header">Support</h6>
|
<h6 class="dropdown-header">{% trans "Support" %}</h6>
|
||||||
<a href="https://github.com/cdubz/babybuddy"
|
<a href="https://github.com/cdubz/babybuddy"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<i class="icon icon-source" aria-hidden="true"></i> Source Code</a>
|
<i class="icon icon-source" aria-hidden="true"></i> {% trans "Source Code" %}</a>
|
||||||
<a href="https://gitter.im/babybuddy/Lobby"
|
<a href="https://gitter.im/babybuddy/Lobby"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<i class="icon icon-chat" aria-hidden="true"></i> Chat / Support</a>
|
<i class="icon icon-chat" aria-hidden="true"></i> {% trans "Chat / Support" %}</a>
|
||||||
<h6 class="dropdown-header">v{% version_string %}</h6>
|
<h6 class="dropdown-header">v{% version_string %}</h6>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{% load babybuddy_tags %}
|
{% load i18n babybuddy_tags %}
|
||||||
|
|
||||||
{% if is_paginated %}
|
{% if is_paginated %}
|
||||||
<nav aria-label="Page navigation">
|
<nav aria-label="Page navigation">
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="{% relative_url 'page' page_obj.previous_page_number %}" aria-label="Previous">
|
<a class="page-link" href="{% relative_url 'page' page_obj.previous_page_number %}" aria-label="Previous">
|
||||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">{% trans "Previous" %}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="{% relative_url 'page' page_obj.next_page_number %}" aria-label="Next">
|
<a class="page-link" href="{% relative_url 'page' page_obj.next_page_number %}" aria-label="Next">
|
||||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">{% trans "Next" %}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete User{% endblock %}
|
{% block title %}{% trans "Delete User" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'babybuddy:user-list' %}">Users</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'babybuddy:user-list' %}">{% trans "Users" %}</a></li>
|
||||||
<li class="breadcrumb-item">{{ object }}</li>
|
<li class="breadcrumb-item">{{ object }}</li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="Delete" class="btn btn-danger" />
|
||||||
<a href="{% url 'babybuddy:user-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'babybuddy:user-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,28 +1,29 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
{{ object }}
|
{{ object }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Create User
|
{% trans "Create User" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'babybuddy:user-list' %}">Users</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'babybuddy:user-list' %}">{% trans "Users" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Create User</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Create User" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Create User</h1>
|
<h1>{% trans "Create User" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load bootstrap widget_tweaks %}
|
{% load bootstrap i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Users{% endblock %}
|
{% block title %}{% trans "Users" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Users</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Users" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -14,13 +14,13 @@
|
||||||
<table class="table table-striped table-hover user-list">
|
<table class="table table-striped table-hover user-list">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>User</th>
|
<th>{% trans "User" %}</th>
|
||||||
<th>First Name</th>
|
<th>{% trans "First Name" %}</th>
|
||||||
<th>Last Name</th>
|
<th>{% trans "Last Name" %}</th>
|
||||||
<th>Email</th>
|
<th>{% trans "Email" %}</th>
|
||||||
<th>Staff</th>
|
<th>{% trans "Staff" %}</th>
|
||||||
<th>Active</th>
|
<th>{% trans "Active" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="4">No users found.</th>
|
<th colspan="4">{% trans "No users found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
|
|
||||||
{% if perms.admin.add_user %}
|
{% if perms.admin.add_user %}
|
||||||
<a href="{% url 'babybuddy:user-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'babybuddy:user-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-add" aria-hidden="true"></i> Create User
|
<i class="icon icon-add" aria-hidden="true"></i> {% trans "Create User" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Change Password{% endblock %}
|
{% block title %}{% trans "Change Password" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item">User</li>
|
<li class="breadcrumb-item">{% trans "User" %}</li>
|
||||||
<li class="breadcrumb-item active">Change Password</li>
|
<li class="breadcrumb-item active">{% trans "Change Password" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Change Password</h1>
|
<h1>{% trans "Change Password" %}</h1>
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}User Settings{% endblock %}
|
{% block title %}{% trans "User Settings" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item">User</li>
|
<li class="breadcrumb-item">{% trans "User" %}</li>
|
||||||
<li class="breadcrumb-item active">Settings</li>
|
<li class="breadcrumb-item active">{% trans "Settings" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>User Settings</h1>
|
<h1>{% trans "User Settings" %}</h1>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if form.non_field_errors %}
|
{% if form.non_field_errors %}
|
||||||
{% for error in form.non_field_errors %}
|
{% for error in form.non_field_errors %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
<strong>Error:</strong> {{ error }}
|
{% blocktrans %}<strong>Error:</strong> {{ error }}{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% elif form.errors %}
|
{% elif form.errors %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
<strong>Error:</strong> Some fields have errors. See below for details.
|
{% blocktrans %}<strong>Error:</strong> Some fields have errors. See below for details.{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>User Profile</legend>
|
<legend>{% trans "User Profile" %}</legend>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
{% with form_user.first_name as field %}
|
{% with form_user.first_name as field %}
|
||||||
{% include 'babybuddy/form_field.html' %}
|
{% include 'babybuddy/form_field.html' %}
|
||||||
|
@ -41,9 +41,14 @@
|
||||||
{% include 'babybuddy/form_field.html' %}
|
{% include 'babybuddy/form_field.html' %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
{% with form_settings.language as field %}
|
||||||
|
{% include 'babybuddy/form_field.html' %}
|
||||||
|
{% endwith %}
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Dashboard</legend>
|
<legend>{% trans "Dashboard" %}</legend>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
{% with form_settings.dashboard_refresh_rate as field %}
|
{% with form_settings.dashboard_refresh_rate as field %}
|
||||||
{% include 'babybuddy/form_field.html' %}
|
{% include 'babybuddy/form_field.html' %}
|
||||||
|
@ -51,16 +56,16 @@
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>API</legend>
|
<legend>{% trans "API" %}</legend>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="id_email" class="col-sm-2 col-form-label">Key</label>
|
<label for="id_email" class="col-sm-2 col-form-label">{% trans "Key" %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<samp>{{ user.settings.api_key }}</samp>
|
<samp>{{ user.settings.api_key }}</samp>
|
||||||
<a class="btn btn-xs btn-danger" href="{% url 'babybuddy:user-reset-api-key' %}">Regenerate</a>
|
<a class="btn btn-xs btn-danger" href="{% url 'babybuddy:user-reset-api-key' %}">{% trans "Regenerate" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Welcome!{% endblock %}
|
{% block title %}{% trans "Welcome!" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Welcome!</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Welcome!" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="jumbotron">
|
<div class="jumbotron">
|
||||||
<h1 class="display-3">Welcome to Baby Buddy!</h1>
|
<h1 class="display-3">{% trans "Welcome to Baby Buddy!" %}</h1>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Learn about and predict baby's needs without (<em>as much</em>)
|
{% blocktrans %}Learn about and predict baby's needs without
|
||||||
guess work by using Baby Buddy to track —
|
(<em>as much</em>) guess work by using Baby Buddy to track —{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
<hr class="my-4">
|
<hr class="my-4">
|
||||||
<div class="card-deck">
|
<div class="card-deck">
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<i class="icon icon-2x icon-diaperchange" aria-hidden="true"></i>
|
<i class="icon icon-2x icon-diaperchange" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="card-title text-center">Diaper Changes</h3>
|
<h3 class="card-title text-center">{% trans "Diaper Changes" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card card-feeding">
|
<div class="card card-feeding">
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<i class="icon icon-2x icon-feeding" aria-hidden="true"></i>
|
<i class="icon icon-2x icon-feeding" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="card-title text-center">Feedings</h3>
|
<h3 class="card-title text-center">{% trans "Feedings" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card card-sleep">
|
<div class="card card-sleep">
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<i class="icon icon-2x icon-sleep" aria-hidden="true"></i>
|
<i class="icon icon-2x icon-sleep" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="card-title text-center">Sleep</h3>
|
<h3 class="card-title text-center">{% trans "Sleep" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card card-tummytime">
|
<div class="card card-tummytime">
|
||||||
|
@ -45,23 +45,23 @@
|
||||||
<i class="icon icon-2x icon-tummytime" aria-hidden="true"></i>
|
<i class="icon icon-2x icon-tummytime" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="card-title text-center">Tummy Time</h3>
|
<h3 class="card-title text-center">{% trans "Tummy Time" %}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="my-4">
|
<hr class="my-4">
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
As the amount of entries grows, Baby Buddy will help
|
{% blocktrans %}As the amount of entries grows, Baby Buddy will help
|
||||||
parents and caregivers to identify small patterns in baby's habits
|
parents and caregivers to identify small patterns in baby's habits
|
||||||
using the dashboard and graphs. Baby Buddy is mobile-friendly and
|
using the dashboard and graphs. Baby Buddy is mobile-friendly and
|
||||||
uses a dark theme to help weary moms and dads with 2AM feedings and
|
uses a dark theme to help weary moms and dads with 2AM feedings and
|
||||||
changings. To get started, just click the button below to add your
|
changings. To get started, just click the button below to add your
|
||||||
first (or second, third, etc.) child!
|
first (or second, third, etc.) child!{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
{% if perms.core.add_child %}
|
{% if perms.core.add_child %}
|
||||||
<a href="{% url 'core:child-add' %}" class="btn btn-lg btn-success">
|
<a href="{% url 'core:child-add' %}" class="btn btn-lg btn-success">
|
||||||
<i class="icon icon-child" aria-hidden="true"></i> Add a Child
|
<i class="icon icon-child" aria-hidden="true"></i> {% trans "Add a Child" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "registration/base.html" %}
|
{% extends "registration/base.html" %}
|
||||||
{% load static widget_tweaks %}
|
{% load i18n static widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Login{% endblock %}
|
{% block title %}Login{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -29,12 +29,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary w-100 fade-in" type="submit" name="login">
|
<button class="btn btn-primary w-100 fade-in" type="submit" name="login">
|
||||||
Login
|
{% trans "Login" %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="bg-faded text-center px-4 py-3 rounded-bottom">
|
<div class="bg-faded text-center px-4 py-3 rounded-bottom">
|
||||||
<a href="{% url 'babybuddy:password_reset' %}" name="reset">
|
<a href="{% url 'babybuddy:password_reset' %}" name="reset">
|
||||||
Forgot your password?</a>
|
{% trans "Forgot your password?" %}</a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,11 +1,12 @@
|
||||||
{% extends "registration/base.html" %}
|
{% extends "registration/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Password Reset Successfully!{% endblock %}
|
{% block title %}{% trans "Password Reset Successfully!" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="text-center mb-0">
|
<div class="text-center mb-0">
|
||||||
<p>Your password has been set. You may go ahead and log in now.</p>
|
<p>{% trans "Your password has been set. You may go ahead and log in now." %}</p>
|
||||||
<p class="mb-0"><a href="{{ login_url }}">Log in</a></p>
|
<p class="mb-0"><a href="{{ login_url }}">{% trans "Log in" %}</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "registration/base.html" %}
|
{% extends "registration/base.html" %}
|
||||||
{% load static widget_tweaks %}
|
{% load i18n static widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Password Reset{% endblock %}
|
{% block title %}{% trans "Password Reset" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
{% if form.errors %}
|
{% if form.errors %}
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
<p class="mb-0"><strong>Oh snap!</strong> The two passwords
|
{% blocktrans %}<p class="mb-0"><strong>Oh snap!</strong> The
|
||||||
did not match. Please try again.</p>
|
two passwords did not match. Please try again.</p>{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<p class="mb-0">Enter your new password in each field below.</p>
|
<p class="mb-0">{% trans "Enter your new password in each field below." %}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="sr-only" for="password1-input-group">
|
<label class="sr-only" for="password1-input-group">
|
||||||
|
@ -28,7 +28,6 @@
|
||||||
{% render_field form.new_password1 name='new_password1' class+='form-control' id='password1-input-group' %}
|
{% render_field form.new_password1 name='new_password1' class+='form-control' id='password1-input-group' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<label class="sr-only" for="password2-input-group">
|
<label class="sr-only" for="password2-input-group">
|
||||||
{{ form.new_password2.label }}
|
{{ form.new_password2.label }}
|
||||||
</label>
|
</label>
|
||||||
|
@ -40,7 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary w-100 fade-in" type="submit" name="reset">
|
<button class="btn btn-primary w-100 fade-in" type="submit" name="reset">
|
||||||
Reset Password
|
{% trans "Reset Password" %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
{% extends "registration/base.html" %}
|
{% extends "registration/base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Reset Email Sent{% endblock %}
|
{% block title %}{% trans "Reset Email Sent" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="text-center mb-0">
|
<div class="text-center mb-0">
|
||||||
<p>We've emailed you instructions for setting your
|
{% blocktrans %}<p>We've emailed you instructions for setting your
|
||||||
password, if an account exists with the email you entered. You
|
password, if an account exists with the email you entered. You
|
||||||
should receive them shortly.</p>
|
should receive them shortly.</p>
|
||||||
<p class="mb-0">If you don't receive an email, please make sure you've
|
<p class="mb-0">If you don't receive an email, please make sure you've
|
||||||
entered the address you registered with, and check your spam
|
entered the address you registered with, and check your spam
|
||||||
folder.</p>
|
folder.</p>{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,13 +1,13 @@
|
||||||
{% extends "registration/base.html" %}
|
{% extends "registration/base.html" %}
|
||||||
{% load static widget_tweaks %}
|
{% load i18n static widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Forgot Password{% endblock %}
|
{% block title %}{% trans "Forgot Password" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="text-center mb-4">
|
<div class="text-center mb-4">
|
||||||
<p class="mb-0">Enter your account email address in the form below. If
|
{% blocktrans %}<p class="mb-0">Enter your account email address in the
|
||||||
the address is valid, you will receive instructions for resetting your
|
form below. If the address is valid, you will receive instructions for
|
||||||
password.</p>
|
resetting your password.</p>{% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary w-100 fade-in" type="submit" name="reset">
|
<button class="btn btn-primary w-100 fade-in" type="submit" name="reset">
|
||||||
Reset Password
|
{% trans "Reset Password" %}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,14 @@ class FormsTestCase(TestCase):
|
||||||
cls.user = User.objects.create_user(
|
cls.user = User.objects.create_user(
|
||||||
is_superuser=True, **cls.credentials)
|
is_superuser=True, **cls.credentials)
|
||||||
|
|
||||||
|
cls.settings_template = {
|
||||||
|
'first_name': 'User',
|
||||||
|
'last_name': 'Name',
|
||||||
|
'email': 'user@user.user',
|
||||||
|
'dashboard_refresh_rate': '',
|
||||||
|
'language': 'en'
|
||||||
|
}
|
||||||
|
|
||||||
def test_change_password(self):
|
def test_change_password(self):
|
||||||
self.c.login(**self.credentials)
|
self.c.login(**self.credentials)
|
||||||
|
|
||||||
|
@ -85,18 +93,28 @@ class FormsTestCase(TestCase):
|
||||||
def test_user_settings(self):
|
def test_user_settings(self):
|
||||||
self.c.login(**self.credentials)
|
self.c.login(**self.credentials)
|
||||||
|
|
||||||
params = {
|
params = self.settings_template.copy()
|
||||||
'first_name': 'User',
|
params['first_name'] = 'New First Name'
|
||||||
'last_name': 'Name',
|
|
||||||
'email': 'user@user.user',
|
|
||||||
'dashboard_refresh_rate': ''
|
|
||||||
}
|
|
||||||
|
|
||||||
page = self.c.post('/user/settings/', params)
|
page = self.c.post('/user/settings/', params, follow=True)
|
||||||
self.assertEqual(page.status_code, 302)
|
self.assertEqual(page.status_code, 200)
|
||||||
|
self.assertContains(page, 'New First Name')
|
||||||
|
|
||||||
|
def test_user_settings_invalid(self):
|
||||||
|
self.c.login(**self.credentials)
|
||||||
|
|
||||||
|
params = self.settings_template.copy()
|
||||||
|
params['email'] = 'Not an email address'
|
||||||
|
|
||||||
params = {'email': 'Not an email address'}
|
|
||||||
page = self.c.post('/user/settings/', params)
|
page = self.c.post('/user/settings/', params)
|
||||||
self.assertEqual(page.status_code, 200)
|
self.assertEqual(page.status_code, 200)
|
||||||
self.assertFormError(page, 'user_form', 'email',
|
self.assertFormError(page, 'user_form', 'email',
|
||||||
'Enter a valid email address.')
|
'Enter a valid email address.')
|
||||||
|
|
||||||
|
def test_user_settings_language(self):
|
||||||
|
self.c.login(**self.credentials)
|
||||||
|
|
||||||
|
params = self.settings_template.copy()
|
||||||
|
params['language'] = 'fr'
|
||||||
|
page = self.c.post('/user/settings/', data=params, follow=True)
|
||||||
|
self.assertContains(page, 'Paramètres Utilisateur')
|
||||||
|
|
|
@ -17,10 +17,13 @@ class SettingsTestCase(TestCase):
|
||||||
}
|
}
|
||||||
user = User.objects.create_user(is_superuser=True, **credentials)
|
user = User.objects.create_user(is_superuser=True, **credentials)
|
||||||
self.assertIsInstance(user.settings, Settings)
|
self.assertIsInstance(user.settings, Settings)
|
||||||
self.assertEqual(str(user.settings), 'Test\'s Settings')
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
user.settings.dashboard_refresh_rate_milliseconds, 60000)
|
user.settings.dashboard_refresh_rate_milliseconds, 60000)
|
||||||
|
|
||||||
user.settings.dashboard_refresh_rate = None
|
user.settings.dashboard_refresh_rate = None
|
||||||
user.save()
|
user.save()
|
||||||
self.assertIsNone(user.settings.dashboard_refresh_rate_milliseconds)
|
self.assertIsNone(user.settings.dashboard_refresh_rate_milliseconds)
|
||||||
|
|
||||||
|
user.settings.language = 'fr'
|
||||||
|
user.save()
|
||||||
|
self.assertEqual(user.settings.language, 'fr')
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.test import Client as HttpClient
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.management import call_command
|
||||||
|
|
||||||
|
from faker import Factory
|
||||||
|
|
||||||
|
|
||||||
|
class TranslationTestCase(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(TranslationTestCase, cls).setUpClass()
|
||||||
|
fake = Factory.create()
|
||||||
|
call_command('migrate', verbosity=0)
|
||||||
|
|
||||||
|
cls.c = HttpClient()
|
||||||
|
|
||||||
|
fake_user = fake.simple_profile()
|
||||||
|
cls.credentials = {
|
||||||
|
'username': fake_user['username'],
|
||||||
|
'password': fake.password()
|
||||||
|
}
|
||||||
|
cls.user = User.objects.create_user(
|
||||||
|
is_superuser=True, **cls.credentials)
|
||||||
|
|
||||||
|
cls.params_template = {
|
||||||
|
'first_name': 'User',
|
||||||
|
'last_name': 'Name',
|
||||||
|
'email': 'user@user.user',
|
||||||
|
'dashboard_refresh_rate': '',
|
||||||
|
'language': 'en'
|
||||||
|
}
|
||||||
|
|
||||||
|
cls.c.login(**cls.credentials)
|
||||||
|
|
||||||
|
def test_translation_fr(self):
|
||||||
|
params = self.params_template.copy()
|
||||||
|
params['language'] = 'fr'
|
||||||
|
|
||||||
|
page = self.c.post('/user/settings/', data=params, follow=True)
|
||||||
|
self.assertContains(page, 'Paramètres Utilisateur')
|
||||||
|
|
||||||
|
page = self.c.get('/welcome/')
|
||||||
|
self.assertContains(page, 'Bienvenue à Baby Buddy!')
|
|
@ -53,6 +53,7 @@ urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('', include('api.urls', namespace='api')),
|
path('', include('api.urls', namespace='api')),
|
||||||
path('', include((app_patterns, 'babybuddy'), namespace='babybuddy')),
|
path('', include((app_patterns, 'babybuddy'), namespace='babybuddy')),
|
||||||
|
path('user/lang', include('django.conf.urls.i18n')),
|
||||||
path('', include('core.urls', namespace='core')),
|
path('', include('core.urls', namespace='core')),
|
||||||
path('', include('dashboard.urls', namespace='dashboard')),
|
path('', include('dashboard.urls', namespace='dashboard')),
|
||||||
path('', include('reports.urls', namespace='reports')),
|
path('', include('reports.urls', namespace='reports')),
|
||||||
|
|
|
@ -7,9 +7,12 @@ from django.contrib.auth.models import User
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
|
from django.utils.text import format_lazy
|
||||||
|
from django.utils.translation import gettext as _, gettext_lazy
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.views.generic.base import TemplateView, RedirectView
|
from django.views.generic.base import TemplateView, RedirectView
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||||
|
from django.views.i18n import set_language
|
||||||
|
|
||||||
from django_filters.views import FilterView
|
from django_filters.views import FilterView
|
||||||
|
|
||||||
|
@ -50,7 +53,7 @@ class UserAdd(StaffOnlyMixin, PermissionRequired403Mixin, SuccessMessageMixin,
|
||||||
permission_required = ('admin.add_user',)
|
permission_required = ('admin.add_user',)
|
||||||
form_class = forms.UserAddForm
|
form_class = forms.UserAddForm
|
||||||
success_url = reverse_lazy('babybuddy:user-list')
|
success_url = reverse_lazy('babybuddy:user-list')
|
||||||
success_message = 'User %(username)s added!'
|
success_message = gettext_lazy('User %(username)s added!')
|
||||||
|
|
||||||
|
|
||||||
class UserUpdate(StaffOnlyMixin, PermissionRequired403Mixin,
|
class UserUpdate(StaffOnlyMixin, PermissionRequired403Mixin,
|
||||||
|
@ -60,7 +63,7 @@ class UserUpdate(StaffOnlyMixin, PermissionRequired403Mixin,
|
||||||
permission_required = ('admin.change_user',)
|
permission_required = ('admin.change_user',)
|
||||||
form_class = forms.UserUpdateForm
|
form_class = forms.UserUpdateForm
|
||||||
success_url = reverse_lazy('babybuddy:user-list')
|
success_url = reverse_lazy('babybuddy:user-list')
|
||||||
success_message = 'User %(username)s updated.'
|
success_message = gettext_lazy('User %(username)s updated.')
|
||||||
|
|
||||||
|
|
||||||
class UserDelete(StaffOnlyMixin, PermissionRequired403Mixin,
|
class UserDelete(StaffOnlyMixin, PermissionRequired403Mixin,
|
||||||
|
@ -71,7 +74,9 @@ class UserDelete(StaffOnlyMixin, PermissionRequired403Mixin,
|
||||||
success_url = reverse_lazy('babybuddy:user-list')
|
success_url = reverse_lazy('babybuddy:user-list')
|
||||||
|
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
success_message = 'User {} deleted.'.format(self.get_object())
|
success_message = format_lazy(gettext_lazy(
|
||||||
|
'User {user} deleted.'), user=self.get_object()
|
||||||
|
)
|
||||||
messages.success(request, success_message)
|
messages.success(request, success_message)
|
||||||
return super(UserDelete, self).delete(request, *args, **kwargs)
|
return super(UserDelete, self).delete(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -93,7 +98,7 @@ class UserPassword(LoginRequiredMixin, View):
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
user = form.save()
|
user = form.save()
|
||||||
update_session_auth_hash(request, user)
|
update_session_auth_hash(request, user)
|
||||||
messages.success(request, 'Password updated.')
|
messages.success(request, _('Password updated.'))
|
||||||
return render(request, self.template_name, {'form': form})
|
return render(request, self.template_name, {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,7 +108,7 @@ class UserResetAPIKey(LoginRequiredMixin, View):
|
||||||
"""
|
"""
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
request.user.settings.api_key(reset=True)
|
request.user.settings.api_key(reset=True)
|
||||||
messages.success(request, 'User API key regenerated.')
|
messages.success(request, _('User API key regenerated.'))
|
||||||
return redirect('babybuddy:user-settings')
|
return redirect('babybuddy:user-settings')
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,7 +140,8 @@ class UserSettings(LoginRequiredMixin, View):
|
||||||
user_settings = form_settings.save(commit=False)
|
user_settings = form_settings.save(commit=False)
|
||||||
user.settings = user_settings
|
user.settings = user_settings
|
||||||
user.save()
|
user.save()
|
||||||
messages.success(request, 'Settings saved!')
|
set_language(request)
|
||||||
|
messages.success(request, _('Settings saved!'))
|
||||||
return redirect('babybuddy:user-settings')
|
return redirect('babybuddy:user-settings')
|
||||||
return render(request, self.template_name, {
|
return render(request, self.template_name, {
|
||||||
'user_form': form_user,
|
'user_form': form_user,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils import timezone
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from core import models
|
from core import models
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ class ChildDeleteForm(forms.ModelForm):
|
||||||
confirm_name = self.cleaned_data['confirm_name']
|
confirm_name = self.cleaned_data['confirm_name']
|
||||||
if confirm_name != str(self.instance):
|
if confirm_name != str(self.instance):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
'Name does not match child name.', code='confirm_mismatch')
|
_('Name does not match child name.'), code='confirm_mismatch')
|
||||||
return confirm_name
|
return confirm_name
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
# Generated by Django 2.2 on 2019-04-17 03:48
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0004_child_picture'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='child',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['last_name', 'first_name'], 'verbose_name': 'Child', 'verbose_name_plural': 'Children'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='diaperchange',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-time'], 'verbose_name': 'Diaper Change', 'verbose_name_plural': 'Diaper Changes'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='feeding',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-start'], 'verbose_name': 'Feeding', 'verbose_name_plural': 'Feedings'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='note',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-time'], 'verbose_name': 'Note', 'verbose_name_plural': 'Notes'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='sleep',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-start'], 'verbose_name': 'Sleep', 'verbose_name_plural': 'Sleep'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='timer',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-active', '-start', '-end'], 'verbose_name': 'Timer', 'verbose_name_plural': 'Timers'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='tummytime',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-start'], 'verbose_name': 'Tummy Time', 'verbose_name_plural': 'Tummy Time'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='weight',
|
||||||
|
options={'default_permissions': ('view', 'add', 'change', 'delete'), 'ordering': ['-date'], 'verbose_name': 'Weight', 'verbose_name_plural': 'Weight'},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='child',
|
||||||
|
name='birth_date',
|
||||||
|
field=models.DateField(verbose_name='Birth date'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='child',
|
||||||
|
name='first_name',
|
||||||
|
field=models.CharField(max_length=255, verbose_name='First name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='child',
|
||||||
|
name='last_name',
|
||||||
|
field=models.CharField(max_length=255, verbose_name='Last name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='child',
|
||||||
|
name='picture',
|
||||||
|
field=models.ImageField(blank=True, null=True, upload_to='child/picture/', verbose_name='Picture'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='child',
|
||||||
|
name='slug',
|
||||||
|
field=models.SlugField(editable=False, max_length=100, unique=True, verbose_name='Slug'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='diaperchange',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='diaper_change', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='diaperchange',
|
||||||
|
name='color',
|
||||||
|
field=models.CharField(blank=True, choices=[('black', 'Black'), ('brown', 'Brown'), ('green', 'Green'), ('yellow', 'Yellow')], max_length=255, verbose_name='Color'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='diaperchange',
|
||||||
|
name='solid',
|
||||||
|
field=models.BooleanField(verbose_name='Solid'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='diaperchange',
|
||||||
|
name='time',
|
||||||
|
field=models.DateTimeField(verbose_name='Time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='diaperchange',
|
||||||
|
name='wet',
|
||||||
|
field=models.BooleanField(verbose_name='Wet'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='amount',
|
||||||
|
field=models.FloatField(blank=True, null=True, verbose_name='Amount'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='feeding', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='duration',
|
||||||
|
field=models.DurationField(editable=False, null=True, verbose_name='Duration'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='end',
|
||||||
|
field=models.DateTimeField(verbose_name='End time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='method',
|
||||||
|
field=models.CharField(choices=[('bottle', 'Bottle'), ('left breast', 'Left breast'), ('right breast', 'Right breast')], max_length=255, verbose_name='Method'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='start',
|
||||||
|
field=models.DateTimeField(verbose_name='Start time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='feeding',
|
||||||
|
name='type',
|
||||||
|
field=models.CharField(choices=[('breast milk', 'Breast milk'), ('formula', 'Formula')], max_length=255, verbose_name='Type'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='note',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='note', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='note',
|
||||||
|
name='note',
|
||||||
|
field=models.TextField(verbose_name='Note'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='note',
|
||||||
|
name='time',
|
||||||
|
field=models.DateTimeField(auto_now=True, verbose_name='Time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='sleep',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sleep', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='sleep',
|
||||||
|
name='duration',
|
||||||
|
field=models.DurationField(editable=False, null=True, verbose_name='Duration'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='sleep',
|
||||||
|
name='end',
|
||||||
|
field=models.DateTimeField(verbose_name='End time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='sleep',
|
||||||
|
name='start',
|
||||||
|
field=models.DateTimeField(verbose_name='Start time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='active',
|
||||||
|
field=models.BooleanField(default=True, editable=False, verbose_name='Active'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='duration',
|
||||||
|
field=models.DurationField(editable=False, null=True, verbose_name='Duration'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='end',
|
||||||
|
field=models.DateTimeField(blank=True, editable=False, null=True, verbose_name='End time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='start',
|
||||||
|
field=models.DateTimeField(default=django.utils.timezone.now, verbose_name='Start time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='timer',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='timers', to=settings.AUTH_USER_MODEL, verbose_name='User'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tummytime',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tummy_time', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tummytime',
|
||||||
|
name='duration',
|
||||||
|
field=models.DurationField(editable=False, null=True, verbose_name='Duration'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tummytime',
|
||||||
|
name='end',
|
||||||
|
field=models.DateTimeField(verbose_name='End time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tummytime',
|
||||||
|
name='milestone',
|
||||||
|
field=models.CharField(blank=True, max_length=255, verbose_name='Milestone'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='tummytime',
|
||||||
|
name='start',
|
||||||
|
field=models.DateTimeField(verbose_name='Start time'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='weight',
|
||||||
|
name='child',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='weight', to='core.Child', verbose_name='Child'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='weight',
|
||||||
|
name='date',
|
||||||
|
field=models.DateField(verbose_name='Date'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='weight',
|
||||||
|
name='weight',
|
||||||
|
field=models.FloatField(verbose_name='Weight'),
|
||||||
|
),
|
||||||
|
]
|
269
core/models.py
269
core/models.py
|
@ -6,6 +6,8 @@ from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.text import format_lazy
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
def validate_date(date, field_name):
|
def validate_date(date, field_name):
|
||||||
|
@ -17,7 +19,7 @@ def validate_date(date, field_name):
|
||||||
"""
|
"""
|
||||||
if date and date > timezone.localdate():
|
if date and date > timezone.localdate():
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{field_name: 'Date can not be in the future.'},
|
{field_name: _('Date can not be in the future.')},
|
||||||
code='date_invalid')
|
code='date_invalid')
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,10 +33,10 @@ def validate_duration(model, max_duration=timedelta(hours=24)):
|
||||||
if model.start and model.end:
|
if model.start and model.end:
|
||||||
if model.start > model.end:
|
if model.start > model.end:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
'Start time must come before end time.',
|
_('Start time must come before end time.'),
|
||||||
code='end_before_start')
|
code='end_before_start')
|
||||||
if model.end - model.start > max_duration:
|
if model.end - model.start > max_duration:
|
||||||
raise ValidationError('Duration too long.', code='max_duration')
|
raise ValidationError(_('Duration too long.'), code='max_duration')
|
||||||
|
|
||||||
|
|
||||||
def validate_unique_period(queryset, model):
|
def validate_unique_period(queryset, model):
|
||||||
|
@ -50,7 +52,7 @@ def validate_unique_period(queryset, model):
|
||||||
if model.start and model.end:
|
if model.start and model.end:
|
||||||
if queryset.filter(start__lte=model.end, end__gte=model.start):
|
if queryset.filter(start__lte=model.end, end__gte=model.start):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
'Another entry intersects the specified time period.',
|
_('Another entry intersects the specified time period.'),
|
||||||
code='period_intersection')
|
code='period_intersection')
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,20 +65,30 @@ def validate_time(time, field_name):
|
||||||
"""
|
"""
|
||||||
if time and time > timezone.localtime():
|
if time and time > timezone.localtime():
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{field_name: 'Date/time can not be in the future.'},
|
{field_name: _('Date/time can not be in the future.')},
|
||||||
code='time_invalid')
|
code='time_invalid')
|
||||||
|
|
||||||
|
|
||||||
class Child(models.Model):
|
class Child(models.Model):
|
||||||
model_name = 'child'
|
model_name = 'child'
|
||||||
first_name = models.CharField(max_length=255)
|
first_name = models.CharField(max_length=255, verbose_name=_('First name'))
|
||||||
last_name = models.CharField(max_length=255)
|
last_name = models.CharField(max_length=255, verbose_name=_('Last name'))
|
||||||
birth_date = models.DateField(blank=False, null=False)
|
birth_date = models.DateField(
|
||||||
slug = models.SlugField(max_length=100, unique=True, editable=False)
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('Birth date')
|
||||||
|
)
|
||||||
|
slug = models.SlugField(
|
||||||
|
editable=False,
|
||||||
|
max_length=100,
|
||||||
|
unique=True,
|
||||||
|
verbose_name=_('Slug')
|
||||||
|
)
|
||||||
picture = models.ImageField(
|
picture = models.ImageField(
|
||||||
upload_to='child/picture/',
|
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True,
|
||||||
|
upload_to='child/picture/',
|
||||||
|
verbose_name=_('Picture')
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
@ -84,7 +96,8 @@ class Child(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['last_name', 'first_name']
|
ordering = ['last_name', 'first_name']
|
||||||
verbose_name_plural = 'Children'
|
verbose_name = _('Child')
|
||||||
|
verbose_name_plural = _('Children')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} {}'.format(self.first_name, self.last_name)
|
return '{} {}'.format(self.first_name, self.last_name)
|
||||||
|
@ -103,25 +116,40 @@ class Child(models.Model):
|
||||||
class DiaperChange(models.Model):
|
class DiaperChange(models.Model):
|
||||||
model_name = 'diaperchange'
|
model_name = 'diaperchange'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='diaper_change', on_delete=models.CASCADE)
|
'Child',
|
||||||
time = models.DateTimeField(blank=False, null=False)
|
on_delete=models.CASCADE,
|
||||||
wet = models.BooleanField()
|
related_name='diaper_change',
|
||||||
solid = models.BooleanField()
|
verbose_name=_('Child')
|
||||||
color = models.CharField(max_length=255, blank=True, choices=[
|
)
|
||||||
('black', 'Black'),
|
time = models.DateTimeField(
|
||||||
('brown', 'Brown'),
|
blank=False,
|
||||||
('green', 'Green'),
|
null=False,
|
||||||
('yellow', 'Yellow'),
|
verbose_name=_('Time')
|
||||||
])
|
)
|
||||||
|
wet = models.BooleanField(verbose_name=_('Wet'))
|
||||||
|
solid = models.BooleanField(verbose_name=_('Solid'))
|
||||||
|
color = models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
('black', _('Black')),
|
||||||
|
('brown', _('Brown')),
|
||||||
|
('green', _('Green')),
|
||||||
|
('yellow', _('Yellow')),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_('Color')
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-time']
|
ordering = ['-time']
|
||||||
|
verbose_name = _('Diaper Change')
|
||||||
|
verbose_name_plural = _('Diaper Changes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Diaper Change'
|
return str(_('Diaper Change'))
|
||||||
|
|
||||||
def attributes(self):
|
def attributes(self):
|
||||||
attributes = []
|
attributes = []
|
||||||
|
@ -139,35 +167,58 @@ class DiaperChange(models.Model):
|
||||||
# One or both of Wet and Solid is required.
|
# One or both of Wet and Solid is required.
|
||||||
if not self.wet and not self.solid:
|
if not self.wet and not self.solid:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
'Wet and/or solid is required.', code='wet_or_solid')
|
_('Wet and/or solid is required.'), code='wet_or_solid')
|
||||||
|
|
||||||
|
|
||||||
class Feeding(models.Model):
|
class Feeding(models.Model):
|
||||||
model_name = 'feeding'
|
model_name = 'feeding'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='feeding', on_delete=models.CASCADE)
|
'Child',
|
||||||
start = models.DateTimeField(blank=False, null=False)
|
on_delete=models.CASCADE,
|
||||||
end = models.DateTimeField(blank=False, null=False)
|
related_name='feeding',
|
||||||
duration = models.DurationField(null=True, editable=False)
|
verbose_name=_('Child')
|
||||||
type = models.CharField(max_length=255, choices=[
|
)
|
||||||
('breast milk', 'Breast milk'),
|
start = models.DateTimeField(
|
||||||
('formula', 'Formula'),
|
blank=False,
|
||||||
])
|
null=False,
|
||||||
method = models.CharField(max_length=255, choices=[
|
verbose_name=_('Start time')
|
||||||
('bottle', 'Bottle'),
|
)
|
||||||
('left breast', 'Left breast'),
|
end = models.DateTimeField(
|
||||||
('right breast', 'Right breast'),
|
blank=False,
|
||||||
])
|
null=False,
|
||||||
amount = models.FloatField(blank=True, null=True)
|
verbose_name=_('End time')
|
||||||
|
)
|
||||||
|
duration = models.DurationField(
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('Duration')
|
||||||
|
)
|
||||||
|
type = models.CharField(
|
||||||
|
choices=[('breast milk', _('Breast milk')), ('formula', _('Formula'))],
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_('Type')
|
||||||
|
)
|
||||||
|
method = models.CharField(
|
||||||
|
choices=[
|
||||||
|
('bottle', _('Bottle')),
|
||||||
|
('left breast', _('Left breast')),
|
||||||
|
('right breast', _('Right breast')),
|
||||||
|
],
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_('Method')
|
||||||
|
)
|
||||||
|
amount = models.FloatField(blank=True, null=True, verbose_name=_('Amount'))
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-start']
|
ordering = ['-start']
|
||||||
|
verbose_name = _('Feeding')
|
||||||
|
verbose_name_plural = _('Feedings')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Feeding'
|
return str(_('Feeding'))
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.start and self.end:
|
if self.start and self.end:
|
||||||
|
@ -184,25 +235,31 @@ class Feeding(models.Model):
|
||||||
if self.type == 'formula'and self.method != 'bottle':
|
if self.type == 'formula'and self.method != 'bottle':
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{'method':
|
{'method':
|
||||||
'Only "Bottle" method is allowed with "Formula" type.'},
|
_('Only "Bottle" method is allowed with "Formula" type.')},
|
||||||
code='bottle_formula_mismatch')
|
code='bottle_formula_mismatch')
|
||||||
|
|
||||||
|
|
||||||
class Note(models.Model):
|
class Note(models.Model):
|
||||||
model_name = 'note'
|
model_name = 'note'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='note', on_delete=models.CASCADE)
|
'Child',
|
||||||
note = models.TextField()
|
on_delete=models.CASCADE,
|
||||||
time = models.DateTimeField(auto_now=True)
|
related_name='note',
|
||||||
|
verbose_name=_('Child')
|
||||||
|
)
|
||||||
|
note = models.TextField(verbose_name=_('Note'))
|
||||||
|
time = models.DateTimeField(auto_now=True, verbose_name=_('Time'))
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-time']
|
ordering = ['-time']
|
||||||
|
verbose_name = _('Note')
|
||||||
|
verbose_name_plural = _('Notes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Note'
|
return str(_('Note'))
|
||||||
|
|
||||||
|
|
||||||
class NapsManager(models.Manager):
|
class NapsManager(models.Manager):
|
||||||
|
@ -214,10 +271,26 @@ class NapsManager(models.Manager):
|
||||||
class Sleep(models.Model):
|
class Sleep(models.Model):
|
||||||
model_name = 'sleep'
|
model_name = 'sleep'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='sleep', on_delete=models.CASCADE)
|
'Child',
|
||||||
start = models.DateTimeField(blank=False, null=False)
|
on_delete=models.CASCADE,
|
||||||
end = models.DateTimeField(blank=False, null=False)
|
related_name='sleep',
|
||||||
duration = models.DurationField(null=True, editable=False)
|
verbose_name=_('Child')
|
||||||
|
)
|
||||||
|
start = models.DateTimeField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('Start time')
|
||||||
|
)
|
||||||
|
end = models.DateTimeField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('End time')
|
||||||
|
)
|
||||||
|
duration = models.DurationField(
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('Duration')
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
naps = NapsManager()
|
naps = NapsManager()
|
||||||
|
@ -225,10 +298,11 @@ class Sleep(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-start']
|
ordering = ['-start']
|
||||||
verbose_name_plural = 'Sleep'
|
verbose_name = _('Sleep')
|
||||||
|
verbose_name_plural = _('Sleep')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Sleep'
|
return str(_('Sleep'))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nap(self):
|
def nap(self):
|
||||||
|
@ -253,26 +327,50 @@ class Sleep(models.Model):
|
||||||
|
|
||||||
class Timer(models.Model):
|
class Timer(models.Model):
|
||||||
model_name = 'timer'
|
model_name = 'timer'
|
||||||
name = models.CharField(max_length=255, null=True, blank=True)
|
name = models.CharField(
|
||||||
|
blank=True,
|
||||||
|
max_length=255,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('Name')
|
||||||
|
)
|
||||||
start = models.DateTimeField(
|
start = models.DateTimeField(
|
||||||
default=timezone.now,
|
default=timezone.now,
|
||||||
blank=False,
|
blank=False,
|
||||||
verbose_name='Start Time'
|
verbose_name=_('Start time')
|
||||||
|
)
|
||||||
|
end = models.DateTimeField(
|
||||||
|
blank=True,
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('End time')
|
||||||
|
)
|
||||||
|
duration = models.DurationField(
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('Duration')
|
||||||
|
)
|
||||||
|
active = models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
editable=False,
|
||||||
|
verbose_name=_('Active')
|
||||||
)
|
)
|
||||||
end = models.DateTimeField(blank=True, null=True, editable=False)
|
|
||||||
duration = models.DurationField(null=True, editable=False)
|
|
||||||
active = models.BooleanField(default=True, editable=False)
|
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
'auth.User', related_name='timers', on_delete=models.CASCADE)
|
'auth.User',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='timers',
|
||||||
|
verbose_name=_('User')
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-active', '-start', '-end']
|
ordering = ['-active', '-start', '-end']
|
||||||
|
verbose_name = _('Timer')
|
||||||
|
verbose_name_plural = _('Timers')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name or 'Timer #{}'.format(self.id)
|
return self.name or str(format_lazy(_('Timer #{id}'), id=self.id))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_db(cls, db, field_names, values):
|
def from_db(cls, db, field_names, values):
|
||||||
|
@ -315,20 +413,42 @@ class Timer(models.Model):
|
||||||
class TummyTime(models.Model):
|
class TummyTime(models.Model):
|
||||||
model_name = 'tummytime'
|
model_name = 'tummytime'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='tummy_time', on_delete=models.CASCADE)
|
'Child',
|
||||||
start = models.DateTimeField(blank=False, null=False)
|
on_delete=models.CASCADE,
|
||||||
end = models.DateTimeField(blank=False, null=False)
|
related_name='tummy_time',
|
||||||
duration = models.DurationField(null=True, editable=False)
|
verbose_name=_('Child')
|
||||||
milestone = models.CharField(max_length=255, blank=True)
|
)
|
||||||
|
start = models.DateTimeField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('Start time')
|
||||||
|
)
|
||||||
|
end = models.DateTimeField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('End time')
|
||||||
|
)
|
||||||
|
duration = models.DurationField(
|
||||||
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
verbose_name=_('Duration')
|
||||||
|
)
|
||||||
|
milestone = models.CharField(
|
||||||
|
blank=True,
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_('Milestone')
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-start']
|
ordering = ['-start']
|
||||||
|
verbose_name = _('Tummy Time')
|
||||||
|
verbose_name_plural = _('Tummy Time')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Tummy Time'
|
return str(_('Tummy Time'))
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.start and self.end:
|
if self.start and self.end:
|
||||||
|
@ -346,19 +466,32 @@ class TummyTime(models.Model):
|
||||||
class Weight(models.Model):
|
class Weight(models.Model):
|
||||||
model_name = 'weight'
|
model_name = 'weight'
|
||||||
child = models.ForeignKey(
|
child = models.ForeignKey(
|
||||||
'Child', related_name='weight', on_delete=models.CASCADE)
|
'Child',
|
||||||
weight = models.FloatField(blank=False, null=False)
|
on_delete=models.CASCADE,
|
||||||
date = models.DateField(blank=False, null=False)
|
related_name='weight',
|
||||||
|
verbose_name=_('Child')
|
||||||
|
)
|
||||||
|
weight = models.FloatField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('Weight')
|
||||||
|
)
|
||||||
|
date = models.DateField(
|
||||||
|
blank=False,
|
||||||
|
null=False,
|
||||||
|
verbose_name=_('Date')
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
default_permissions = ('view', 'add', 'change', 'delete')
|
default_permissions = ('view', 'add', 'change', 'delete')
|
||||||
ordering = ['-date']
|
ordering = ['-date']
|
||||||
verbose_name_plural = 'Weight'
|
verbose_name = _('Weight')
|
||||||
|
verbose_name_plural = _('Weight')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'Weight'
|
return str(_('Weight'))
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
validate_date(self.date, 'date')
|
validate_date(self.date, 'date')
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Child{% endblock %}
|
{% block title %}{% trans "Delete a Child" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">Children</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">{% trans "Children" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{ form.confirm_name.id_for_label }}">To confirm this action. Type the full name of the child below.</label>
|
<label for="{{ form.confirm_name.id_for_label }}">
|
||||||
|
{% trans "To confirm this action. Type the full name of the child below." %}
|
||||||
|
</label>
|
||||||
{% if form.confirm_name.errors %}
|
{% if form.confirm_name.errors %}
|
||||||
{{ form.confirm_name|add_class:"form-control is-invalid" }}
|
{{ form.confirm_name|add_class:"form-control is-invalid" }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -24,7 +26,7 @@
|
||||||
<div class="invalid-feedback">{{ form.confirm_name.errors.0 }}</div>
|
<div class="invalid-feedback">{{ form.confirm_name.errors.0 }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:child-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:child-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,10 +1,10 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load static thumbnail %}
|
{% load i18n static thumbnail %}
|
||||||
|
|
||||||
{% block title %}{{ object }}{% endblock %}
|
{% block title %}{{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">Children</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">{% trans "Children" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="child-name display-4">{{ object }}</div>
|
<div class="child-name display-4">{{ object }}</div>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Born <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
{% trans "Born" %} <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
||||||
Age <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
{% trans "Age" %} <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
||||||
</p>
|
</p>
|
||||||
{% include 'dashboard/child_button_group.html' %}
|
{% include 'dashboard/child_button_group.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,16 +31,16 @@
|
||||||
<div class="col-lg-8 offset-lg-4 col-md-6 offset-md-6">
|
<div class="col-lg-8 offset-lg-4 col-md-6 offset-md-6">
|
||||||
<h3 class="text-center">
|
<h3 class="text-center">
|
||||||
{% if date_previous %}
|
{% if date_previous %}
|
||||||
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="Previous">
|
<a class="btn btn-sm btn-default" href="?date={{ date_previous|date:"Y-m-d" }}" aria-label="{% trans "Previous" %}">
|
||||||
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
<i class="icon icon-chevron-left" aria-hidden="true"></i>
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">{% trans "Previous" %}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ date|date }}
|
{{ date|date }}
|
||||||
{% if date_next %}
|
{% if date_next %}
|
||||||
<a class="btn btn-sm btn-default" href="?date={{ date_next|date:"Y-m-d" }}" aria-label="Next">
|
<a class="btn btn-sm btn-default" href="?date={{ date_next|date:"Y-m-d" }}" aria-label="{% trans "Next" %}">
|
||||||
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
<i class="icon icon-chevron-right" aria-hidden="true"></i>
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">{% trans "Next" %}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
{{ object.event }}
|
{{ object.event }}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-muted">
|
<div class="card-footer text-muted">
|
||||||
{{ object.time|timesince }} ago ({{ object.time|time }})
|
{% blocktrans with since=object.time|timesince time=object.time|time %}{{ since }} ago ({{ time }}){% endblocktrans %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,28 +1,29 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
{{ object }}
|
{{ object }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Child
|
{% trans "Add a Child" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">Children</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">{% trans "Children" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add a Child</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a Child" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Child</h1>
|
<h1>{% trans "Add a Child" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks static thumbnail %}
|
{% load i18n static thumbnail widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Children{% endblock %}
|
{% block title %}{% trans "Children" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Children</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Children" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Children</h1>
|
<h1>{% trans "Children" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover child-list">
|
<table class="table table-striped table-hover child-list">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="picture-column"><i class="icon icon-camera" aria-hidden="true"></i></th>
|
<th class="picture-column"><i class="icon icon-camera" aria-hidden="true"></i></th>
|
||||||
<th>First Name</th>
|
<th>{% trans "First Name" %}</th>
|
||||||
<th>Last Name</th>
|
<th>{% trans "Last Name" %}</th>
|
||||||
<th>Birth Date</th>
|
<th>{% trans "Birth Date" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<td>{{ child.last_name }}</td>
|
<td>{{ child.last_name }}</td>
|
||||||
<td>{{ child.birth_date }}</td>
|
<td>{{ child.birth_date }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_child %}
|
{% if perms.core.change_child %}
|
||||||
<a href="{% url 'core:child-update' child.slug %}" class="btn btn-warning">
|
<a href="{% url 'core:child-update' child.slug %}" class="btn btn-warning">
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="4">No children found.</th>
|
<th colspan="4">{% trans "No children found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_child %}
|
{% if perms.core.add_child %}
|
||||||
<a href="{% url 'core:child-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:child-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-child" aria-hidden="true"></i> Add a Child
|
<i class="icon icon-child" aria-hidden="true"></i> {% trans "Add a Child" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Diaper Change{% endblock %}
|
{% block title %}{% trans "Delete a Diaper Change" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:diaperchange-list' %}">Diaper Changes</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:diaperchange-list' %}">{% trans "Diaper Changes" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:diaperchange-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:diaperchange-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if request.resolver_match.url_name == 'diaperchange-update' %}
|
{% if request.resolver_match.url_name == 'diaperchange-update' %}
|
||||||
Update a Diaper Change
|
{% trans "Update a Diaper Change" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Diaper Change
|
{% trans "Add a Diaper Change" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:diaperchange-list' %}">Diaper Changes</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:diaperchange-list' %}">{% trans "Diaper Changes" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Diaper Change</h1>
|
<h1>{% trans "Add a Diaper Change" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load bootstrap i18n widget_tweaks %}
|
||||||
{% load bootstrap %}
|
|
||||||
|
|
||||||
{% block title %}Diaper Changes{% endblock %}
|
{% block title %}{% trans "Diaper Changes" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Diaper Changes</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Diaper Changes" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Diaper Changes</h1>
|
<h1>{% trans "Diaper Changes" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th class="text-center">Wet</th>
|
<th class="text-center">{% trans "Wet" %}</th>
|
||||||
<th class="text-center">Solid</th>
|
<th class="text-center">{% trans "Solid" %}</th>
|
||||||
<th>Color</th>
|
<th>{% trans "Color" %}</th>
|
||||||
<th>Time</th>
|
<th>{% trans "Time" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
<td>{{ change.color }}</td>
|
<td>{{ change.color }}</td>
|
||||||
<td>{{ change.time|date:'n/j/y G:i' }}</td>
|
<td>{{ change.time|date:'n/j/y G:i' }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_diaperchange %}
|
{% if perms.core.change_diaperchange %}
|
||||||
<a href="{% url 'core:diaperchange-update' change.id %}" class="btn btn-primary">
|
<a href="{% url 'core:diaperchange-update' change.id %}" class="btn btn-primary">
|
||||||
|
@ -51,7 +50,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="6">No diaper changes found.</th>
|
<th colspan="6">{% trans "No diaper changes found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -61,7 +60,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_diaperchange %}
|
{% if perms.core.add_diaperchange %}
|
||||||
<a href="{% url 'core:diaperchange-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:diaperchange-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-diaperchange" aria-hidden="true"></i> Add a Change
|
<i class="icon icon-diaperchange" aria-hidden="true"></i> {% trans "Add a Change" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Feeding{% endblock %}
|
{% block title %}{% trans "Delete a Feeding" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:feeding-list' %}">Feedings</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:feeding-list' %}">{% trans "Feedings" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:feeding-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:feeding-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if request.resolver_match.url_name == 'feeding-update' %}
|
{% if request.resolver_match.url_name == 'feeding-update' %}
|
||||||
Update a Feeding
|
{% trans "Update a Feeding" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Feeding
|
{% trans "Add a Feeding" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:feeding-list' %}">Feedings</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:feeding-list' %}">{% trans "Feedings" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Feeding</h1>
|
<h1>{% trans "Add a Feeding" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load duration i18n widget_tweaks %}
|
||||||
{% load duration %}
|
|
||||||
|
|
||||||
{% block title %}Feedings{% endblock %}
|
{% block title %}{% trans "Feedings" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Feedings</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Feedings" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Feedings</h1>
|
<h1>{% trans "Feedings" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th>Method</th>
|
<th>{% trans "Method" %}</th>
|
||||||
<th>Type</th>
|
<th>{% trans "Type" %}</th>
|
||||||
<th>Amt.</th>
|
{% comment %}Abbreviation of "Amount"{% endcomment %}
|
||||||
<th>Duration</th>
|
<th>{% trans "Amt." %}</th>
|
||||||
<th>Date</th>
|
<th>{% trans "Duration" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th>{% trans "Date" %}</th>
|
||||||
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<td>{{ feeding.duration|duration_string }}</td>
|
<td>{{ feeding.duration|duration_string }}</td>
|
||||||
<td>{{ feeding.start|date:'n/j/y G:i' }}</td>
|
<td>{{ feeding.start|date:'n/j/y G:i' }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_feeding %}
|
{% if perms.core.change_feeding %}
|
||||||
<a href="{% url 'core:feeding-update' feeding.id %}" class="btn btn-primary">
|
<a href="{% url 'core:feeding-update' feeding.id %}" class="btn btn-primary">
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="7">No feedings found.</th>
|
<th colspan="7">{% trans "No feedings found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_feeding %}
|
{% if perms.core.add_feeding %}
|
||||||
<a href="{% url 'core:feeding-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:feeding-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-feeding" aria-hidden="true"></i> Add a Feeding
|
<i class="icon icon-feeding" aria-hidden="true"></i> {% trans "Add a Feeding" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Note{% endblock %}
|
{% block title %}{% trans "Delete a Note" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:note-list' %}">Notes</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:note-list' %}">{% trans "Notes" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:note-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:note-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if request.resolver_match.url_name == 'note-update' %}
|
{% if request.resolver_match.url_name == 'note-update' %}
|
||||||
Update a Note
|
{% trans "Update a Note" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Note
|
{% trans "Add a Note" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:note-list' %}">Notes</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:note-list' %}">{% trans "Notes" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Note</h1>
|
<h1>{% trans "Add a Note" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,23 +1,23 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Notes{% endblock %}
|
{% block title %}{% trans "Notes" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Notes</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Notes" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Notes</h1>
|
<h1>{% trans "Notes" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th>Note</th>
|
<th>{% trans "Note" %}</th>
|
||||||
<th>Time</th>
|
<th>{% trans "Time" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<td>{{ note.note }}</td>
|
<td>{{ note.note }}</td>
|
||||||
<td>{{ note.time }}</td>
|
<td>{{ note.time }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_note %}
|
{% if perms.core.change_note %}
|
||||||
<a href="{% url 'core:note-update' note.id %}" class="btn btn-primary">
|
<a href="{% url 'core:note-update' note.id %}" class="btn btn-primary">
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="4">No notes found.</th>
|
<th colspan="4">{% trans "No notes found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_note %}
|
{% if perms.core.add_note %}
|
||||||
<a href="{% url 'core:note-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:note-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-note" aria-hidden="true"></i> Add a Note
|
<i class="icon icon-note" aria-hidden="true"></i> {% trans "Add a Note" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Sleep Entry{% endblock %}
|
{% block title %}{% trans "Delete a Sleep Entry" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:sleep-list' %}">Sleep</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:sleep-list' %}">{% trans "Sleep" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:sleep-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:sleep-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if request.resolver_match.url_name == 'sleep-update' %}
|
{% if request.resolver_match.url_name == 'sleep-update' %}
|
||||||
Update a Sleep Entry
|
{% trans "Update a Sleep Entry" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Sleep Entry
|
{% trans "Add a Sleep Entry" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:sleep-list' %}">Sleep</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:sleep-list' %}">{% trans "Sleep" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Sleep Entry</h1>
|
<h1>{% trans "Add a Sleep Entry" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load bootstrap duration widget_tweaks %}
|
{% load bootstrap duration i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Sleep{% endblock %}
|
{% block title %}{% trans "Sleep" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Sleep</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Sleep" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Sleep</h1>
|
<h1>{% trans "Sleep" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th>Duration</th>
|
<th>{% trans "Duration" %}</th>
|
||||||
<th>Start</th>
|
<th>{% trans "Start" %}</th>
|
||||||
<th>End</th>
|
<th>{% trans "End" %}</th>
|
||||||
<th class="text-center">Nap</th>
|
<th class="text-center">{% trans "Nap" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<td>{{ sleep.end|date:'n/j/y G:i' }}</td>
|
<td>{{ sleep.end|date:'n/j/y G:i' }}</td>
|
||||||
<td class="text-center">{{ sleep.nap|bool_icon }}</td>
|
<td class="text-center">{{ sleep.nap|bool_icon }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_sleep %}
|
{% if perms.core.change_sleep %}
|
||||||
<a href="{% url 'core:sleep-update' sleep.id %}" class="btn btn-primary">
|
<a href="{% url 'core:sleep-update' sleep.id %}" class="btn btn-primary">
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="5">No sleep entries found.</th>
|
<th colspan="5">{% trans "No sleep entries found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_sleep %}
|
{% if perms.core.add_sleep %}
|
||||||
<a href="{% url 'core:sleep-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:sleep-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-sleep" aria-hidden="true"></i> Add a Sleep Entry
|
<i class="icon icon-sleep" aria-hidden="true"></i> {% trans "Add a Sleep Entry" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete {{ object }}{% endblock %}
|
{% block title %}{% blocktrans %}Delete {{ object }}{% endblocktrans %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">Timers</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">{% trans "Timers" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:timer-detail' object.id %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:timer-detail' object.id %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="/" class="btn btn-default">Cancel</a>
|
<a href="/" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,10 +1,10 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load duration timers %}
|
{% load duration i18n timers %}
|
||||||
|
|
||||||
{% block title %}{{ object }}{% endblock %}
|
{% block title %}{{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">Timers</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">{% trans "Timers" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
<li class="breadcrumb-item font-weight-bold">{{ object }}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -17,34 +17,40 @@
|
||||||
<span class="timer-seconds">{{ object.duration|seconds }}</span>s
|
<span class="timer-seconds">{{ object.duration|seconds }}</span>s
|
||||||
</div>
|
</div>
|
||||||
<p class="lead text-secondary">
|
<p class="lead text-secondary">
|
||||||
Started {{ object.start }}
|
{% trans "Started" %} {{ object.start }}
|
||||||
{% if not object.active %}
|
{% if not object.active %}
|
||||||
/ Stopped {{ object.end }}
|
/ {% trans "Stopped" %} {{ object.end }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
{{ timer }} created by {{ object.user }}
|
{% blocktrans %}{{ timer }} created by {{ object.user }}{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if perms.core.add_feeding %}
|
{% if perms.core.add_feeding %}
|
||||||
<a class="btn btn-success btn-lg btn-block mb-3"
|
<a class="btn btn-success btn-lg btn-block mb-3"
|
||||||
href="{% url 'core:feeding-add' %}?timer={{ timer.id }}"
|
href="{% url 'core:feeding-add' %}?timer={{ timer.id }}"
|
||||||
role="button"><i class="icon icon-feeding" aria-hidden="true"></i> Feeding</a>
|
role="button"><i class="icon icon-feeding" aria-hidden="true"></i>
|
||||||
|
{% trans "Feeding" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.add_sleep %}
|
{% if perms.core.add_sleep %}
|
||||||
<a class="btn btn-success btn-lg btn-block mb-3"
|
<a class="btn btn-success btn-lg btn-block mb-3"
|
||||||
href="{% url 'core:sleep-add' %}?timer={{ timer.id }}"
|
href="{% url 'core:sleep-add' %}?timer={{ timer.id }}"
|
||||||
role="button"><i class="icon icon-sleep" aria-hidden="true"></i> Sleep</a>
|
role="button"><i class="icon icon-sleep" aria-hidden="true"></i>
|
||||||
|
{% trans "Sleep" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.core.add_tummytime %}
|
{% if perms.core.add_tummytime %}
|
||||||
<a class="btn btn-success btn-lg btn-block mb-3"
|
<a class="btn btn-success btn-lg btn-block mb-3"
|
||||||
href="{% url 'core:tummytime-add' %}?timer={{ timer.id }}"
|
href="{% url 'core:tummytime-add' %}?timer={{ timer.id }}"
|
||||||
role="button"><i class="icon icon-tummytime" aria-hidden="true"></i> Tummy Time</a>
|
role="button"><i class="icon icon-tummytime" aria-hidden="true"></i>
|
||||||
|
{% trans "Tummy Time" %}
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="btn-group btn-group-lg center-block" role="group" aria-label="Timer actions">
|
<div class="btn-group btn-group-lg center-block" role="group" aria-label="{% trans "Timer actions" %}">
|
||||||
|
|
||||||
{% if perms.core.delete_timer %}
|
{% if perms.core.delete_timer %}
|
||||||
<a class="btn btn-danger"
|
<a class="btn btn-danger"
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block title %}Timer{% endblock %}
|
{% block title %}{% trans "Timer" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">Timers</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:timer-list' %}">{% trans "Timers" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:timer-detail' object.id %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:timer-detail' object.id %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Start</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Start" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Start Timer</h1>
|
<h1>{% trans "Start Timer" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load bootstrap duration widget_tweaks %}
|
{% load bootstrap duration i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Timers{% endblock %}
|
{% block title %}{% trans "Timers" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Timers</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Timers" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Timers</h1>
|
<h1>{% trans "Timers" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th>Start</th>
|
<th>{% trans "Start" %}</th>
|
||||||
<th>Duration</th>
|
<th>{% trans "Duration" %}</th>
|
||||||
<th>End</th>
|
<th>{% trans "End" %}</th>
|
||||||
<th>Active</th>
|
<th>{% trans "Active" %}</th>
|
||||||
<th>User</th>
|
<th>{% trans "User" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="7">No timer entries found.</th>
|
<th colspan="7">{% trans "No timer entries found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1,30 +1,34 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a id="nav-timer-menu-link"
|
<a id="nav-timer-menu-link"
|
||||||
class="nav-link dropdown-toggle"
|
class="nav-link dropdown-toggle"
|
||||||
href="#"
|
href="#"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"><i class="icon icon-timer" aria-hidden="true"></i> Timers</a>
|
aria-expanded="false"><i class="icon icon-timer" aria-hidden="true"></i>
|
||||||
|
{% trans "Timers" %}
|
||||||
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="nav-timer-menu-link">
|
<div class="dropdown-menu" aria-labelledby="nav-timer-menu-link">
|
||||||
{% if perms.core.add_timer %}
|
{% if perms.core.add_timer %}
|
||||||
<a class="dropdown-item" href="{% url 'core:timer-add-quick' %}">
|
<a class="dropdown-item" href="{% url 'core:timer-add-quick' %}">
|
||||||
<i class="icon icon-timer" aria-hidden="true"></i> Quick Start Timer
|
<i class="icon icon-timer" aria-hidden="true"></i> {% trans "Quick Start Timer" %}
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item" href="{% url 'core:timer-add' %}">
|
<a class="dropdown-item" href="{% url 'core:timer-add' %}">
|
||||||
<i class="icon icon-add" aria-hidden="true"></i> Start Timer
|
<i class="icon icon-add" aria-hidden="true"></i> {% trans "Start Timer" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.core.view_timer %}
|
{% if perms.core.view_timer %}
|
||||||
<a class="dropdown-item" href="{% url 'core:timer-list' %}">
|
<a class="dropdown-item" href="{% url 'core:timer-list' %}">
|
||||||
<i class="icon icon-list" aria-hidden="true"></i> View Timers
|
<i class="icon icon-list" aria-hidden="true"></i> {% trans "View Timers" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if timers %}
|
{% if timers %}
|
||||||
<h6 class="dropdown-header">Active Timers</h6>
|
<h6 class="dropdown-header">{% trans "Active Timers" %}</h6>
|
||||||
{% for timer in timers %}
|
{% for timer in timers %}
|
||||||
<a class="dropdown-item" href="{% url 'core:timer-detail' timer.id %}">{{ timer }} ({{ timer.user }})</a>
|
<a class="dropdown-item" href="{% url 'core:timer-detail' timer.id %}">{{ timer }} ({{ timer.user }})</a>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<a class="dropdown-item disabled" href="#">None</a>
|
<a class="dropdown-item disabled" href="#">{% trans "None" %}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Tummy Time Entry{% endblock %}
|
{% block title %}{% trans "Delete a Tummy Time Entry" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:tummytime-list' %}">Tummy Time</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:tummytime-list' %}">{% trans "Tummy Time" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:tummytime-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:tummytime-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if request.resolver_match.url_name == 'tummytime-update' %}
|
{% if request.resolver_match.url_name == 'tummytime-update' %}
|
||||||
Update a Tummy Time Entry
|
{% trans "Update a Tummy Time Entry" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Tummy Time Entry
|
{% trans "Add a Tummy Time Entry" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:tummytime-list' %}">Tummy Time</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:tummytime-list' %}">{% trans "Tummy Time" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Tummy Time Entry</h1>
|
<h1>{% trans "Add a Tummy Time Entry" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load duration i18n widget_tweaks %}
|
||||||
{% load duration %}
|
|
||||||
|
|
||||||
{% block title %}Tummy Time{% endblock %}
|
{% block title %}{% trans "Tummy Time" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Tummy Time</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Tummy Time" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Tummy Time</h1>
|
<h1>{% trans "Tummy Time" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th>Duration</th>
|
<th>{% trans "Duration" %}</th>
|
||||||
<th>Start</th>
|
<th>{% trans "Start" %}</th>
|
||||||
<th>End</th>
|
<th>{% trans "End" %}</th>
|
||||||
<th>Milestone</th>
|
<th>{% trans "Milestone" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -32,7 +31,7 @@
|
||||||
<td>{{ tummytime.end|date:'n/j/y G:i' }}</td>
|
<td>{{ tummytime.end|date:'n/j/y G:i' }}</td>
|
||||||
<td>{{ tummytime.milestone }}</td>
|
<td>{{ tummytime.milestone }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_tummytime %}
|
{% if perms.core.change_tummytime %}
|
||||||
<a href="{% url 'core:tummytime-update' tummytime.id %}" class="btn btn-primary">
|
<a href="{% url 'core:tummytime-update' tummytime.id %}" class="btn btn-primary">
|
||||||
|
@ -51,7 +50,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="6">No tummy time entries found.</th>
|
<th colspan="6">{% trans "No tummy time entries found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -61,7 +60,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_tummytime %}
|
{% if perms.core.add_tummytime %}
|
||||||
<a href="{% url 'core:tummytime-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:tummytime-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-tummytime" aria-hidden="true"></i> Add a Tummy Time Entry</a>
|
<i class="icon icon-tummytime" aria-hidden="true"></i> {% trans "Add a Tummy Time Entry" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,18 +1,18 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Delete a Weight Entry{% endblock %}
|
{% block title %}{% trans "Delete a Weight Entry" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:weight-list' %}">Weight</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:weight-list' %}">{% trans "Weight" %}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Delete</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form role="form" method="post">
|
<form role="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
{% blocktrans %}<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>{% endblocktrans %}
|
||||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||||
<a href="{% url 'core:weight-list' %}" class="btn btn-default">Cancel</a>
|
<a href="{% url 'core:weight-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,27 +1,28 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
{{ object }}
|
{{ object }}
|
||||||
{% else %}
|
{% else %}
|
||||||
Add a Weight Entry
|
{% trans "Add a Weight Entry" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:weight-list' %}">Weight</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:weight-list' %}">{% trans "Weight" %}</a></li>
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Update</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Add a Weight Entry</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a Weight Entry" %}</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if object %}
|
{% if object %}
|
||||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
{% blocktrans %}<h1>Update <span class="text-info">{{ object }}</span></h1>{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>Add a Weight Entry</h1>
|
<h1>{% trans "Add a Weight Entry" %}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'babybuddy/form.html' %}
|
{% include 'babybuddy/form.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load i18n widget_tweaks %}
|
||||||
|
|
||||||
{% block title %}Weight{% endblock %}
|
{% block title %}{% trans "Weight" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Weight</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Weight" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Weight</h1>
|
<h1>{% trans "Weight" %}</h1>
|
||||||
{% include 'babybuddy/filter.html' %}
|
{% include 'babybuddy/filter.html' %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-striped table-hover">
|
<table class="table table-striped table-hover">
|
||||||
<thead class="thead-inverse">
|
<thead class="thead-inverse">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Child</th>
|
<th>{% trans "Child" %}</th>
|
||||||
<th>Weight</th>
|
<th>{% trans "Weight" %}</th>
|
||||||
<th>Date</th>
|
<th>{% trans "Date" %}</th>
|
||||||
<th class="text-center">Actions</th>
|
<th class="text-center">{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<td>{{ object.weight }}</td>
|
<td>{{ object.weight }}</td>
|
||||||
<td>{{ object.date }}</td>
|
<td>{{ object.date }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="Actions">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
{% if perms.core.change_weight %}
|
{% if perms.core.change_weight %}
|
||||||
<a href="{% url 'core:weight-update' object.id %}" class="btn btn-primary">
|
<a href="{% url 'core:weight-update' object.id %}" class="btn btn-primary">
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="4">No weight entries found.</th>
|
<th colspan="4">{% trans "No weight entries found." %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
{% if perms.core.add_weight %}
|
{% if perms.core.add_weight %}
|
||||||
<a href="{% url 'core:weight-add' %}" class="btn btn-sm btn-success">
|
<a href="{% url 'core:weight-add' %}" class="btn btn-sm btn-success">
|
||||||
<i class="icon icon-weight" aria-hidden="true"></i> Add a Weight Entry
|
<i class="icon icon-weight" aria-hidden="true"></i> {% trans "Add a Weight Entry" %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
||||||
|
|
||||||
|
@ -20,7 +21,9 @@ def get_objects(child, date):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.time),
|
'time': timezone.localtime(instance.time),
|
||||||
'event': '{} had a diaper change.'.format(child.first_name),
|
'event': _('%(child)s had a diaper change.') % {
|
||||||
|
'child': child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -29,13 +32,17 @@ def get_objects(child, date):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.start),
|
'time': timezone.localtime(instance.start),
|
||||||
'event': '{} started feeding.'.format(instance.child.first_name),
|
'event': _('%(child)s started feeding.') % {
|
||||||
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'start'
|
'type': 'start'
|
||||||
})
|
})
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.end),
|
'time': timezone.localtime(instance.end),
|
||||||
'event': '{} finished feeding.'.format(instance.child.first_name),
|
'event': _('%(child)s finished feeding.') % {
|
||||||
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'end'
|
'type': 'end'
|
||||||
})
|
})
|
||||||
|
@ -45,13 +52,17 @@ def get_objects(child, date):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.start),
|
'time': timezone.localtime(instance.start),
|
||||||
'event': '{} fell asleep.'.format(instance.child.first_name),
|
'event': _('%(child)s fell asleep.') % {
|
||||||
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'start'
|
'type': 'start'
|
||||||
})
|
})
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.end),
|
'time': timezone.localtime(instance.end),
|
||||||
'event': '{} woke up.'.format(instance.child.first_name),
|
'event': _('%(child)s woke up.') % {
|
||||||
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'end'
|
'type': 'end'
|
||||||
})
|
})
|
||||||
|
@ -61,15 +72,17 @@ def get_objects(child, date):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.start),
|
'time': timezone.localtime(instance.start),
|
||||||
'event': '{} started tummy time!'.format(
|
'event': _('%(child)s started tummy time!') % {
|
||||||
instance.child.first_name),
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'start'
|
'type': 'start'
|
||||||
})
|
})
|
||||||
events.append({
|
events.append({
|
||||||
'time': timezone.localtime(instance.end),
|
'time': timezone.localtime(instance.end),
|
||||||
'event': '{} finished tummy time.'.format(
|
'event': _('%(child)s finished tummy time.') % {
|
||||||
instance.child.first_name),
|
'child': instance.child.first_name
|
||||||
|
},
|
||||||
'model_name': instance.model_name,
|
'model_name': instance.model_name,
|
||||||
'type': 'end'
|
'type': 'end'
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,6 +3,7 @@ from django.contrib import messages
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||||
|
@ -16,9 +17,9 @@ class CoreAddView(PermissionRequired403Mixin, SuccessMessageMixin, CreateView):
|
||||||
def get_success_message(self, cleaned_data):
|
def get_success_message(self, cleaned_data):
|
||||||
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
||||||
if 'child' in cleaned_data:
|
if 'child' in cleaned_data:
|
||||||
self.success_message = '%(model)s entry for %(child)s added!'
|
self.success_message = _('%(model)s entry for %(child)s added!')
|
||||||
else:
|
else:
|
||||||
self.success_message = '%(model)s entry added!'
|
self.success_message = _('%(model)s entry added!')
|
||||||
return self.success_message % cleaned_data
|
return self.success_message % cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,9 +28,9 @@ class CoreUpdateView(PermissionRequired403Mixin, SuccessMessageMixin,
|
||||||
def get_success_message(self, cleaned_data):
|
def get_success_message(self, cleaned_data):
|
||||||
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
cleaned_data['model'] = self.model._meta.verbose_name.title()
|
||||||
if 'child' in cleaned_data:
|
if 'child' in cleaned_data:
|
||||||
self.success_message = '%(model)s entry for %(child)s updated.'
|
self.success_message = _('%(model)s entry for %(child)s updated.')
|
||||||
else:
|
else:
|
||||||
self.success_message = '%(model)s entry updated.'
|
self.success_message = _('%(model)s entry updated.')
|
||||||
return self.success_message % cleaned_data
|
return self.success_message % cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ class ChildAdd(CoreAddView):
|
||||||
permission_required = ('core.add_child',)
|
permission_required = ('core.add_child',)
|
||||||
form_class = forms.ChildForm
|
form_class = forms.ChildForm
|
||||||
success_url = reverse_lazy('core:child-list')
|
success_url = reverse_lazy('core:child-list')
|
||||||
success_message = '%(first_name)s %(last_name)s added!'
|
success_message = _('%(first_name)s %(last_name)s added!')
|
||||||
|
|
||||||
|
|
||||||
class ChildDetail(PermissionRequired403Mixin, DetailView):
|
class ChildDetail(PermissionRequired403Mixin, DetailView):
|
||||||
|
@ -286,7 +287,7 @@ class TimerRestart(PermissionRequired403Mixin, RedirectView):
|
||||||
|
|
||||||
class TimerStop(PermissionRequired403Mixin, SuccessMessageMixin, RedirectView):
|
class TimerStop(PermissionRequired403Mixin, SuccessMessageMixin, RedirectView):
|
||||||
permission_required = ('core.change_timer',)
|
permission_required = ('core.change_timer',)
|
||||||
success_message = '%(timer)s stopped.'
|
success_message = _('%(timer)s stopped.')
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
instance = models.Timer.objects.get(id=kwargs['pk'])
|
instance = models.Timer.objects.get(id=kwargs['pk'])
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block header %}Last Diaper Change{% endblock %}
|
{% block header %}{% trans "Last Diaper Change" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if change %}
|
{% if change %}
|
||||||
{{ change.time|timesince }} ago
|
{% blocktrans with time=change.time|timesince %}{{ time }} ago{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Never
|
{% trans "Never" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block header %}Diaper Changes{% endblock %}
|
{% block header %}{% trans "Diaper Changes" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Past Week
|
{% trans "Past Week" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -14,23 +15,23 @@
|
||||||
{% if info.wet_pct > 0 %}
|
{% if info.wet_pct > 0 %}
|
||||||
<div class="progress-bar bg-primary lead"
|
<div class="progress-bar bg-primary lead"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
style="width: {{ info.wet_pct }}%;">{{ info.wet|floatformat:'0' }} wet</div>
|
style="width: {{ info.wet_pct|safe }}%;">{{ info.wet|floatformat:'0' }} {% trans "wet" %}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if info.solid_pct > 0 %}
|
{% if info.solid_pct > 0 %}
|
||||||
<div class="progress-bar bg-secondary lead"
|
<div class="progress-bar bg-secondary lead"
|
||||||
role="progressbar"
|
role="progressbar"
|
||||||
style="width: {{ info.solid_pct }}%;">
|
style="width: {{ info.solid_pct|safe }}%;">
|
||||||
{{ info.solid|floatformat:'0' }} solid</div>
|
{{ info.solid|floatformat:'0' }} {% trans "solid" %}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center text-light small">
|
<div class="text-center text-light small">
|
||||||
{% if key == 0 %}
|
{% if key == 0 %}
|
||||||
today
|
{% trans "today" %}
|
||||||
{% elif key == 1 %}
|
{% elif key == 1 %}
|
||||||
yesterday
|
{% trans "yesterday" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ key }} days ago
|
{% blocktrans %}{{ key }} days ago{% endblocktrans %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block header %}Last Feeding{% endblock %}
|
{% block header %}{% trans "Last Feeding" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if feeding %}
|
{% if feeding %}
|
||||||
{{ feeding.end|timesince }} ago
|
{% blocktrans with time=feeding.end|timesince %}{{ time }} ago{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Never
|
{% trans "Never" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block header %}Last Feeding Method{% endblock %}
|
{% block header %}{% trans "Last Feeding Method" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if feeding %}
|
{% if feeding %}
|
||||||
<div class="display-4 text-center">{{ feeding.method }}</div>
|
<div class="display-4 text-center">{{ feeding.method }}</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
None
|
{% trans "None" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,18 +1,20 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block header %}Today's Sleep{% endblock %}
|
{% block header %}{% trans "Today's Sleep" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if total %}
|
{% if total %}
|
||||||
{{ total|duration_string }}
|
{{ total|duration_string }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
None yet today
|
{% trans "None yet today" %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if count > 0 %}{{ count }} sleep entries{% endif %}
|
{% if count > 0 %}
|
||||||
|
{% blocktrans %}{{ count }} sleep entries{% endblocktrans %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,13 +1,13 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block header %}Last Slept{% endblock %}
|
{% block header %}{% trans "Last Slept" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if sleep %}
|
{% if sleep %}
|
||||||
{{ sleep.end|timesince }} ago
|
{% blocktrans with time=sleep.end|timesince %}{{ time }} ago{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Never
|
{% trans "Never" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block header %}Today's Naps{% endblock %}
|
{% block header %}{% trans "Today's Naps" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if count %}
|
{% if count %}
|
||||||
{{ count }} nap{{ count|pluralize }}
|
{% blocktrans with plural=count|pluralize %}{{ count }} nap{{ plural }}{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
None yet today
|
{% trans "None yet today" %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
<div class="card card-dashboard card-statistics">
|
<div class="card card-dashboard card-statistics">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<i class="icon icon-graph pull-left" aria-hidden="true"></i>
|
<i class="icon icon-graph pull-left" aria-hidden="true"></i>
|
||||||
Statistics
|
{% trans "Statistics" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<div id="statistics-carousel" class="carousel slide" data-interval="false">
|
<div id="statistics-carousel" class="carousel slide" data-interval="false">
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
{{ stat.stat }}
|
{{ stat.stat }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<em>Not enough data</em>
|
<em>{% trans "Not enough data" %}</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
<div class="card-text">{{ stat.title }}</div>
|
<div class="card-text">{{ stat.title }}</div>
|
||||||
|
@ -29,11 +29,11 @@
|
||||||
</div>
|
</div>
|
||||||
<a class="carousel-control-prev" href="#statistics-carousel" role="button" data-slide="prev">
|
<a class="carousel-control-prev" href="#statistics-carousel" role="button" data-slide="prev">
|
||||||
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
|
||||||
<span class="sr-only">Previous</span>
|
<span class="sr-only">{% trans "Previous" %}</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="carousel-control-next" href="#statistics-carousel" role="button" data-slide="next">
|
<a class="carousel-control-next" href="#statistics-carousel" role="button" data-slide="next">
|
||||||
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
<span class="carousel-control-next-icon" aria-hidden="true"></span>
|
||||||
<span class="sr-only">Next</span>
|
<span class="sr-only">{% trans "Next" %}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block header %}Active Timers{% endblock %}
|
{% block header %}{% trans "Active Timers" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% with instances|length as count %}
|
{% with instances|length as count %}
|
||||||
{{ count }} active timer{{ count|pluralize }}
|
{% blocktrans with plural=count|pluralize %}{{ count }} active timer{{ plural }}{% endblocktrans %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -13,7 +14,10 @@
|
||||||
{% for instance in instances %}
|
{% for instance in instances %}
|
||||||
<a href="{% url 'core:timer-detail' instance.id %}"
|
<a href="{% url 'core:timer-detail' instance.id %}"
|
||||||
class="list-group-item list-group-item-action">
|
class="list-group-item list-group-item-action">
|
||||||
<strong>{{ instance }}</strong> <p class="text-muted small m-0">Started by {{ instance.user }} at {{ instance.start|time }}</p>
|
<strong>{{ instance }}</strong>
|
||||||
|
<p class="text-muted small m-0">
|
||||||
|
{% blocktrans with start=instance.start|time %}Started by {{ instance.user }} at {{ start }}{% endblocktrans %}
|
||||||
|
</p>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block header %}Today's Tummy Time{% endblock %}
|
{% block header %}{% trans "Today's Tummy Time" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if stats.count > 0 %}
|
{% if stats.count > 0 %}
|
||||||
{{ stats.total|duration_string }}
|
{{ stats.total|duration_string }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
None yet today
|
{% trans "None yet today" %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -16,7 +16,9 @@
|
||||||
{% block listgroup %}
|
{% block listgroup %}
|
||||||
<ul class="list-group list-group-flush text-muted small">
|
<ul class="list-group list-group-flush text-muted small">
|
||||||
{% for instance in instances %}
|
{% for instance in instances %}
|
||||||
<li class="list-group-item">{{ instance.duration|duration_string }} at {{ instance.end|time }}</li>
|
<li class="list-group-item">
|
||||||
|
{% blocktrans with duration=instance.duration|duration_string end=instance.end|time %}{{ duration }} at {{ end }}{% endblocktrans %}
|
||||||
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,13 +1,13 @@
|
||||||
{% extends 'cards/base.html' %}
|
{% extends 'cards/base.html' %}
|
||||||
{% load duration %}
|
{% load duration i18n %}
|
||||||
|
|
||||||
{% block header %}Last Tummy Time{% endblock %}
|
{% block header %}{% trans "Last Tummy Time" %}{% endblock %}
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if tummytime %}
|
{% if tummytime %}
|
||||||
{{ tummytime.time|timesince }} ago
|
{% blocktrans with time=tummytime.time|timesince %}{{ time }} ago{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
Never
|
{% trans "Never" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load cards %}
|
{% load cards i18n %}
|
||||||
|
|
||||||
{% block title %}Dashboard - {{ object }}{% endblock %}
|
{% block title %}{% trans "Dashboard" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">Children</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">{% trans "Children" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item active" aria-current="page">Dashboard</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Dashboard" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<div class="child-actions btn-group btn-group-lg center-block" role="group" aria-label="Child actions">
|
{% load i18n %}
|
||||||
|
|
||||||
|
<div class="child-actions btn-group btn-group-lg center-block" role="group" aria-label="{% trans "Child actions" %}">
|
||||||
|
|
||||||
{% if perms.core.view_child %}
|
{% if perms.core.view_child %}
|
||||||
<a href="{% url 'dashboard:dashboard-child' object.slug %}" class="btn btn-success">
|
<a href="{% url 'dashboard:dashboard-child' object.slug %}" class="btn btn-success">
|
||||||
|
@ -14,12 +16,12 @@
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"><i class="icon icon-graph" aria-hidden="true"></i></button>
|
aria-expanded="false"><i class="icon icon-graph" aria-hidden="true"></i></button>
|
||||||
<div class="dropdown-menu" aria-labelledby="reports-dropdown">
|
<div class="dropdown-menu" aria-labelledby="reports-dropdown">
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-types-child' object.slug %}">Diaper Change Types</a>
|
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-types-child' object.slug %}">{% trans "Diaper Change Types" %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-lifetimes-child' object.slug %}">Diaper Lifetimes</a>
|
<a class="dropdown-item" href="{% url 'reports:report-diaperchange-lifetimes-child' object.slug %}">{% trans "Diaper Lifetimes" %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-feeding-duration-child' object.slug %}">Feeding Durations (Average)</a>
|
<a class="dropdown-item" href="{% url 'reports:report-feeding-duration-child' object.slug %}">{% trans "Feeding Durations (Average)" %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-sleep-pattern-child' object.slug %}">Sleep Pattern</a>
|
<a class="dropdown-item" href="{% url 'reports:report-sleep-pattern-child' object.slug %}">{% trans "Sleep Pattern" %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">Sleep Totals</a>
|
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">{% trans "Sleep Totals" %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'reports:report-weight-weight-child' object.slug %}">Weight</a>
|
<a class="dropdown-item" href="{% url 'reports:report-weight-weight-child' object.slug %}">{% trans "Weight" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load static thumbnail %}
|
{% load i18n static thumbnail %}
|
||||||
|
|
||||||
{% block title %}Dashboard{% endblock %}
|
{% block title %}{% trans "Dashboard" %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item font-weight-bold">Dashboard</li>
|
<li class="breadcrumb-item font-weight-bold">{% trans "Dashboard" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -24,8 +24,8 @@
|
||||||
<h4 class="card-title">{{ object }}</h4>
|
<h4 class="card-title">{{ object }}</h4>
|
||||||
<div class="card-text">
|
<div class="card-text">
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Born <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
{% trans "Born" %} <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
||||||
Age <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
{% trans "Age" %} <span class="text-secondary">{{ object.birth_date|timesince }}</span>
|
||||||
</p>
|
</p>
|
||||||
{% include 'dashboard/child_button_group.html' %}
|
{% include 'dashboard/child_button_group.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ from django import template
|
||||||
from django.db.models import Avg, Count, Sum
|
from django.db.models import Avg, Count, Sum
|
||||||
from django.db.models.functions import TruncDate
|
from django.db.models.functions import TruncDate
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from core import models
|
from core import models
|
||||||
|
|
||||||
|
@ -163,39 +164,39 @@ def card_statistics(child):
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'duration',
|
'type': 'duration',
|
||||||
'stat': changes['btwn_average'],
|
'stat': changes['btwn_average'],
|
||||||
'title': 'Diaper change frequency'})
|
'title': _('Diaper change frequency')})
|
||||||
|
|
||||||
feedings = _feeding_statistics(child)
|
feedings = _feeding_statistics(child)
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'duration',
|
'type': 'duration',
|
||||||
'stat': feedings['btwn_average'],
|
'stat': feedings['btwn_average'],
|
||||||
'title': 'Feeding frequency'})
|
'title': _('Feeding frequency')})
|
||||||
|
|
||||||
naps = _nap_statistics(child)
|
naps = _nap_statistics(child)
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'duration',
|
'type': 'duration',
|
||||||
'stat': naps['average'],
|
'stat': naps['average'],
|
||||||
'title': 'Average nap duration'})
|
'title': _('Average nap duration')})
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'float',
|
'type': 'float',
|
||||||
'stat': naps['avg_per_day'],
|
'stat': naps['avg_per_day'],
|
||||||
'title': 'Average naps per day'})
|
'title': _('Average naps per day')})
|
||||||
|
|
||||||
sleep = _sleep_statistics(child)
|
sleep = _sleep_statistics(child)
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'duration',
|
'type': 'duration',
|
||||||
'stat': sleep['average'],
|
'stat': sleep['average'],
|
||||||
'title': 'Average sleep duration'})
|
'title': _('Average sleep duration')})
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'duration',
|
'type': 'duration',
|
||||||
'stat': sleep['btwn_average'],
|
'stat': sleep['btwn_average'],
|
||||||
'title': 'Average awake duration'})
|
'title': _('Average awake duration')})
|
||||||
|
|
||||||
weight = _weight_statistics(child)
|
weight = _weight_statistics(child)
|
||||||
stats.append({
|
stats.append({
|
||||||
'type': 'float',
|
'type': 'float',
|
||||||
'stat': weight['change_weekly'],
|
'stat': weight['change_weekly'],
|
||||||
'title': 'Weight change per week'})
|
'title': _('Weight change per week')})
|
||||||
|
|
||||||
return {'stats': stats}
|
return {'stats': stats}
|
||||||
|
|
||||||
|
|
12
gulpfile.js
12
gulpfile.js
|
@ -171,6 +171,18 @@ gulp.task('makemigrations', function(cb) {
|
||||||
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
|
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('makemessages', function(cb) {
|
||||||
|
var command = ['run', 'python', 'manage.py', 'makemessages'];
|
||||||
|
command = command.concat(process.argv.splice(3));
|
||||||
|
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('compilemessages', function(cb) {
|
||||||
|
var command = ['run', 'python', 'manage.py', 'compilemessages'];
|
||||||
|
command = command.concat(process.argv.splice(3));
|
||||||
|
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('reset', function(cb) {
|
gulp.task('reset', function(cb) {
|
||||||
spawn(
|
spawn(
|
||||||
'pipenv',
|
'pipenv',
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ def diaperchange_lifetimes(changes):
|
||||||
|
|
||||||
trace = go.Box(
|
trace = go.Box(
|
||||||
y=[round(d.seconds/3600, 2) for d in durations],
|
y=[round(d.seconds/3600, 2) for d in durations],
|
||||||
name='Changes',
|
name=_('Changes'),
|
||||||
jitter=0.3,
|
jitter=0.3,
|
||||||
pointpos=-1.8,
|
pointpos=-1.8,
|
||||||
boxpoints='all'
|
boxpoints='all'
|
||||||
|
@ -30,8 +32,8 @@ def diaperchange_lifetimes(changes):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['height'] = 800
|
layout_args['height'] = 800
|
||||||
layout_args['title'] = '<b>Diaper Lifetimes</b>'
|
layout_args['title'] = _('<b>Diaper Lifetimes</b>')
|
||||||
layout_args['yaxis']['title'] = 'Time between changes (hours)'
|
layout_args['yaxis']['title'] = _('Time between changes (hours)')
|
||||||
layout_args['yaxis']['zeroline'] = False
|
layout_args['yaxis']['zeroline'] = False
|
||||||
layout_args['yaxis']['dtick'] = 1
|
layout_args['yaxis']['dtick'] = 1
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.db.models import Count, Case, When
|
from django.db.models import Count, Case, When
|
||||||
from django.db.models.functions import TruncDate
|
from django.db.models.functions import TruncDate
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
@ -23,28 +24,28 @@ def diaperchange_types(changes):
|
||||||
|
|
||||||
solid_trace = go.Scatter(
|
solid_trace = go.Scatter(
|
||||||
mode='markers',
|
mode='markers',
|
||||||
name='Solid',
|
name=_('Solid'),
|
||||||
x=list(changes.values_list('date', flat=True)),
|
x=list(changes.values_list('date', flat=True)),
|
||||||
y=list(changes.values_list('solid_count', flat=True)),
|
y=list(changes.values_list('solid_count', flat=True)),
|
||||||
)
|
)
|
||||||
wet_trace = go.Scatter(
|
wet_trace = go.Scatter(
|
||||||
mode='markers',
|
mode='markers',
|
||||||
name='Wet',
|
name=_('Wet'),
|
||||||
x=list(changes.values_list('date', flat=True)),
|
x=list(changes.values_list('date', flat=True)),
|
||||||
y=list(changes.values_list('wet_count', flat=True))
|
y=list(changes.values_list('wet_count', flat=True))
|
||||||
)
|
)
|
||||||
total_trace = go.Scatter(
|
total_trace = go.Scatter(
|
||||||
name='Total',
|
name=_('Total'),
|
||||||
x=list(changes.values_list('date', flat=True)),
|
x=list(changes.values_list('date', flat=True)),
|
||||||
y=list(changes.values_list('total', flat=True))
|
y=list(changes.values_list('total', flat=True))
|
||||||
)
|
)
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['title'] = '<b>Diaper Change Types</b>'
|
layout_args['title'] = _('<b>Diaper Change Types</b>')
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = _('Date')
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Number of changes'
|
layout_args['yaxis']['title'] = _('Number of changes')
|
||||||
|
|
||||||
fig = go.Figure({
|
fig = go.Figure({
|
||||||
'data': [solid_trace, wet_trace, total_trace],
|
'data': [solid_trace, wet_trace, total_trace],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.db.models import Count, Sum
|
from django.db.models import Count, Sum
|
||||||
from django.db.models.functions import TruncDate
|
from django.db.models.functions import TruncDate
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
@ -32,7 +33,7 @@ def feeding_duration(instances):
|
||||||
averages.append(total['sum']/total['count'])
|
averages.append(total['sum']/total['count'])
|
||||||
|
|
||||||
trace_avg = go.Scatter(
|
trace_avg = go.Scatter(
|
||||||
name='Average duration',
|
name=_('Average duration'),
|
||||||
line=dict(shape='spline'),
|
line=dict(shape='spline'),
|
||||||
x=list(totals.values_list('date', flat=True)),
|
x=list(totals.values_list('date', flat=True)),
|
||||||
y=[td.seconds/60 for td in averages],
|
y=[td.seconds/60 for td in averages],
|
||||||
|
@ -40,7 +41,7 @@ def feeding_duration(instances):
|
||||||
text=[_duration_string_ms(td) for td in averages]
|
text=[_duration_string_ms(td) for td in averages]
|
||||||
)
|
)
|
||||||
trace_count = go.Scatter(
|
trace_count = go.Scatter(
|
||||||
name='Total feedings',
|
name=_('Total feedings'),
|
||||||
mode='markers',
|
mode='markers',
|
||||||
x=list(totals.values_list('date', flat=True)),
|
x=list(totals.values_list('date', flat=True)),
|
||||||
y=list(totals.values_list('count', flat=True)),
|
y=list(totals.values_list('count', flat=True)),
|
||||||
|
@ -49,12 +50,12 @@ def feeding_duration(instances):
|
||||||
)
|
)
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['title'] = '<b>Average Feeding Durations</b>'
|
layout_args['title'] = _('<b>Average Feeding Durations</b>')
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = _('Date')
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Average duration (minutes)'
|
layout_args['yaxis']['title'] = _('Average duration (minutes)')
|
||||||
layout_args['yaxis2'] = dict(layout_args['yaxis'])
|
layout_args['yaxis2'] = dict(layout_args['yaxis'])
|
||||||
layout_args['yaxis2']['title'] = 'Number of feedings'
|
layout_args['yaxis2']['title'] = _('Number of feedings')
|
||||||
layout_args['yaxis2']['overlaying'] = 'y'
|
layout_args['yaxis2']['overlaying'] = 'y'
|
||||||
layout_args['yaxis2']['side'] = 'right'
|
layout_args['yaxis2']['side'] = 'right'
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
|
@ -124,10 +125,10 @@ def sleep_pattern(instances):
|
||||||
|
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['hovermode'] = 'closest'
|
layout_args['hovermode'] = 'closest'
|
||||||
layout_args['title'] = '<b>Sleep Pattern</b>'
|
layout_args['title'] = _('<b>Sleep Pattern</b>')
|
||||||
layout_args['height'] = 800
|
layout_args['height'] = 800
|
||||||
|
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = _('Date')
|
||||||
layout_args['xaxis']['tickangle'] = -65
|
layout_args['xaxis']['tickangle'] = -65
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ def sleep_pattern(instances):
|
||||||
for i in range(30, 60*24, 30):
|
for i in range(30, 60*24, 30):
|
||||||
ticks[i] = (start + timezone.timedelta(minutes=i)).strftime('%I:%M %p')
|
ticks[i] = (start + timezone.timedelta(minutes=i)).strftime('%I:%M %p')
|
||||||
|
|
||||||
layout_args['yaxis']['title'] = 'Time of day'
|
layout_args['yaxis']['title'] = _('Time of day')
|
||||||
layout_args['yaxis']['rangemode'] = 'tozero'
|
layout_args['yaxis']['rangemode'] = 'tozero'
|
||||||
layout_args['yaxis']['tickmode'] = 'array'
|
layout_args['yaxis']['tickmode'] = 'array'
|
||||||
layout_args['yaxis']['tickvals'] = list(ticks.keys())
|
layout_args['yaxis']['tickvals'] = list(ticks.keys())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
@ -36,7 +37,7 @@ def sleep_totals(instances):
|
||||||
totals[start.date()] += instance.duration
|
totals[start.date()] += instance.duration
|
||||||
|
|
||||||
trace = go.Bar(
|
trace = go.Bar(
|
||||||
name='Total sleep',
|
name=_('Total sleep'),
|
||||||
x=list(totals.keys()),
|
x=list(totals.keys()),
|
||||||
y=[td.seconds/3600 for td in totals.values()],
|
y=[td.seconds/3600 for td in totals.values()],
|
||||||
hoverinfo='text',
|
hoverinfo='text',
|
||||||
|
@ -46,10 +47,10 @@ def sleep_totals(instances):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['title'] = '<b>Sleep Totals</b>'
|
layout_args['title'] = _('<b>Sleep Totals</b>')
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = _('Date')
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Hours of sleep'
|
layout_args['yaxis']['title'] = _('Hours of sleep')
|
||||||
|
|
||||||
fig = go.Figure({
|
fig = go.Figure({
|
||||||
'data': [trace],
|
'data': [trace],
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ def weight_weight(objects):
|
||||||
objects = objects.order_by('-date')
|
objects = objects.order_by('-date')
|
||||||
|
|
||||||
trace = go.Scatter(
|
trace = go.Scatter(
|
||||||
name='Weight',
|
name=_('Weight'),
|
||||||
x=list(objects.values_list('date', flat=True)),
|
x=list(objects.values_list('date', flat=True)),
|
||||||
y=list(objects.values_list('weight', flat=True)),
|
y=list(objects.values_list('weight', flat=True)),
|
||||||
fill='tozeroy',
|
fill='tozeroy',
|
||||||
|
@ -22,10 +24,10 @@ def weight_weight(objects):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['title'] = '<b>Weight</b>'
|
layout_args['title'] = _('<b>Weight</b>')
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = _('Date')
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Weight'
|
layout_args['yaxis']['title'] = _('Weight')
|
||||||
|
|
||||||
fig = go.Figure({
|
fig = go.Figure({
|
||||||
'data': [trace],
|
'data': [trace],
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Diaper Lifetimes - {{ object }}{% endblock %}
|
{% block title %}{% trans "Diaper Lifetimes" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Diaper Lifetimes</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Diaper Lifetimes" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Diaper Change Types - {{ object }}{% endblock %}
|
{% block title %}{% trans "Diaper Change Types" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Diaper Types</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Diaper Change Types" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Average Feeding Durations - {{ object }}{% endblock %}
|
{% block title %}{% trans "Average Feeding Durations" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Average Feeding Durations</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Average Feeding Durations" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load static %}
|
{% load i18n static %}
|
||||||
|
|
||||||
{% block title %}{% endblock %}
|
{% block title %}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">Children</a></li>
|
<li class="breadcrumb-item"><a href="{% url 'core:child-list' %}">{% trans "Children" %}</a></li>
|
||||||
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
<li class="breadcrumb-item font-weight-bold"><a href="{% url 'core:child' object.slug %}">{{ object }}</a></li>
|
||||||
<li class="breadcrumb-item">Reports</li>
|
<li class="breadcrumb-item">{% trans "Reports" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="jumbotron text-center">
|
<div class="jumbotron text-center">
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
There is no enough data to generate this report.
|
{% trans "There is no enough data to generate this report." %}
|
||||||
<i class="icon icon-sad" aria-hidden="true"></i>
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Sleep Patterns - {{ object }}{% endblock %}
|
{% block title %}{% trans "Sleep Pattern" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Sleep Pattern</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Sleep Pattern" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Sleep Totals - {{ object }}{% endblock %}
|
{% block title %}{% trans "Sleep Totals" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Sleep Totals</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Sleep Totals" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{% extends 'reports/report_base.html' %}
|
{% extends 'reports/report_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
{% block title %}Weight - {{ object }}{% endblock %}
|
{% block title %}{% trans "Weight" %} - {{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<li class="breadcrumb-item active" aria-current="page">Weight</li>
|
<li class="breadcrumb-item active" aria-current="page">{% trans "Weight" %}</li>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
Loading…
Reference in New Issue