...
 
Commits (11)
......@@ -3,7 +3,11 @@ coverage==4.4.1
Django==1.11
django-appconf==1.0.2
django-avatar==4.1.0
django-blog==1.3.post0
django-bootstrap-form==3.4
django-bootstrap3==10.0.1
django-cors-headers==2.2.0
django-imagekit==4.0.2
django-jalali==2.4.6
django-jet==1.0.7
django-model-utils==3.1.2
......@@ -13,8 +17,17 @@ django-widget-tweaks==1.4.2
djangorestframework==3.8.2
djangorestframework-jwt==1.11.0
jdatetime==2.0.0
Markdown==2.6.11
mysqlclient==1.3.12
nose==1.3.7
pilkit==2.0
Pillow==5.1.0
pinax-blog==7.0.4
pinax-images==3.0.1
pinax-messages==2.0.2
pinax-templates==2.0.1
Pygments==2.2.0
PyJWT==1.6.1
python-creole==1.3.2
pytz==2018.4
six==1.11.0
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-05-29 07:36
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
import django_jalali.db.models
class Migration(migrations.Migration):
dependencies = [
('body', '0005_auto_20180527_0428'),
]
operations = [
migrations.RemoveField(
model_name='drug',
name='description',
),
migrations.AddField(
model_name='drug',
name='atcـcode',
field=models.CharField(default=django.utils.timezone.now, max_length=255, verbose_name='دسته دارو'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='date',
field=django_jalali.db.models.jDateTimeField(null=True, verbose_name='تاریخ ایجاد'),
),
migrations.AddField(
model_name='drug',
name='dosage_form',
field=models.CharField(default='none', max_length=255, verbose_name='شکل دارویی'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='ingredient',
field=models.CharField(default='', max_length=255, verbose_name='ترکیبات'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='remarks',
field=models.CharField(default='', max_length=255, verbose_name='توضیحات'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='route_of_admin',
field=models.CharField(default='', max_length=255, verbose_name='راه مصرف'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='salt',
field=models.CharField(default='', max_length=255, verbose_name='ملح'),
preserve_default=False,
),
migrations.AddField(
model_name='drug',
name='strengh',
field=models.CharField(default='', max_length=255, verbose_name='مقدار دارو'),
preserve_default=False,
),
migrations.AlterField(
model_name='drug',
name='name',
field=models.CharField(max_length=255, verbose_name='نام دارو'),
),
]
......@@ -22,8 +22,15 @@ class Weight(models.Model):
return smart_unicode(self.text)
class Drug(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
description = models.CharField(max_length=255)
name = models.CharField(_("نام دارو"), max_length=255)
salt = models.CharField(_("ملح"), max_length=255)
dosage_form = models.CharField(_("شکل دارویی"), max_length=255)
strengh = models.CharField(_("مقدار دارو"), max_length=255)
route_of_admin = models.CharField(_("راه مصرف"), max_length=255)
atcـcode = models.CharField(_("دسته دارو"), max_length=255)
ingredient = models.CharField(_("ترکیبات"), max_length=255)
remarks = models.CharField(_("توضیحات"), max_length=255)
date = jmodels.jDateTimeField(_("تاریخ ایجاد"), null=True)
# add user activity level table to database
class UserActivity(models.Model):
......
This diff is collapsed.
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__) # noqa
import pkg_resources
default_app_config = "pinax.messages.apps.AppConfig"
__version__ = pkg_resources.get_distribution("pinax-messages").version
from django.contrib import admin
from .models import Message, UserThread
class UserThreadAdmin(admin.ModelAdmin):
list_display = ["thread", "user", "unread", "deleted"]
list_filter = ["unread", "deleted"]
raw_id_fields = ["user"]
class MessageAdmin(admin.ModelAdmin):
list_display = ["thread", "sender", "sent_at"]
list_filter = ["sent_at", "thread"]
raw_id_fields = ["sender"]
admin.site.register(Message, MessageAdmin)
admin.site.register(UserThread, UserThreadAdmin)
from django.apps import AppConfig as BaseAppConfig
from django.utils.translation import ugettext_lazy as _
class AppConfig(BaseAppConfig):
name = "pinax.messages"
label = "pinax_messages"
verbose_name = _("Pinax Messages")
from __future__ import unicode_literals
import importlib
from django.conf import settings # noqa
from django.core.exceptions import ImproperlyConfigured
from appconf import AppConf
def load_path_attr(path):
i = path.rfind(".")
module, attr = path[:i], path[i + 1:]
try:
mod = importlib.import_module(module)
except ImportError as e:
raise ImproperlyConfigured("Error importing {0}: '{1}'".format(module, e))
try:
attr = getattr(mod, attr)
except AttributeError:
raise ImproperlyConfigured("Module '{0}' does not define a '{1}'".format(module, attr))
return attr
class PinaxMessagesAppConf(AppConf):
HOOKSET = "pinax.messages.hooks.DefaultHookSet"
def configure_hookset(self, value):
return load_path_attr(value)()
class Meta:
prefix = "pinax_messages"
from .models import Thread
def user_messages(request):
c = {}
if request.user.is_authenticated:
c["inbox_threads"] = Thread.inbox(request.user)
c["unread_threads"] = Thread.unread(request.user)
return c
from django import forms
from django.contrib.auth import get_user_model
from django.utils.translation import ugettext_lazy as _
from .hooks import hookset
from .models import Message
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return hookset.display_name(obj)
class UserModelMultipleChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return hookset.display_name(obj)
class NewMessageForm(forms.ModelForm):
subject = forms.CharField(label=_('موضوع'))
to_user = UserModelChoiceField(label=_('به '), queryset=get_user_model().objects.none())
content = forms.CharField(label=_('محتوا'), widget=forms.Textarea)
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super(NewMessageForm, self).__init__(*args, **kwargs)
self.fields["to_user"].queryset = hookset.get_user_choices(self.user)
if self.initial.get("to_user") is not None:
qs = self.fields["to_user"].queryset.filter(pk=self.initial["to_user"])
self.fields["to_user"].queryset = qs
def save(self, commit=True):
data = self.cleaned_data
return Message.new_message(
self.user, [data["to_user"]], data["subject"], data["content"]
)
class Meta:
model = Message
fields = ["to_user", "subject", "content"]
class NewMessageFormMultiple(forms.ModelForm):
subject = forms.CharField()
to_user = UserModelMultipleChoiceField(get_user_model().objects.none())
content = forms.CharField(widget=forms.Textarea)
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super(NewMessageFormMultiple, self).__init__(*args, **kwargs)
self.fields["to_user"].queryset = hookset.get_user_choices(self.user)
if self.initial.get("to_user") is not None:
qs = self.fields["to_user"].queryset.filter(pk__in=self.initial["to_user"])
self.fields["to_user"].queryset = qs
def save(self, commit=True):
data = self.cleaned_data
return Message.new_message(
self.user, data["to_user"], data["subject"], data["content"]
)
class Meta:
model = Message
fields = ["to_user", "subject", "content"]
class MessageReplyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.thread = kwargs.pop("thread")
self.user = kwargs.pop("user")
super(MessageReplyForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
return Message.new_reply(
self.thread, self.user, self.cleaned_data["content"]
)
class Meta:
model = Message
fields = ["content"]
from django.contrib.auth import get_user_model
class DefaultHookSet(object):
def display_name(self, user):
return str(user)
def get_user_choices(self, user):
return get_user_model().objects.exclude(id=user.id)
class HookProxy(object):
_settings = None
def load_settings(self):
if self._settings is None:
from .conf import settings
self._settings = settings
def __getattr__(self, attr):
self.load_settings()
return getattr(self._settings.PINAX_MESSAGES_HOOKSET, attr)
hookset = HookProxy()
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Message',
fields=[
('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
('sent_at', models.DateTimeField(default=django.utils.timezone.now)),
('content', models.TextField()),
('sender', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='sent_messages', on_delete=models.CASCADE)),
],
options={
'ordering': ('sent_at',),
},
),
migrations.CreateModel(
name='Thread',
fields=[
('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
('subject', models.CharField(max_length=150)),
],
),
migrations.CreateModel(
name='UserThread',
fields=[
('id', models.AutoField(auto_created=True, serialize=False, verbose_name='ID', primary_key=True)),
('unread', models.BooleanField()),
('deleted', models.BooleanField()),
('thread', models.ForeignKey(to='pinax_messages.Thread', on_delete=models.CASCADE)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
],
),
migrations.AddField(
model_name='thread',
name='users',
field=models.ManyToManyField(through='pinax_messages.UserThread', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='message',
name='thread',
field=models.ForeignKey(to='pinax_messages.Thread', related_name='messages', on_delete=models.CASCADE),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-06-05 11:22
from __future__ import unicode_literals
from django.db import migrations
import django_jalali.db.models
class Migration(migrations.Migration):
dependencies = [
('pinax_messages', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='message',
name='sent_at',
field=django_jalali.db.models.jDateTimeField(blank=True, editable=False, verbose_name='تاریخ ارسال'),
),
]
from __future__ import unicode_literals
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from .signals import message_sent
from .utils import cached_attribute
from django_jalali.db import models as jmodels
@python_2_unicode_compatible
class Thread(models.Model):
subject = models.CharField(max_length=150)
users = models.ManyToManyField(settings.AUTH_USER_MODEL, through="UserThread")
@classmethod
def inbox(cls, user):
return cls.objects.filter(userthread__user=user, userthread__deleted=False)
@classmethod
def deleted(cls, user):
return cls.objects.filter(userthread__user=user, userthread__deleted=True)
@classmethod
def unread(cls, user):
return cls.objects.filter(
userthread__user=user,
userthread__deleted=False,
userthread__unread=True
)
def __str__(self):
return "{}: {}".format(
self.subject,
", ".join([str(user) for user in self.users.all()])
)
def get_absolute_url(self):
return reverse("pinax_messages:thread_detail", args=[self.pk])
@property
@cached_attribute
def first_message(self):
return self.messages.all()[0]
@property
@cached_attribute
def latest_message(self):
return self.messages.order_by("-sent_at")[0]
@classmethod
def ordered(cls, objs):
"""
Returns the iterable ordered the correct way, this is a class method
because we don"t know what the type of the iterable will be.
"""
objs = list(objs)
objs.sort(key=lambda o: o.latest_message.sent_at, reverse=True)
return objs
class UserThread(models.Model):
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
unread = models.BooleanField()
deleted = models.BooleanField()
class Message(models.Model):
thread = models.ForeignKey(Thread, related_name="messages", on_delete=models.CASCADE)
sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="sent_messages", on_delete=models.CASCADE)
sent_at = jmodels.jDateTimeField(_("تاریخ ارسال"), auto_now_add=True)
content = models.TextField()
@classmethod
def new_reply(cls, thread, user, content):
"""
Create a new reply for an existing Thread.
Mark thread as unread for all other participants, and
mark thread as read by replier.
"""
msg = cls.objects.create(thread=thread, sender=user, content=content)
thread.userthread_set.exclude(user=user).update(deleted=False, unread=True)
thread.userthread_set.filter(user=user).update(deleted=False, unread=False)
message_sent.send(sender=cls, message=msg, thread=thread, reply=True)
return msg
@classmethod
def new_message(cls, from_user, to_users, subject, content):
"""
Create a new Message and Thread.
Mark thread as unread for all recipients, and
mark thread as read and deleted from inbox by creator.
"""
thread = Thread.objects.create(subject=subject)
for user in to_users:
thread.userthread_set.create(user=user, deleted=False, unread=True)
thread.userthread_set.create(user=from_user, deleted=True, unread=False)
msg = cls.objects.create(thread=thread, sender=from_user, content=content)
message_sent.send(sender=cls, message=msg, thread=thread, reply=False)
return msg
class Meta:
ordering = ("sent_at",)
def get_absolute_url(self):
return self.thread.get_absolute_url()
from django.dispatch import Signal
message_sent = Signal(providing_args=["message", "thread", "reply"])
from django import template
from pinax.messages.models import Thread
register = template.Library()
@register.filter
def unread(thread, user):
"""
Check whether there are any unread messages for a particular thread for a user.
"""
return bool(thread.userthread_set.filter(user=user, unread=True))
@register.filter
def unread_thread_count(user):
"""
Return the number of Threads with unread messages for this user, useful for highlighting on an account bar for example.
"""
return Thread.unread(user).count()
from test_plus.test import TestCase as PlusTestCase
class TestCase(PlusTestCase):
pass
This diff is collapsed.
from django.conf.urls import include, url
urlpatterns = [
url(r"^", include("pinax.messages.urls", namespace="pinax_messages")),
]
from django.conf.urls import url
from . import views
app_name = "pinax_messages"
urlpatterns = [
url(r"^inbox/$", views.InboxView.as_view(),
name="inbox"),
url(r"^create/$", views.MessageCreateView.as_view(),
name="message_create"),
url(r"^create/(?P<user_id>\d+)/$", views.MessageCreateView.as_view(),
name="message_user_create"),
url(r"^thread/(?P<pk>\d+)/$", views.ThreadView.as_view(),
name="thread_detail"),
url(r"^thread/(?P<pk>\d+)/delete/$", views.ThreadDeleteView.as_view(),
name="thread_delete"),
]
from functools import wraps
def cached_attribute(func):
cache_name = "_%s" % func.__name__
@wraps(func)
def inner(self, *args, **kwargs):
if hasattr(self, cache_name):
return getattr(self, cache_name)
val = func(self, *args, **kwargs)
setattr(self, cache_name, val)
return val
return inner
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.generic import (
CreateView,
DeleteView,
TemplateView,
UpdateView
)
from .forms import MessageReplyForm, NewMessageForm, NewMessageFormMultiple
from .models import Thread
try:
from account.decorators import login_required
except: # noqa
from django.contrib.auth.decorators import login_required
class InboxView(TemplateView):
"""
View inbox thread list.
"""
template_name = "pinax/messages/inbox.html"
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(InboxView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(InboxView, self).get_context_data(**kwargs)
if self.kwargs.get("deleted", None):
threads = Thread.ordered(Thread.deleted(self.request.user))
folder = "deleted"
else:
threads = Thread.ordered(Thread.inbox(self.request.user))
folder = "inbox"
context.update({
"folder": folder,
"threads": threads,
"threads_unread": Thread.ordered(Thread.unread(self.request.user))
})
return context
class ThreadView(UpdateView):
"""
View a single Thread or POST a reply.
"""
model = Thread
form_class = MessageReplyForm
context_object_name = "thread"
template_name = "pinax/messages/thread_detail.html"
success_url = reverse_lazy("pinax_messages:inbox")
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ThreadView, self).dispatch(*args, **kwargs)
def get_queryset(self):
qs = super(ThreadView, self).get_queryset()
qs = qs.filter(userthread__user=self.request.user).distinct()
return qs
def get_form_kwargs(self):
kwargs = super(ThreadView, self).get_form_kwargs()
kwargs.update({
"user": self.request.user,
"thread": self.object
})
return kwargs
def get(self, request, *args, **kwargs):
response = super(ThreadView, self).get(request, *args, **kwargs)
self.object.userthread_set.filter(user=request.user).update(unread=False)
return response
class MessageCreateView(CreateView):
"""
Create a new thread message.
"""
template_name = "pinax/messages/message_create.html"
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(MessageCreateView, self).dispatch(*args, **kwargs)
def get_form_class(self):
if self.form_class is None:
if self.kwargs.get("multiple", False):
return NewMessageFormMultiple
return NewMessageForm
def get_initial(self):
user_id = self.kwargs.get("user_id", None)
if user_id is not None:
user_id = [int(user_id)]
elif "to_user" in self.request.GET and self.request.GET["to_user"].isdigit():
user_id = map(int, self.request.GET.getlist("to_user"))
if not self.kwargs.get("multiple", False) and user_id:
user_id = user_id[0]
return {"to_user": user_id}
def get_form_kwargs(self):
kwargs = super(MessageCreateView, self).get_form_kwargs()
kwargs.update({
"user": self.request.user,
})
return kwargs
class ThreadDeleteView(DeleteView):
"""
Delete a thread.
"""
model = Thread
success_url = reverse_lazy("pinax_messages:inbox")
template_name = "pinax/messages/thread_confirm_delete.html"
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ThreadDeleteView, self).dispatch(*args, **kwargs)
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
success_url = self.get_success_url()
self.object.userthread_set.filter(user=request.user).update(deleted=True)
return HttpResponseRedirect(success_url)
......@@ -13,8 +13,25 @@
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
body{
@font-face {
font-family: Sahel;
src: url("../fonts/Sahel-FD.eot");
src: url("../fonts/Sahel-FD.eot?#iefix") format("embedded-opentype"), url("../fonts/Sahel-FD.woff") format("woff"), url("../fonts/Sahel-FD.ttf") format("truetype");
font-weight: normal; }
@font-face {
font-family: Sahel;
src: url("../fonts/Sahel-Bold-FD.eot");
src: url("../fonts/Sahel-Bold-FD.eot?#iefix") format("embedded-opentype"), url("../fonts/Sahel-Bold-FD.woff") format("woff"), url("../fonts/Sahel-Bold-FD.ttf") format("truetype");
font-weight: bold; }
@font-face {
font-family: Sahel;
src: url("../fonts/Sahel-Black-FD.eot");
src: url("../fonts/Sahel-Black-FD.eot?#iefix") format("embedded-opentype"), url("../fonts/Sahel-Black-FD.woff") format("woff"), url("../fonts/Sahel-Black-FD.ttf") format("truetype");
font-weight: 900; }
body {
font-family: 'Sahel' !important;
}
.form-control::-moz-placeholder{
color: #DDDDDD;
......@@ -968,4 +985,4 @@ h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small {
#pb-modalreglog-progressbar
{
border-radius: 2px;
}
\ No newline at end of file
}
......@@ -6,7 +6,17 @@ body, html {
/**
* Profile image component
*/
.profile-header-container{
.card {
margin: 0 auto; /* Added */
float: none; /* Added */
margin-bottom: 10px; /* Added */
}
div.a {
text-align: center;
}
.profile-header-container{
margin: 0 auto;
text-align: center;
}
......
This diff is collapsed.
......@@ -15,8 +15,9 @@ urlpatterns = [
# The home page
url(r'^$', views.index, name='index'),
url(r'^weight/list$', views.WeightList.as_view(), name='weights_list'),
url(r'^users/list$', views.UserList.as_view(), name='users_list'),
url(r'^home/$', views.HomeView.as_view(), name='dashboard'),
url(r'^profile/$', views.ProfileView.as_view(), name='profile'),
url(r'^profile/(?P<pk>[\w]+)/$', views.ProfileView.as_view(), name='profile'),
url(r'^profile/edit/(?P<pk>[\w]+)/$', views.ProfileUpdate.as_view(), name='profile_edit'),
url(r'^rx/$', views.RxView.as_view(), name='rx'),
url(r'^goal/$', views.GoalView.as_view(), name='goal'),
......
......@@ -13,8 +13,9 @@ from users.models import User
from jdatetime import date
from django.utils.decorators import method_decorator
from django.core.urlresolvers import reverse_lazy
from django.contrib.admin.views.decorators import staff_member_required
from pinax.messages.models import Thread
from pinax.messages.forms import Message
......@@ -29,10 +30,30 @@ def index(request):
def dispatch(self, *args, **kwargs):
return super(InboxView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super(InboxView, self).get_context_data(**kwargs)
if self.kwargs.get("deleted", None):
threads = Thread.ordered(Thread.deleted(self.request.user))
folder = "deleted"
else:
threads = Thread.ordered(Thread.inbox(self.request.user))
folder = "inbox"
context.update({
"folder": folder,
"threads": threads,
"threads_unread": Thread.ordered(Thread.unread(self.request.user))
})
return context
@method_decorator(login_required, name='dispatch')
class HomeView(TemplateView):
template_name = 'sites/dashboard.html'
def get_queryset(self):
return self.model.objects.filter(user=self.request.user)
......@@ -40,6 +61,9 @@ class HomeView(TemplateView):
def get_context_data(self, **kwargs):
dataset = {}
dataset = []
threads = Thread.ordered(Thread.inbox(self.request.user))
folder = "inbox"
# Iterate through the data in `Revenue` model and insert in to the `dataSource['data']` list.
for key in Weight.objects.filter(user=self.request.user):
data = {}
......@@ -48,12 +72,20 @@ class HomeView(TemplateView):
dataset.append(data)
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
context.update({
"folder": folder,
"threads": threads,
"threads_unread": Thread.ordered(Thread.unread(self.request.user))
})
context['dataset'] = dataset
return context
@method_decorator(login_required, name='dispatch')
class ProfileView(TemplateView):
class ProfileView(DetailView):
model = User
template_name = 'sites/profile.html'
@method_decorator(login_required, name='dispatch')
......@@ -83,15 +115,16 @@ class GoalView(TemplateView):
@method_decorator(login_required, name='dispatch')
class DrugView(TemplateView):
template_name = 'sites/drug.html'
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
rxs = Rx.objects.all()
rxs = Rx.objects.filter(user = self.request.user)
if rxs:
lastrx = rxs.reverse()[0]
drug = rxs.drugs
else:
lastrx = 'none'
context['lastrx'] = lastrx
drug = 'none'
context['drug'] = drug
return context
......@@ -268,3 +301,12 @@ class ProfileUpdate(UpdateView):
self.object.save()
return super(ProfileUpdate, self).form_valid(form)
@method_decorator(staff_member_required, name='dispatch')
class UserList(ListView):
model = User
\ No newline at end of file
This diff is collapsed.
......@@ -54,6 +54,8 @@ INSTALLED_APPS = [
'django_nose',
'avatar',
'django_jalali',
"pinax.messages",
'bootstrap3',
]
JWT_AUTH = {
......@@ -91,6 +93,7 @@ TEMPLATES = [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'pinax.messages.context_processors.user_messages',
],
},
},
......@@ -151,7 +154,7 @@ CORS_ORIGIN_ALLOW_ALL=True
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'fa-ir'
TIME_ZONE = 'Asia/Tehran'
......@@ -184,4 +187,4 @@ DATE_INPUT_FORMATS = [
'%Y-%m-%d', # '2006-10-25'
'%m/%d/%Y', # '10/25/2006'
'%m/%d/%y' # '10/25/06'
]
\ No newline at end of file
]
\ No newline at end of file
......@@ -8,6 +8,7 @@ api_urls = [
]
urlpatterns = [
url(r"^messages/", include("pinax.messages.urls", namespace="pinax_messages")),
url('', include('django.contrib.auth.urls')),
url(r'^avatar/', include('avatar.urls')),
url(r'^',include('sites.urls')),
......
......@@ -14,7 +14,7 @@
{% block content %}
<div class="container-fluid">
<div class="col-sm-6 col-md-4">
<div class="col-sm-6 col-md-4 offset-sm-4">
<div class="card">
<div class="card-header">
جزئیات
......
......@@ -31,7 +31,7 @@
{% block content %}
<div class="row">
<div class="col-md-3">
<div class="col-md-4 offset-sm-4">
<div class="card">
<div class="card-header">
{% if object_list %}
......@@ -66,7 +66,7 @@
</div>
</div>
<!-- /.conainer-fluid -->
{% endblock content %}
{% block javascripts %}
{{ block.super }}
......
......@@ -40,10 +40,14 @@
</br>
کالری مورد نیاز روزانه جهت کم کردن 1 کیلوگرم در هفته : {{ wlbmr_one }}
</div>
{% else %}
{% elif bmi < 25 and bmi > 19 %}
<div class="alert alert-success" role="alert">
شما در وضعیت مطلوبی قرار دارید
</div>
{% else %}
<div class="alert alert-success" role="alert">
هرچه زودتر نسبت به تکمیل پروفایل و افزودن وزن اقدام کنید
</div>
{% endif %}
<div class="container-fluid">
......
{% extends "site_base.html" %}
{% block body_class %}pinax-messages{% endblock %}
{% extends "../../sites/base_site.html" %}
{% load i18n %}
{% load pinax_messages_tags %}
{% block title %} صندوق ورودی {% endblock title %}
​{% block stylesheets %}
{{ block.super }}
{% endblock stylesheets %}
{% block location %}
صندوق ورودی
{% endblock location %}
{% block content %}
<div class="container-fluid">
<div class="list-group">
<section class="actions-header">
<div class="row">
<h1>صندوق ورودی</h1>
<div class="col-sm-12">
<a class="btn btn-success pull-right" href="{% url "pinax_messages:message_create" %}">پیام جدید</a>
</div>
</div>
</section>
<section class="mailbox">
{% for thread in threads %}
<div class="thread {% if thread|unread:user %}unread{% endif %}">
<a class="list-group-item" href="{{thread.get_absolute_url}}" >
<div class="row">
<span class="col-sm-2 users">{{ thread.users.all|join:", " }}</span>
<div class="col-sm-10">
<p class="subject">{{ thread.subject }}</p>
<p class="content text-muted">{{ thread.latest_message.content }}</p>
</div>
</div>
</a>
</div>
{% empty %}
<div>You have no messages.</div>
{% endfor %}
</section>
</div>
</div>
{% endblock content %}
{% block javascripts %}
{{ block.super }}
{% endblock javascripts %}
\ No newline at end of file
{% extends "../../sites/base_site.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load pinax_messages_tags %}
{% block title %} پیام جدید {% endblock title %}
​{% block stylesheets %}
{{ block.super }}
{% endblock stylesheets %}
{% block location %}
پیام جدید
{% endblock location %}
{% block content %}
<div class="container-fluid">
<h2>پیام جدید</h2>
<section>
<form class="comment-form" action="{% url "pinax_messages:message_create" %}" method="post">
{% csrf_token %}
<div class="col-sm-5">
{% bootstrap_form form %}
<button class="btn btn-primary pull-right">ارسال</button>
</form>
<a class="btn btn-default" href="{% url "pinax_messages:inbox" %}">لغو</a>
</div>
</section>
{% endblock %}
\ No newline at end of file
{% extends "../../sites/base_site.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load pinax_messages_tags %}
{% block title %} مکالمه {% endblock title %}
​{% block stylesheets %}
{{ block.super }}
<style type="text/css">
body {
font-family: 'Varela Round', sans-serif;
}
.modal-confirm {
color: #636363;
width: 400px;
}
.modal-confirm .modal-content {
padding: 20px;
border-radius: 5px;
border: none;
text-align: center;
font-size: 14px;
}
.modal-confirm .modal-header {
border-bottom: none;
position: relative;
}
.modal-confirm h4 {
text-align: center;
font-size: 26px;
margin: 30px 0 -10px;
}
.modal-confirm .close {
position: absolute;
top: -5px;
right: -2px;
}
.modal-confirm .modal-body {
color: #999;
}
.modal-confirm .modal-footer {
border: none;
text-align: center;
border-radius: 5px;
font-size: 13px;
padding: 10px 15px 25px;
}
.modal-confirm .modal-footer a {
color: #999;
}
.modal-confirm .icon-box {
width: 80px;
height: 80px;
margin: 0 auto;
border-radius: 50%;
z-index: 9;
text-align: center;
border: 3px solid #f15e5e;
}
.modal-confirm .icon-box i {
color: #f15e5e;
font-size: 46px;
display: inline-block;
margin-top: 13px;
}
.modal-confirm .btn {
color: #fff;
border-radius: 4px;
background: #60c7c1;
text-decoration: none;
transition: all 0.4s;
line-height: normal;
min-width: 120px;
border: none;
min-height: 40px;
border-radius: 3px;
margin: 0 5px;
outline: none !important;
}
.modal-confirm .btn-info {
background: #c1c1c1;
}
.modal-confirm .btn-info:hover, .modal-confirm .btn-info:focus {
background: #a8a8a8;
}
.modal-confirm .btn-danger {
background: #f15e5e;
}
.modal-confirm .btn-danger:hover, .modal-confirm .btn-danger:focus {
background: #ee3535;
}
.trigger-btn {
display: inline-block;
margin: 100px auto;
}
</style>
{% endblock stylesheets %}
{% block location %}
مکالمه
{% endblock location %}
{% block content %}
<div class="container-fluid">
<div class="pinax-messages-thread-detail-container">
<h3 href="#myModal" class="with-actions">{{ thread.subject }}
<a href="#myModal" class="trigger-btn" data-toggle="modal"><i class="far fa-trash-alt"></i> حذف مکالمه</a>
</h3>
<section class="thread-messages">
{% for message in thread.messages.all %}
<div class="thread-message">
<div class="message-byline">
<div class="message-from">{{ message.sender.username }}</div>
<div class="message-sent">{{ message.sent_at }}</div>
</div>
<div class="message-content">{{ message.content|urlize|linebreaks }}</div>
</div>
{% endfor %}
</section>
<form class="comment-form" action="{% url "pinax_messages:thread_detail" thread.pk %}" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-actions">
<a href="{% url "pinax_messages:inbox" %}" class="cancel">لغو</a>
<button>ارسال</button>
</div>
</form>
</div>
<div id="myModal" class="modal fade">
<div class="modal-dialog modal-confirm">
<div class="modal-content">
<div class="modal-header">
<div class="icon-box">
<i class="far fa-trash-alt"></i>
</div>
<h4 class="modal-title">اطمینان دارید؟</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<p>از پاک کردن این مکالمه اطمینان دارید؟</p>
<p>{% url "pinax_messages:thread_delete" thread.pk as post_url %}</p>
</div>
<div class="modal-footer">
<form action="{{ post_url }}" method="POST" class="form form-horizontal">
{% csrf_token %}
<div class="form-actions">
<button type="button" class="btn btn-info" data-dismiss="modal">لغو</button>
<button type="submit" class="btn btn-danger">{% trans "Delete" %}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block javascripts %}
{{ block.super }}
{% endblock javascripts %}
{% load avatar_tags %}
{% load static %}
{% load i18n %}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>
{% block title %}
{% endblock title %}
</title>
<!-- Bootstrap core CSS -->
<link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet">
<link href="{% static "css/bootstrap-rtl.css" %}" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="{% static "css/blog-home.css" %}" rel="stylesheet">
</head>
{% block body %}
<body>
{% block top_navigation %}
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
<div class="container">
<a class="navbar-brand" href="#">تنباما</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">خانه
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">درباره</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Services</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">تماس</a>
</li>
</ul>
</div>
</div>
</nav>
{% endblock top_navigation %}
<!-- Page Content -->
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-8">
{% block content %}
{% endblock content %}
<!-- Pagination -->
<ul class="pagination justify-content-center mb-4">
<li class="page-item">
<a class="page-link" href="#">&larr; Older</a>
</li>
<li class="page-item disabled">
<a class="page-link" href="#">Newer &rarr;</a>
</li>
</ul>
</div>
<!-- Sidebar Widgets Column -->
<div class="col-md-4">
{% block sidebar %}
{% endblock sidebar %}
<!-- Search Widget -->
<div class="card my-4">
<h5 class="card-header">Search</h5>
<div class="card-body">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
</div>
</div>
</div>
<!-- Categories Widget -->
<div class="card my-4">
<h5 class="card-header">Categories</h5>
<div class="card-body">
<div class="row">
<div class="col-lg-6">
<ul class="list-unstyled mb-0">
<li>
<a href="#">Web Design</a>
</li>
<li>
<a href="#">HTML</a>
</li>
<li>
<a href="#">Freebies</a>
</li>
</ul>
</div>
<div class="col-lg-6">
<ul class="list-unstyled mb-0">
<li>
<a href="#">JavaScript</a>
</li>
<li>
<a href="#">CSS</a>
</li>
<li>
<a href="#">Tutorials</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Side Widget -->
<div class="card my-4">
<h5 class="card-header">Side Widget</h5>
<div class="card-body">
You can put anything you want inside of these side widgets. They are easy to use, and feature the new Bootstrap 4 card containers!
</div>
</div>
</div>
</div>
<!-- /.row -->
</div>
<!-- /.container -->
<!-- Footer -->
<footer class="py-5 bg-dark">
<div class="container">
{% block footer %}
{% endblock footer %}
<p class="m-0 text-center text-white"> Tanbama</p>
</div>
<!-- /.container -->
</footer>
{% block javascripts %}
<!-- Bootstrap core JavaScript -->
<script src="{% static "js/jquery.min.js" %}"></script>
<script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
{% endblock javascripts %}
</body>
{% endblock body %}
</html>
This diff is collapsed.
......@@ -15,10 +15,10 @@
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 col-lg-6">
<div class="col-sm-6 col-lg-6 offset-sm-3">
<div class="animated fadeIn">
{% if not request.user.is_staff %}
<div class="card">
<div class="card-header">
تغییرات وزن
......@@ -29,6 +29,7 @@
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
......