diff --git a/mo/web/org.py b/mo/web/org.py
index 2aa1f4cf022ff4c3ed016813b76f5033079bfff1..72c67429e74bc812683b708653fb918e54036d56 100644
--- a/mo/web/org.py
+++ b/mo/web/org.py
@@ -1,11 +1,14 @@
-from flask import render_template, redirect, url_for, request, flash
-from sqlalchemy.orm import aliased
+from flask import render_template, redirect, url_for, request, flash, g
+from sqlalchemy import and_, or_
+from sqlalchemy.orm import aliased, joinedload
+from typing import List, Set, Dict
 
 import mo.db as db
-from mo.web.jinja import user_url
+import mo.rights
 import mo.users
-from mo.web.table import Table, Row, Column
 from mo.web import app
+from mo.web.jinja import user_url
+from mo.web.table import Table, Row, Column
 
 
 @app.route('/org/')
@@ -28,7 +31,37 @@ def org_index():
         except ValueError:
             flash('ID uživatele musí být číslo', 'danger')
 
-    return render_template('org_index.html')
+    sess = db.get_session()
+    ctr = (sess.query(db.Contest, db.UserRole)
+               .select_from(db.UserRole, db.Round, db.Contest)
+               .filter(and_(db.UserRole.user_id == g.user.user_id,
+                            or_(db.UserRole.category == None, db.UserRole.category == db.Round.category),
+                            or_(db.UserRole.year == None, db.UserRole.year == db.Round.year),
+                            or_(db.UserRole.seq == None, db.UserRole.seq == db.Round.seq),
+                            db.Round.year == mo.current_year,
+                            db.Contest.round_id == db.Round.round_id,
+                            db.Contest.place_id == db.UserRole.place_id))
+               .options(joinedload(db.Contest.place))
+               .order_by(db.Round.level, db.Round.category, db.Round.seq, db.Round.part,
+                         db.Contest.place_id, db.Contest.contest_id)
+               .all())
+
+    # Pokud máme pro jednu soutěž více rolí, zkombinujeme je
+    contests: List[db.Contest] = []
+    contest_role_sets: Dict[db.Contest, Set[db.RoleType]] = {}
+    for ct, ur in ctr:
+        if len(contests) == 0 or contests[-1] != ct:
+            contests.append(ct)
+            contest_role_sets[ct.contest_id] = set()
+        contest_role_sets[ct.contest_id].add(ur.role)
+
+    # Role pro každou soutěž setřídíme podle důležitosti
+    contest_roles: Dict[db.Contest, List[db.RoleType]] = {
+        ct_id: sorted(list(contest_role_sets[ct_id]), key=lambda r: mo.rights.role_order_by_type[r])
+        for ct_id in contest_role_sets.keys()
+    }
+
+    return render_template('org_index.html', contests=contests, contest_roles=contest_roles, role_type_names=db.role_type_names)
 
 
 school_export_columns = (
diff --git a/mo/web/templates/org_index.html b/mo/web/templates/org_index.html
index 3244560a7a35b1ed49cf594848f2e3e7721e51e9..73a21f886d3be32aea08d14005d44e0d0e0e022d 100644
--- a/mo/web/templates/org_index.html
+++ b/mo/web/templates/org_index.html
@@ -2,6 +2,39 @@
 {% block title %}Organizátorské rozhraní{% endblock %}
 {% block body %}
 
+{% if contests %}
+
+<h3>Moje soutěže</h3>
+<table class="table table-bordered table-condensed greyhead">
+{% set curr = namespace(level=-1) %}
+	{% for c in contests %}
+		{% if curr.level != c.round.level %}
+		<thead><tr>
+			<th>ID
+			<th>Kategorie
+			<th>Kolo
+			<th>{{ c.round.get_level().name|capitalize }}
+			<th>Stav
+			<th>Moje role
+			<th>Odkazy
+		</thead>
+		{% set curr.level = c.round.level %}
+		{% endif %}
+
+		<tr>
+			<td><a href='{{ url_for('org_contest', id=c.contest_id) }}'>{{ c.round.round_code() }}</a>
+			<td class="text-center"><b>{{ c.round.category }}</b>
+			<td>{{ c.round.name }}
+			<td>{{ c.place.name }}
+			<td class="rstate-{{c.state.name}}">{{ c.state.friendly_name() }}
+			<td>{% for r in contest_roles[c.contest_id] %}{{ role_type_names[r] }}{% if not loop.last %}<br>{% endif %}{% endfor %}
+			<td>
+				<a class="btn btn-xs btn-primary" href='{{ url_for('org_contest', id=c.contest_id) }}'>Detail</a>
+	{% endfor %}
+</table>
+
+{% endif %}
+
 <h3>Různé</h3>
 
 <ul>