Merge branch 'add-common-events'

This commit is contained in:
Michael Hall 2018-03-22 00:15:34 -04:00
commit 84d500e106
19 changed files with 738 additions and 20 deletions

View file

@ -5,7 +5,7 @@ from django.utils.safestring import mark_safe
from .models.locale import Language, Continent, Country, SPR, City
from .models.profiles import UserProfile, Organization, Team, Member, Category, Topic
from .models.search import Searchable
from .models.events import Place, Event, EventPhoto, Attendee
from .models.events import Place, Event, EventPhoto, CommonEvent, Attendee
admin.site.register(Language)
admin.site.register(Continent)
@ -66,6 +66,15 @@ class EventPhotoAdmin(admin.ModelAdmin):
view.short_description = 'Photo'
admin.site.register(EventPhoto, EventPhotoAdmin)
class CommonEventAdmin(admin.ModelAdmin):
raw_id_fields = ('place', 'city', 'spr', 'country')
list_display = ('__str__', 'participant_count', 'organization', 'start_time', 'country', 'spr', 'city')
ordering = ('-start_time',)
def participant_count(self, event):
return event.participating_events.all().count()
participant_count.short_description = 'Participants'
admin.site.register(CommonEvent, CommonEventAdmin)
class MemberAdmin(admin.ModelAdmin):
list_display = ('__str__', 'role')
list_filter = ('role', 'team')

View file

@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from .models.profiles import Team, UserProfile
from .models.events import Event, Place, EventPhoto
from .models.events import Event, CommonEvent, Place, EventPhoto
from datetime import time
from time import strptime, strftime
@ -245,3 +245,33 @@ class SearchForm(forms.Form):
widgets ={
'city': Lookup(source='/api/cities/', label='name'),
}
class NewCommonEventForm(forms.ModelForm):
class Meta:
model = CommonEvent
fields = [
'name',
'start_time',
'end_time',
'summary',
'country',
'spr',
'city',
'place',
'web_url',
'announce_url',
'category',
'tags',
]
widgets ={
'country': Lookup(source='/api/countries/', label='name'),
'spr': Lookup(source='/api/spr/', label='name'),
'city': Lookup(source='/api/cities/', label='name'),
'place': Lookup(source='/api/places/', label='name'),
'start_time': DateTimeWidget,
'end_time': DateTimeWidget
}

View file

@ -0,0 +1,93 @@
# Generated by Django 2.0 on 2018-03-21 01:13
import datetime
from django.db import migrations, models
import django.db.models.deletion
import imagekit.models.fields
class Migration(migrations.Migration):
dependencies = [
('events', '0017_add_event_images'),
]
operations = [
migrations.CreateModel(
name='CommonEvent',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=150, verbose_name='Event Name')),
('start_time', models.DateTimeField(db_index=True, help_text='Local date and time that the event starts', verbose_name='Local Start Time')),
('end_time', models.DateTimeField(db_index=True, help_text='Local date and time that the event ends', verbose_name='Local End Time')),
('summary', models.TextField(blank=True, help_text='Summary of the Event', null=True)),
('web_url', models.URLField(blank=True, help_text='URL for the event', null=True, verbose_name='Website')),
('announce_url', models.URLField(blank=True, help_text='URL for the announcement', null=True, verbose_name='Announcement')),
('created_time', models.DateTimeField(db_index=True, default=datetime.datetime.now, help_text='the date and time when the event was created')),
('tags', models.CharField(blank=True, max_length=128, null=True, verbose_name='Keyword Tags')),
('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.Category')),
('city', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.City')),
('country', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.Country')),
],
),
migrations.AddField(
model_name='organization',
name='owner_profile',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='owned_orgs', to='events.UserProfile'),
),
migrations.AlterField(
model_name='eventphoto',
name='src',
field=models.ImageField(upload_to='event_photos', verbose_name='Photo'),
),
migrations.AlterField(
model_name='team',
name='organization',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='teams', to='events.Organization'),
),
migrations.AlterField(
model_name='team',
name='owner_profile',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_teams', to='events.UserProfile'),
),
migrations.AlterField(
model_name='userprofile',
name='avatar',
field=imagekit.models.fields.ProcessedImageField(blank=True, upload_to='avatars', verbose_name='Photo Image'),
),
migrations.AddField(
model_name='commonevent',
name='created_by',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.UserProfile'),
),
migrations.AddField(
model_name='commonevent',
name='organization',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='events.Organization'),
),
migrations.AddField(
model_name='commonevent',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sub_events', to='events.CommonEvent'),
),
migrations.AddField(
model_name='commonevent',
name='place',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.Place'),
),
migrations.AddField(
model_name='commonevent',
name='spr',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.SPR'),
),
migrations.AddField(
model_name='commonevent',
name='topics',
field=models.ManyToManyField(blank=True, to='events.Topic'),
),
migrations.AddField(
model_name='event',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='participating_events', to='events.CommonEvent'),
),
]

