{#-
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-#}
{% extends g.theme.master %}
{% set wiki_found = False %}
{% set tracker_found = False %}
{% set forum_found = False %}

{% block title %}{{c.project.name}} / Admin{% endblock %}

{% block header %}Project Admin{% endblock %}

{% block content %}
  <p>{{config.site_name}} projects come with a number of Tools, which can be configured and adjusted to your needs.</p>

  <div class="grid-2">
    <img src="{{g.forge_static('images/project_default.png')}}" alt="">
  </div>
  <div class="grid-13">
    <h3>Project Setup</h3>
    <p>The first thing to do to setup your project is to create a solid description, so folks coming to your page can figure out what the project is all about. You'll then want to input information about the project, and we'll make sure all this relevant information gets added to the {{config.site_name}} project directory.</p>
  </div>
  <div class="grid-4">
    <a href="overview">Update MetaData</a>
  </div>
  <div style="clear:both"></div>

  <div class="grid-2">
    <img src="{{ g.theme.app_icon_url('Wiki', 48) }}" alt="">
  </div>
  <div class="grid-13">
    <h3>Wikis</h3>
    <p>You can create documentation, post proposed feature descriptions, and discuss these shared documents.</p>
  </div>
  <div class="grid-4">
    {% for tool in c.project.app_configs %}
      {% if tool.tool_name.lower() == 'wiki' and not wiki_found %}
        <a href="{{c.project.url()}}{{tool.options.mount_point}}/add">Add Page</a><br>
        <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View Wiki</a>
        {% set wiki_found = True %}
      {% endif %}
    {% endfor %}
  </div>
  <div style="clear:both"></div>
  {% if scm_tools %}
    {% set tool = scm_tools[0] %}
    <div class="grid-2">
        <img src="{{ g.theme.app_icon_url('Git', 48) }}" alt="">
    </div>
    <div class="grid-13">
      <h3>Code</h3>
      <p>Source Control Management will help you keep track of code changes over time. A repository has already been created, checkout, add files and upload code.</p>
    </div>
    <div class="grid-4">
      <a href="{{c.project.url()}}{{tool.options.mount_point}}/fork">Checkout repo</a><br>
      <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View source</a>
    </div>
  {% endif %}
  <div style="clear:both"></div>

  <div class="grid-2">
    <img src="{{ g.theme.app_icon_url('Tickets', 48) }}" alt="">
  </div>
  <div class="grid-13">
  <h3>Tickets</h3>
    <p>With the {{config.site_name}} tracker you can keep track of items of work that need to be done. You can create one or more trackers for bugs, enhancements, tasks, that will help you plan and manage your development process.</p>
  </div>
  <div class="grid-4">
    {% for tool in c.project.app_configs %}
      {% if tool.tool_name.lower() == 'tickets' and not tracker_found %}
        <a href="{{c.project.url()}}{{tool.options.mount_point}}/new">Create Ticket</a><br>
        <a href="{{c.project.url()}}{{tool.options.mount_point}}/milestones">Edit Milestones</a><br>
        <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View Tickets</a>
        {% set tracker_found = True %}
      {% endif %}
    {% endfor %}
  </div>
  <div style="clear:both"></div>

  <div class="grid-2">
    <img src="{{ g.theme.app_icon_url('Discussion', 48) }}" alt="">
  </div>
  <div class="grid-13">
    <h3>Forums</h3>
    <p>To use the forums, create a couple of forums, post introductory messages, and check out the spam controll/post moderation options.</p>
  </div>
  <div class="grid-4">
    {% for tool in c.project.app_configs %}
      {% if tool.tool_name == 'Discussion' and not forum_found %}
          <a href="{{c.project.url()}}{{tool.options.mount_point}}/?new_forum=True">Create Forum</a><br>
          <a href="{{c.project.url()}}{{tool.options.mount_point}}/">View Forums</a>
        {% set forum_found = True %}
      {% endif %}
    {% endfor %}
  </div>
{% endblock %}
