-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #29 from hotosm/feat/news-page
news page should be ready to go
- Loading branch information
Showing
92 changed files
with
1,356 additions
and
876 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,6 @@ node_modules | |
**/dist/ | ||
/staticfiles/ | ||
.coverage | ||
/hot_osm/locale | ||
/media | ||
/locale |
63 changes: 63 additions & 0 deletions
63
app/news/migrations/0020_newsownerpage_category_select_and_more.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Generated by Django 4.2.7 on 2024-06-25 22:20 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('news', '0019_newsownerpage_and_more'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='category_select', | ||
field=models.CharField(default='Select Categories'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='enter_tag_hint', | ||
field=models.CharField(default='Enter tag'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='keyword_search_hint', | ||
field=models.CharField(default='Search by keyword'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='remove_filters_text', | ||
field=models.CharField(default='Remove All Filters'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='results_text', | ||
field=models.CharField(default='Results'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='search_button_text', | ||
field=models.CharField(default='Search'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='sort_by_new', | ||
field=models.CharField(default='Sort by New'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='sort_by_old', | ||
field=models.CharField(default='Sort by Old'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='sort_by_titlea', | ||
field=models.CharField(default='Sort by Title Alphabetical'), | ||
), | ||
migrations.AddField( | ||
model_name='newsownerpage', | ||
name='sort_by_titlez', | ||
field=models.CharField(default='Sort by Title Reverse Alphabetical'), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div class="mt-4 flex items-center w-fit h-fit" @click="hit()" x-data="{ sort: '{{sort_id}}', hit() {setSortType('{{sort_by}}')} }" x-init="if(sort == params.get('sort')) hit()"> | ||
<input class="checked:bg-hot-red checked:hover:bg-hot-red checked:focus:bg-hot-red" type="radio" name="sort" :id="sort" :value="sort" :checked="(params.get('sort') == sort || !params.get('sort')) ? 'on' : ''"> | ||
<label class="pl-2" :for="sort">{{sort_by}}</label> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
{% extends "base.html" %} | ||
{% load static %} | ||
{% load wagtailcore_tags %} | ||
{% load wagtailimages_tags %} | ||
{% load compress %} | ||
{% block body_class %}template-individualnewspage{% endblock %} | ||
{% block extra_css %} | ||
{% compress css %} | ||
{% endcompress css %} | ||
{% endblock extra_css %} | ||
|
||
{% block content %} | ||
<div class="max-w-7xl mx-auto my-10" x-data="{ params: new URLSearchParams((new URL(window.location.href)).search) }"> | ||
<div class="px-6 md:px-10"> | ||
<h1 class="text-h1 font-semibold my-10">{{page.title}}</h1> | ||
<form> | ||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> | ||
{% comment %} KEYWORD SEARCH {% endcomment %} | ||
<div class="bg-hot-off-white flex items-center"> | ||
<input class="w-full bg-transparent border-none" placeholder="{{page.keyword_search_hint}}" type="text" name="keyword" :value="params.get('keyword')"> | ||
{% include "ui/components/icon_svgs/SearchIcon.html" with class="text-hot-red mx-3" %} | ||
</div> | ||
|
||
{% comment %} CATEGORY {% endcomment %} | ||
<div class="relative" x-data="{ show: false }" @click.away="show = false"> | ||
<div class="w-full h-full flex justify-between py-2 px-3 bg-hot-off-white items-center cursor-pointer" @click="show = !show"> | ||
<p class="pointer-events-none"> | ||
{{page.category_select}} | ||
</p> | ||
{% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-90 text-hot-red" %} | ||
</div> | ||
<div class="absolute z-20 bg-hot-off-white p-4 w-full" x-show="show"> | ||
<hr class="border-b-2"> | ||
{% for category in categories %} | ||
<div class="mt-4 flex"> | ||
<label for="cat-{{forloop.counter}}">{{category.category_name}}</label> | ||
<input class="ml-auto checked:bg-hot-red checked:hover:bg-hot-red checked:focus:bg-hot-red" id="cat-{{forloop.counter}}" type="checkbox" name="{{category.category_name}}" :checked="params.get('{{category.category_name}}')"> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
</div> | ||
|
||
{% comment %} SORT {% endcomment %} | ||
<div class="relative" x-data="{ show: false, setSortType(text) {$refs.sorttype.innerText = text} }" @click.away="show = false"> | ||
<div class="w-full h-full flex justify-between py-2 px-3 bg-hot-off-white items-center cursor-pointer" @click="show = !show"> | ||
<p class="pointer-events-none" x-ref="sorttype"> | ||
{{page.sort_by_new}} | ||
</p> | ||
{% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-90 text-hot-red" %} | ||
</div> | ||
<div class="absolute z-20 bg-hot-off-white p-4 w-full" x-show="show"> | ||
<hr class="border-b-2"> | ||
{% include "./components/NewsSortOption.html" with sort_by=page.sort_by_new sort_id="sort.new" %} | ||
{% include "./components/NewsSortOption.html" with sort_by=page.sort_by_old sort_id="sort.old" %} | ||
{% include "./components/NewsSortOption.html" with sort_by=page.sort_by_titlea sort_id="sort.titlea" %} | ||
{% include "./components/NewsSortOption.html" with sort_by=page.sort_by_titlez sort_id="sort.titlez" %} | ||
</div> | ||
</div> | ||
|
||
{% comment %} TAG {% endcomment %} | ||
<div class="bg-hot-off-white flex items-center" x-data="{ submitTagInput() { | ||
if(!$refs.taginput.value) return; | ||
$refs.taglist.innerHTML += `<div @click='' class='bg-hot-red text-white p-2 cursor-default'><input class='hidden' value='on' name='tag.${escape($refs.taginput.value)}'><p>${escape($refs.taginput.value)} <span class='ml-2 cursor-pointer' @click='$el.parentElement.parentElement.remove()'>✖</span></p></div>`; $refs.taginput.value = ''; | ||
} }"> | ||
<input class="w-full bg-transparent border-none" placeholder="{{page.enter_tag_hint}}" type="text" name="tagfield" x-ref="taginput" | ||
x-on:keydown.enter="submitTagInput(); $event.preventDefault(); return false;" | ||
> | ||
<p class="text-hot-red px-3 py-2 cursor-pointer" @click="submitTagInput()">+</p> | ||
</div> | ||
|
||
<div class="bg-hot-red text-white font-semibold"> | ||
<input type="submit" value="{{page.search_button_text}}" class="bg-transparent w-full h-full cursor-pointer py-2"> | ||
</div> | ||
</div> | ||
|
||
<hr class="border-black border-t-2 mt-10 mb-4"> | ||
|
||
{% comment %} TAGS GO HERE {% endcomment %} | ||
<a href="{{page.url}}"> | ||
<p class="cursor-pointer inline-block"> | ||
{{page.remove_filters_text}} | ||
{% include "ui/components/icon_svgs/RefreshIcon.html" with class="ml-4" %} | ||
</p> | ||
</a> | ||
{% comment %} for some reason having the 'let nada = undefined' is necessary because it doesn't like when you start the x-init with a for loop {% endcomment %} | ||
<div id="taglist" x-ref="taglist" class="flex gap-4 mt-4" | ||
x-init="let nada = undefined; for (let x of params) { | ||
if (x[0].startsWith('tag.')) { | ||
let tag = x[0].slice(4); | ||
$el.innerHTML += `<div @click='' class='bg-hot-red text-white p-2 cursor-default'><input class='hidden' value='on' name='tag.${tag}'><p>${tag} <span class='ml-2 cursor-pointer' @click='$el.parentElement.parentElement.remove()'>✖</span></p></div>`; | ||
} | ||
}" | ||
> | ||
</div> | ||
</form> | ||
|
||
<h2 class="text-h2 font-bold my-8">{{news_paginator.count}} {{page.results_text}}</h2> | ||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> | ||
{% for article in news %} | ||
{% include "ui/components/news/NewsPreviewBlockProjects.html" with news=article showimage=True class="[&_.image-hide-small]:hidden md:[&_.image-hide-small]:block" %} | ||
{% endfor %} | ||
</div> | ||
|
||
<div class="w-full flex justify-center items-center" | ||
x-data="{ | ||
page: params.get('page') ? params.get('page') : 1, | ||
paramsX: new URLSearchParams((new URL(window.location.href)).search), | ||
getPageLink(x) { this.paramsX.set('page', x); return '?' + this.paramsX.toString() } | ||
}"> | ||
<a :href="page > 1 ? getPageLink(parseInt(page) - 1) : ''" aria-label="Previous Page"> | ||
<p class="cursor-pointer" :class="page == 1 ? 'text-hot-slate-grey' : 'text-hot-red'"> | ||
{% include "ui/components/icon_svgs/LinkCaret.html" with class="rotate-180" %} | ||
</p> | ||
</a> | ||
<div class="flex gap-2 mx-4"> | ||
{% with ''|center:news_paginator.num_pages as range %} | ||
{% for _ in range %} | ||
{% if forloop.counter == 1 or forloop.counter == news_paginator.num_pages or forloop.counter == current_page or forloop.counter|add:1 == current_page or forloop.counter|add:'-1' == current_page %} | ||
<a :href="getPageLink(parseInt({{forloop.counter}}))"> | ||
<p class="px-2 font-bold" :class="page == {{forloop.counter}} ? 'bg-hot-red text-white' : 'bg-hot-off-white'"> | ||
{{forloop.counter}} | ||
</p> | ||
</a> | ||
{% endif %} | ||
{% if forloop.counter|add:2 == current_page or forloop.counter|add:'-2' == current_page and not forloop.last %} | ||
{% comment %} | ||
for reasons that i can't begin to comprehend, the if statement | ||
below CANNOT be part of the if statement above. it just does | ||
not work | ||
{% endcomment %} | ||
{% if not forloop.first %} | ||
<p class="mx-1">...</p> | ||
{% endif %} | ||
{% endif %} | ||
{% endfor %} | ||
{% endwith %} | ||
</div> | ||
<a :href="page < {{news_paginator.num_pages}} ? getPageLink(parseInt(page) + 1) : ''" aria-label="Next Page"> | ||
<p class="cursor-pointer" :class="page == {{news_paginator.num_pages}} ? 'text-hot-slate-grey' : 'text-hot-red'"> | ||
{% include "ui/components/icon_svgs/LinkCaret.html" %} | ||
</p> | ||
</a> | ||
</div> | ||
</div> | ||
</div> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<svg class="inline {{class}}" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20.75 20.75"> | ||
<path id="Icon_ionic-md-refresh" data-name="Icon ionic-md-refresh" d="M16,23.781A7.781,7.781,0,0,1,16,8.219a7.538,7.538,0,0,1,5.447,2.334L17.3,14.7h9.078V5.625L23.327,8.673A10.362,10.362,0,1,0,25.986,18.83H23.242A7.727,7.727,0,0,1,16,23.781Z" transform="translate(-5.625 -5.625)" fill="#d43f3f"/> | ||
</svg> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<svg class="inline {{class}}" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 13.99 13.993"> | ||
<path id="Icon_ionic-ios-search" data-name="Icon ionic-ios-search" d="M18.326,17.474l-3.891-3.927a5.545,5.545,0,1,0-.842.853l3.865,3.9a.6.6,0,0,0,.845.022A.6.6,0,0,0,18.326,17.474Zm-8.248-3.027a4.378,4.378,0,1,1,3.1-1.282A4.351,4.351,0,0,1,10.078,14.446Z" transform="translate(-4.5 -4.493)" fill="#d43f3f"/> | ||
</svg> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.