View file

@ -0,0 +1,19 @@
# Generated by Django 2.0 on 2018-03-22 03:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0018_add_common_events'),
]
operations = [
migrations.AddField(
model_name='organization',
name='slug',
field=models.CharField(default='slug_required', max_length=256),
preserve_default=False,
),
]

View file

@ -55,6 +55,7 @@ class PlaceSerializer(serializers.ModelSerializer):
class Event(models.Model):
name = models.CharField(max_length=150, verbose_name=_('Event Name'))
team = models.ForeignKey(Team, on_delete=models.CASCADE)
parent = models.ForeignKey('CommonEvent', related_name='participating_events', null=True, blank=True, on_delete=models.SET_NULL)
start_time = models.DateTimeField(help_text=_('Local date and time that the event starts'), verbose_name=_('Local Start Time'), db_index=True)
end_time = models.DateTimeField(help_text=_('Local date and time that the event ends'), verbose_name=_('Local End Time'), db_index=True)
@ -196,3 +197,42 @@ class EventPhoto(models.Model):
processors=[ResizeToFill(250, 187)],
format='JPEG',
options={'quality': 60})
class CommonEvent(models.Model):
name = models.CharField(max_length=150, verbose_name=_('Event Name'))
organization = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE)
parent = models.ForeignKey('CommonEvent', related_name='sub_events', null=True, blank=True, on_delete=models.SET_NULL)
start_time = models.DateTimeField(help_text=_('Local date and time that the event starts'), verbose_name=_('Local Start Time'), db_index=True)
end_time = models.DateTimeField(help_text=_('Local date and time that the event ends'), verbose_name=_('Local End Time'), db_index=True)
summary = models.TextField(help_text=_('Summary of the Event'), blank=True, null=True)
country = models.ForeignKey(Country, null=True, blank=True, on_delete=models.SET_NULL)
spr = models.ForeignKey(SPR, null=True, blank=True, on_delete=models.SET_NULL)
city = models.ForeignKey(City, null=True, blank=True, on_delete=models.SET_NULL)
place = models.ForeignKey(Place, blank=True, null=True, on_delete=models.SET_NULL)
web_url = models.URLField(verbose_name=_('Website'), help_text=_('URL for the event'), max_length=200, blank=True, null=True)
announce_url = models.URLField(verbose_name=_('Announcement'), help_text=_('URL for the announcement'), max_length=200, blank=True, null=True)
created_by = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
created_time = models.DateTimeField(help_text=_('the date and time when the event was created'), default=datetime.datetime.now, db_index=True)
category = models.ForeignKey('Category', on_delete=models.SET_NULL, blank=False, null=True)
topics = models.ManyToManyField('Topic', blank=True)
tags = models.CharField(verbose_name=_("Keyword Tags"), blank=True, null=True, max_length=128)
def get_absolute_url(self):
return reverse('show-common-event', kwargs={'event_id': self.id, 'event_slug': self.slug})
def get_full_url(self):
site = self.organization.site
return "https://%s%s" % (site.domain, self.get_absolute_url())
@property
def slug(self):
return slugify(self.name)
def __str__(self):
return self.name

View file

@ -107,6 +107,18 @@ class UserProfile(models.Model):
return True
return False
def can_create_common_event(self, org):
try:
if self.user.is_superuser:
return True
except:
return False
if not self.user_id:
return False
if org.owner_profile == self:
return True
return False
def can_edit_team(self, team):
try:
if self.user.is_superuser:
@ -154,14 +166,17 @@ AnonymousUser.profile = property(_getAnonProfile)
class Organization(models.Model):
name = models.CharField(max_length=256, null=False, blank=False)
slug = models.CharField(max_length=256, null=False, blank=False)
site = models.ForeignKey(Site, on_delete=models.CASCADE)
owner_profile = models.ForeignKey(UserProfile, related_name='owned_orgs', blank=False, null=True, on_delete=models.SET_NULL)
def __str__(self):
return u'%s' % (self.name)
class Team(models.Model):
name = models.CharField(_("Team Name"), max_length=256, null=False, blank=False)
organization = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE)
organization = models.ForeignKey(Organization, related_name='teams', null=True, blank=True, on_delete=models.CASCADE)
description = models.TextField(help_text=_('Team Description'), blank=True, null=True)
@ -174,7 +189,7 @@ class Team(models.Model):
created_date = models.DateField(_("Date Created"), null=True, blank=True)
owner_profile = models.ForeignKey(UserProfile, related_name='owner', null=True, on_delete=models.CASCADE)
owner_profile = models.ForeignKey(UserProfile, related_name='owned_teams', null=True, on_delete=models.CASCADE)
admin_profiles = models.ManyToManyField(UserProfile, related_name='admins', blank=True)
contact_profiles = models.ManyToManyField(UserProfile, related_name='contacts', blank=True)

View file

@ -124,7 +124,7 @@ form {
{% load flatpages %}
{% get_flatpages as flatpages %}
<footer class="footer">
<footer class="footer mt-3">
<div class="container">
<div class="row">
<div class="col">

View file

@ -6,8 +6,11 @@
{% block content %}
<h2>Plan a <strong>{{team.name}}</strong> get together</h2>
{% if event.parent %}<p class="text-muted">As part of <a href="{% url "show-common-event" event.parent.id event.parent.slug %}">{{ event.parent.name }}</a></p>{% endif %}
<form action="{% url "create-event" team.id%}" method="post">
{% csrf_token %}
{% if event.parent %}<<input type="hidden" name="common" value="{{event.parent.id}}" />{% endif %}
<div class="form-group">
{% include "events/event_form.html" %}
<br />

View file

@ -34,6 +34,11 @@
</div>
{% endfor %}
</div>
<div class="row">
<div class="col">
<br/><a href="{% url 'create-event-team-select' %}" class="btn btn-success">Plan a Get Together</a>
</div>
</div>
</div>
{% endblock %}

View file

@ -45,6 +45,11 @@
<p>{{ event.summary|markdown }}</p>
<table class="table">
{% if event.parent %}
<tr>
<td><b>Part of:</b></td><td><a href="{{ event.parent.get_absolute_url }}" target="_blank">{{ event.parent.name }}</a></td>
</tr>
{% endif %}
<tr>
<td><b>Time:</b></td><td>{{ event.start_time }} - {{ event.end_time }}</td>
</tr><tr>
@ -57,12 +62,12 @@
No place selected yet.
{% endif %}
</td>
</tr><tr>
{% if event.web_url %}
</tr><tr>
<td><b>Website:</b></td><td><a href="{{ event.web_url }}" target="_blank">{{ event.web_url }}</a></td>
{% endif %}
</tr>
{% if event.web_url %}
<tr>
<td><b>Website:</b></td><td><a href="{{ event.web_url }}" target="_blank">{{ event.web_url }}</a></td>
</tr>
{% endif %}
</table>
<br/>
<div class="container">

View file

@ -0,0 +1,99 @@
{% extends "get_together/base.html" %}
{% load static %}
{% block extra_google_analytics %}
gtag('config', '{{settings.GOOGLE_ANALYTICS_ID}}', {'page_path': '/org/+create-event/'});
{% endblock %}
{% block content %}
<h2>Plan a <strong>{{org.name}}</strong> event</h2>
<form action="{% url "create-common-event" org.slug%}" method="post">
{% csrf_token %}
<div class="form-group">
{% include "events/event_form.html" %}
<br />
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
{% endblock %}
{% block javascript %}
<script src="{% static 'js/jquery-ui-lookup.js' %}"></script>
<script type="text/javascript">
$(document).ready(function(){
$.datepicker.setDefaults({
showOn: 'focus',
dateFormat: 'yy-mm-dd',
});
$("#id_start_time_0").datepicker({altField: "#id_end_time_0", altFormat: "yy-mm-dd"});
$("#id_end_time_0").datepicker();
$("#country_select").lookup({
search: function(searchText, callback) {
if (searchText.length < 3) return callback(searchText, []);
$.getJSON("/api/countries/?q="+searchText, function(data) {
var m = this.url.match(/q=([^&]+)/);
var q = "";
if (m && m.length > 0) {
q = this.url.match(/q=([^&]+)/)[1]
}
return callback(q, data);
});
}
})
$("#spr_select").lookup({
search: function(searchText, callback) {
if (searchText.length < 3) return callback(searchText, []);
$.getJSON("/api/spr/?q="+searchText, function(data) {
var m = this.url.match(/q=([^&]+)/);
var q = "";
if (m && m.length > 0) {
q = this.url.match(/q=([^&]+)/)[1]
}
return callback(q, data);
});
}
})
$("#city_select").lookup({
search: function(searchText, callback) {
if (searchText.length < 3) return callback(searchText, []);
$.getJSON("/api/cities/?q="+searchText, function(data) {
var m = this.url.match(/q=([^&]+)/);
var q = "";
if (m && m.length > 0) {
q = this.url.match(/q=([^&]+)/)[1]
}
return callback(q, data);
});
}
})
$("#place_select").lookup({
search: function(searchText, callback) {
if (searchText.length < 3) return callback(searchText, []);
$.getJSON("/api/places/?q="+searchText, function(data) {
var m = this.url.match(/q=([^&]+)/);
var q = "";
if (m && m.length > 0) {
q = this.url.match(/q=([^&]+)/)[1]
}
return callback(q, data);
});
}
})
$("#id_category").selectmenu();
$("#id_tz").selectmenu();
});
</script>
{% endblock %}

View file

@ -0,0 +1,41 @@
{% extends "get_together/base.html" %}
{% load static %}
{% block styles %}
<link href="{% static 'css/bootstrap-album.css' %}" rel="stylesheet"/>
{% endblock %}
{% block content %}
<h2>Select which team:</h2>
<div class="container">
<div class="row">
{% for team in teams %}
<div class="col-md-4">
<div class="card mb-4 box-shadow">
<div class="card-banner">
<a href="{% url 'show-team' team.id %}">
{% if team.category %}
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
{% else %}
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
{% endif %}
</a>
<p class="card-title">{{team.name}}</p>
</div>
<div class="card-body">
<p class="card-text"><strong>{{team.city}}</strong></p>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">{{ team.members.count }} members</small>
<div class="btn-group">
<a class="btn btn-success" href="{% url 'create-event' team.id %}?common={{common_event_id}}">Host Event</a></span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,84 @@
{% extends "get_together/base.html" %}
{% load markup static %}
{% block add_to_totle %} | {{event.name}}{% endblock %}
{% block meta %}
<meta property="og:url" content="{{event.get_full_url}}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="{{event.name}}" />
<meta property="og:description" content="{{event.summary|jsencode}}" />
<meta property="og:image" content="{{event.category.img_url}}" />
<link rel="canonical" href="{{event.get_full_url}}">
{% endblock %}
{% block content %}
{% if settings.SOCIAL_AUTH_FACEBOOK_KEY %}
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '{{settings.SOCIAL_AUTH_FACEBOOK_KEY}}',
autoLogAppEvents : true,
xfbml : true,
version : 'v2.12'
});
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
function shareFacebook() {
FB.ui({
display: 'popup',
method: 'share',
href: '{{event.get_full_url}}',
quote: 'I\'m going to a Get Together!\n\n{{event.name|jsencode}}',
hashtag: '#gettogether',
summary: "Let's have a Get Together!"
}, function(response){});
}
</script>
{% endif %}
{% if settings.SOCIAL_AUTH_TWITTER_KEY %}
<script>window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));
</script>
{% endif %}
<h2>Announce your Get Together</h2>
<div class="layout">
<div class="row mt-3">
<div class="col">
{% if settings.SOCIAL_AUTH_FACEBOOK_KEY %}<a href="#" onClick="shareFacebook()"; class="btn btn-primary">Facebook</a>{% endif %}
{% if settings.SOCIAL_AUTH_TWITTER_KEY %}
<a class="btn btn-primary"
href="https://twitter.com/intent/tweet?text=I'm+going+to+a+get+together!%0D{{event.name|urlencode}}&original_referer={{event.get_full_url|urlencode}}&url={{event.get_full_url|urlencode}}&hashtags=gettogether"
data-size="large">
Twitter</a>
{% endif %}
</div>
<div class="col">
<a href="{{event.get_absolute_url}}" class="btn btn-secondary">Share later</a>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,111 @@
{% extends "get_together/base.html" %}
{% load markup static %}
{% block add_to_totle %} | {{common_event.name}}{% endblock %}
{% block meta %}
<meta property="og:url" content="{{common_event.get_full_url}}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="{{common_event.name}}" />
<meta property="og:description" content="{{common_event.summary}}" />
<meta property="og:image" content="{{common_event.category.img_url}}" />
{% endblock %}
{% block styles %}
<link href="{% static 'css/bootstrap-album.css' %}" rel="stylesheet"/>
<style>
.gt-profile {
position: relative;
}
.gt-profile .gt-profile-badges {
position: absolute;
top: 16px;
left: 6px;
}
.table td, .table th {
border-top: none;
}
</style>
{% endblock %}
{% block content %}
<div class="fluid-container">
<div class="row">
<div class="col-md-9">
<h2>{{ common_event.name }}
{% if can_edit_event %}
<a href="{% url 'edit-common-event' common_event.id %}" class="btn btn-secondary btn-sm">Edit Event</a>
{% endif %}
<a href="{% url 'share-common-event' common_event.id %}" class="btn btn-primary btn-sm">Share</a>
</h2><p class="text-muted">Organized by <a href="{% url "show-org" common_event.organization.slug %}">{{ common_event.organization.name }}</a></p><hr/>
<p>{{ common_event.summary|markdown }}</p>
<table class="table">
<tr>
<td><b>Time:</b></td><td>{{ common_event.start_time }} - {{ common_event.end_time }}</td>
</tr>
<tr>
<td><b>Category:</b></td><td>{{ common_event.category.name }}</td>
</tr>
{% if common_event.place %}
<tr>
<td><b>Place:</b></td><td>
<a class="" href="{% url 'show-place' common_event.place.id %}">{{ common_event.place.name }}</a>
</td>
</tr>
{% endif %}
{% if common_event.web_url %}
<tr>
<td><b>Website:</b></td><td><a href="{{ common_event.web_url }}" target="_blank">{{ common_event.web_url }}</a></td>
</tr>
{% endif %}
{% if common_event.announce_url %}
<tr>
<td><b>Announcement:</b></td><td><a href="{{ common_event.announce_url }}" target="_blank">{{ common_event.announce_url }}</a></td>
</tr>
{% endif %}
</table>
<br/>
<div class="container">
<div class="row">
<div class="col"><h4>Participating Teams</h4><hr/></div>
</div>
<div class="row">
{% for event in common_event.participating_events.all %}
<div class="col-md-4">
<div class="card mb-4 box-shadow">
<div class="card-banner">
{% if event.team.category %}
<img class="card-img-top" src="{{event.team.category.img_url}}" alt="{{event.name}}">
{% else %}
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{event.name}}">
{% endif %}
<p class="card-title">{{event.team.name}}</p>
</div>
<div class="card-body">
<p class="card-text"><strong><a class="card-link" href="{{event.get_absolute_url}}">{{event.name}}</a></strong></p>
<div class="d-flex justify-content-between align-items-center">
<small class="text-muted">{{ event.start_time }}</small>
<div class="btn-group">
<a class="btn btn-primary" href="{{ event.get_absolute_url }}">View</a></span>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="row">
<div class="col">
<br/><a href="{% url 'create-common-event-team-select' common_event.id %}" class="btn btn-success">Host an event</a>
</div>
</div>
<br />
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,76 @@
{% extends "get_together/base.html" %}
{% load markup %}
{% block styles %}
<style>
.gt-profile {
position: relative;
}
.gt-profile .gt-profile-badges {
position: absolute;
top: 16px;
left: 6px;
}
</style>
{% endblock %}
{% block content %}
<div class="fluid-container">
<div class="row">
<div class="col-sm-9">
<h2>Welcome to {{ org.name }}
</h2><hr/>
<h4>Upcoming Events</h4>
<div class="container">
{% for event in upcoming_events %}
<div class="row">
<div class="col"><a href="{{ event.get_absolute_url }}">{{event.name}}</a></div>
<div class="col">{{ event.place }}</div>
<div class="col">{{ event.start_time }}</div>
</div>
{% endfor %}
{% if can_create_event %}
<div class="row">
<div class="col">
<br/><a href="{% url 'create-common-event' org.slug %}" class="btn btn-primary">Plan a Get Together</a>
</div>
</div>
{% endif %}
</div>
<br/>
{% if recent_events %}
<h4>Recent Events</h4>
<div class="container">
{% for event in recent_events %}
<div class="row">
<div class="col"><a href="{{ event.get_absolute_url }}">{{event.name}}</a></div>
<div class="col">{{ event.place }}</div>
<div class="col">{{ event.start_time }}</div>
</div>
{% endfor %}
</div>
<br/>
{% endif %}
</div>
<div class="col-sm-3">
<div class="container">
<h4>Members</h4><hr/>
{% for member in member_list %}
<div class="row mb-3">
<div class="col media gt-profile">
<div class="media-body">
<h6 class="mt-0 mb-0"><a href="{% url 'show-team' member.id %}" title="{{member.name}}">{{member.name}}</a></h6>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -33,6 +33,11 @@
</div>
{% endfor %}
</div>
<div class="row">
<div class="col">
<br/><a href="{% url 'create-team' %}" class="btn btn-success">Start a team</a>
</div>
</div>
</div>
{% endblock %}

View file

@ -66,6 +66,12 @@ urlpatterns = [
path('events/<int:event_id>/+photo/', views.add_event_photo, name='add-event-photo'),
path('events/<int:event_id>/<str:event_slug>/', views.show_event, name='show-event'),
path('org/<str:org_slug>/', views.show_org, name='show-org'),
path('org/<str:org_slug>/+create-event/', views.create_common_event, name='create-common-event'),
path('common/<int:event_id>/+share/', views.share_common_event, name='share-common-event'),
path('common/<int:event_id>/+create-event/', views.create_common_event_team_select, name='create-common-event-team-select'),
path('common/<int:event_id>/<str:event_slug>/', views.show_common_event, name='show-common-event'),
path('places/', views.places_list, name='places'),
path('places/<int:place_id>/', views.show_place, name='show-place'),
path('+create-place/', views.create_place, name='create-place'),

View file

@ -3,13 +3,13 @@ from django.utils.translation import ugettext_lazy as _
from django.contrib import messages
from django.contrib.auth import logout as logout_user
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, JsonResponse
from events.models.profiles import Team, UserProfile, Member
from events.forms import TeamEventForm, NewTeamEventForm, DeleteEventForm, NewPlaceForm, UploadEventPhotoForm
from events.models.profiles import Team, Organization, UserProfile, Member
from events.forms import TeamEventForm, NewTeamEventForm, DeleteEventForm, NewPlaceForm, UploadEventPhotoForm, NewCommonEventForm
from events.models.events import Event, EventPhoto, Place, Attendee
from events.models.events import Event, CommonEvent, EventPhoto, Place, Attendee
import datetime
import simplejson
@ -48,23 +48,30 @@ def create_event(request, team_id):
messages.add_message(request, messages.WARNING, message=_('You can not create events for this team.'))
return redirect('show-team', team_id=team.pk)
new_event = Event(team=team, created_by=request.user.profile)
if request.method == 'GET':
form = NewTeamEventForm()
if 'common' in request.GET and request.GET['common'] != '':
new_event.parent = CommonEvent.objects.get(id=request.GET['common'])
form = NewTeamEventForm(instance=new_event)
context = {
'event': new_event,
'team': team,
'event_form': form,
}
return render(request, 'get_together/events/create_event.html', context)
elif request.method == 'POST':
form = NewTeamEventForm(request.POST)
if 'common' in request.POST and request.POST['common'] != '':
new_event.parent = CommonEvent.objects.get(id=request.POST['common'])
form = NewTeamEventForm(request.POST, instance=new_event)
if form.is_valid:
form.instance.team = team
form.instance.created_by = request.user.profile
new_event = form.save()
return redirect('add-place', new_event.id)
else:
context = {
'event': new_event,
'team': team,
'event_form': form,
}
@ -200,4 +207,61 @@ def delete_event(request, event_id):
else:
return redirect('home')
def show_common_event(request, event_id, event_slug):
event = CommonEvent.objects.get(id=event_id)
context = {
'org': event.organization,
'common_event': event,
'can_edit_event': False,
}
return render(request, 'get_together/orgs/show_common_event.html', context)
@login_required
def create_common_event(request, org_slug):
org = Organization.objects.get(slug=org_slug)
if not request.user.profile.can_create_common_event(org):
messages.add_message(request, messages.WARNING, message=_('You can not create events for this org.'))
return redirect('show-org', org_id=org.pk)
new_event = CommonEvent(organization=org, created_by=request.user.profile)
if request.method == 'GET':
form = NewCommonEventForm(instance=new_event)
context = {
'org': org,
'event_form': form,
}
return render(request, 'get_together/orgs/create_common_event.html', context)
elif request.method == 'POST':
form = NewCommonEventForm(request.POST, instance=new_event)
if form.is_valid:
new_event = form.save()
return redirect('show-common-event', new_event.id, new_event.slug)
else:
context = {
'org': org,
'event_form': form,
}
return render(request, 'get_together/orgs/create_common_event.html', context)
else:
return redirect('home')
def share_common_event(request, event_id):
event = CommonEvent.objects.get(id=event_id)
context = {
'event': event,
}
return render(request, 'get_together/orgs/share_common_event.html', context)
@login_required
def create_common_event_team_select(request, event_id):
teams = request.user.profile.moderating
if len(teams) == 1:
return redirect(reverse('create-event', kwargs={'team_id':teams[0].id}) + '?common=%s'%event_id)
context = {
'common_event_id': event_id,
'teams': teams
}
return render(request, 'get_together/orgs/create_common_event_team_select.html', context)

View file

@ -6,10 +6,10 @@ from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from events.models.profiles import Team, UserProfile, Member
from events.models.profiles import Organization, Team, UserProfile, Member
from events.forms import TeamForm, NewTeamForm, DeleteTeamForm
from events.models.events import Event, Place, Attendee
from events.models.events import Event, CommonEvent, Place, Attendee
import datetime
import simplejson
@ -120,4 +120,17 @@ def delete_team(request, team_id):
else:
return redirect('home')
def show_org(request, org_slug):
org = Organization.objects.get(slug=org_slug)
upcoming_events = CommonEvent.objects.filter(organization=org, end_time__gt=datetime.datetime.now()).order_by('start_time')
recent_events = CommonEvent.objects.filter(organization=org, end_time__lte=datetime.datetime.now()).order_by('-start_time')[:5]
context = {
'org': org,
'upcoming_events': upcoming_events,
'recent_events': recent_events,
'member_list': Team.objects.filter(organization=org).order_by('name'),
'can_create_event': request.user.profile.can_create_common_event(org),
}
return render(request, 'get_together/orgs/show_org.html', context)