Skip to content

Commit a9bca75

Browse files
committed
Rework homepage UI
Summary: * New welcome section, featuring "how to" video and steps * Featured and popular documents list * Document card display Resolves T231 Resolves T232 Test Plan: * Check the new homepage against mockups Reviewers: doshitan Reviewed By: doshitan Subscribers: atogle Maniphest Tasks: T232, T231 Differential Revision: https://phabricator.opengovfoundation.org/D126
1 parent 5ee9f5c commit a9bca75

File tree

14 files changed

+177
-247
lines changed

14 files changed

+177
-247
lines changed

app/Http/Controllers/HomeController.php

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,13 @@ class HomeController extends Controller
1515
*/
1616
public function index(Request $request)
1717
{
18-
$categories = $request->input('categories');
18+
$featuredDocuments = Document::getFeatured();
19+
$popularDocuments = Document::getActiveOrRecent(3);
1920

20-
$selectedCategories = [];
21-
22-
$documentQuery = Document::getEager()->where('publish_state', Document::PUBLISH_STATE_PUBLISHED);
23-
24-
if ($categories) {
25-
$selectedCategories = Category::whereIn('id', $categories)->get();
26-
$documentQuery->whereHas('categories', function($q) use ($categories) {
27-
$q->whereIn('id', $categories);
28-
});
29-
}
30-
31-
$documents = $documentQuery->paginate(5);
32-
$featuredDocuments = Document::getFeaturedOrRecent();
33-
$mostActiveDocuments = Document::getActive(6);
34-
$mostRecentDocuments = Document::mostRecentPublicWithOpenDiscussion()->get();
35-
36-
return view('home', compact(
21+
return view('home', compact([
3722
'selectedCategories',
38-
'documents',
3923
'featuredDocuments',
40-
'mostActiveDocuments',
41-
'mostRecentDocuments'
42-
));
24+
'popularDocuments',
25+
]));
4326
}
4427
}

app/Models/Doc.php

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\SoftDeletes;
77
use Illuminate\Database\Eloquent\Collection;
8+
use Illuminate\Support\Str;
89
use App\Models\Category;
910
use App\Models\DocContent as DocumentContent;
1011
use App\Services\SearchQueryCompiler;
1112
use App\Traits\RootAnnotatableHelpers;
13+
use GrahamCampbell\Markdown\Facades\Markdown;
1214
use Event;
1315
use Exception;
1416
use URL;
@@ -104,6 +106,7 @@ public function introtext()
104106

105107
public function setIntroText($value)
106108
{
109+
$htmlCacheKey = static::introtextHtmlCacheKey($this);
107110
$introtext = DocMeta
108111
::where('meta_key', '=', 'intro-text')
109112
->where('doc_id', $this->id)
@@ -118,9 +121,15 @@ public function setIntroText($value)
118121
$introtext->meta_value = $value;
119122
}
120123

124+
Cache::forget($htmlCacheKey);
121125
$introtext->save();
122126
}
123127

128+
public function shortIntroText()
129+
{
130+
return Str::words(strip_tags($this->introtext_html), 15, ' ...');
131+
}
132+
124133
public function dates()
125134
{
126135
return $this->hasMany('App\Models\Date');
@@ -309,6 +318,7 @@ public function enableSponsors()
309318
public function enableIntrotext()
310319
{
311320
$this->appends[] = 'introtext';
321+
$this->appends[] = 'introtext_html';
312322
}
313323

314324
public function getIntrotextAttribute()
@@ -320,6 +330,29 @@ public function getIntrotextAttribute()
320330
}
321331
}
322332

333+
public function getIntrotextHtmlAttribute()
334+
{
335+
if ($this->introtext()->count()) {
336+
$cacheKey = static::introtextHtmlCacheKey($this);
337+
338+
if (Cache::has($cacheKey)) {
339+
return Cache::get($cacheKey);
340+
}
341+
342+
$introtextHtml = Markdown::convertToHtml($this->introtext()->first()->meta_value);
343+
Cache::forever($cacheKey, $introtextHtml);
344+
345+
return $introtextHtml;
346+
}
347+
348+
return null;
349+
}
350+
351+
protected static function introtextHtmlCacheKey(Doc $document)
352+
{
353+
return 'doc-'.$document->id.'-introtext-html';
354+
}
355+
323356
public function getSponsorIdsAttribute()
324357
{
325358
$ids = [];
@@ -451,6 +484,27 @@ public static function getEager()
451484
->with('dates');
452485
}
453486

487+
/**
488+
* Get a number of active documents, filling in with recent documents if
489+
* number requested is not fufilled.
490+
*/
491+
public static function getActiveOrRecent($num = 10, $offset = 0)
492+
{
493+
$documents = collect(static::getActive($num, $offset));
494+
495+
if ($documents->count() < $num) {
496+
$recentDocuments = static
497+
::where('publish_state', static::PUBLISH_STATE_PUBLISHED)
498+
->where('is_template', '!=', '1')
499+
->orderBy('created_at', 'desc')
500+
->take($num - $documents->count())
501+
;
502+
$documents = $documents->union($recentDocuments->get());
503+
}
504+
505+
return $documents;
506+
}
507+
454508
/*
455509
* Active documents are much harder to query. We do this with its own
456510
* custom query.
@@ -556,43 +610,6 @@ public static function getFeatured($onlyPublished = true)
556610
return null;
557611
}
558612

559-
560-
public static function getFeaturedOrRecent()
561-
{
562-
$docs = static::getFeatured();
563-
564-
// If we don't have a document, just find anything recent.
565-
if (empty($docs)) {
566-
$docs =
567-
static::with('categories')
568-
->with('sponsors')
569-
->with('statuses')
570-
->with('dates')
571-
->where('publish_state', '=', static::PUBLISH_STATE_PUBLISHED)
572-
->where('is_template', '!=', '1')
573-
->orderBy('created_at', 'desc')
574-
->limit(1)
575-
->get()
576-
;
577-
}
578-
579-
$return_docs = [];
580-
foreach ($docs as $key => $doc) {
581-
$doc->enableCounts();
582-
$doc->enableSponsors();
583-
$return_doc = $doc->toArray();
584-
585-
$return_doc['introtext'] = $doc->introtext()->first()['meta_value'];
586-
$return_doc['updated_at'] = date('c', strtotime($return_doc['updated_at']));
587-
$return_doc['created_at'] = date('c', strtotime($return_doc['created_at']));
588-
$return_doc['featuredImageUrl'] = $doc->getFeaturedImageUrl();
589-
590-
$return_docs[] = $return_doc;
591-
}
592-
593-
return $return_docs;
594-
}
595-
596613
public static function allOwnedBy($userId)
597614
{
598615
$rawDocs = \DB::select(

database/seeds/DocumentsTableSeeder.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ class DocumentsTableSeeder extends Seeder
1111
{
1212
public function run()
1313
{
14+
$faker = Faker\Factory::create();
1415
$sponsor = Sponsor::find(1);
1516

1617
$documents = factory(Document::class, (int)config('madison.seeder.num_docs'))->create([
1718
'publish_state' => Document::PUBLISH_STATE_PUBLISHED,
18-
])->each(function ($document) use ($sponsor) {
19+
])->each(function ($document) use ($sponsor, $faker) {
1920
$document->sponsors()->attach($sponsor);
21+
$document->setIntroText(join(' ', $faker->sentences));
2022
$document->content()->save(factory(DocContent::class)->make());
2123
});
2224

resources/assets/sass/global.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
display: inline;
3030
}
3131

32+
footer.nav {
33+
padding-bottom: 30px;
34+
}
35+
3236
// Overlay shadows
3337
%simple-shadow {
3438
box-shadow: 0 0 5px 0 rgba(0,0,0,0.9);

resources/assets/sass/home.scss

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
.home-feature {
2-
@extend .col-md-12;
3-
}
1+
.doc-card.thumbnail {
2+
padding: 0;
43

5-
.document-thumbnail {
6-
max-width: 100%;
4+
.caption { padding: 13px; }
5+
img { border-radius: 4px 4px 0 0; }
76
}

resources/lang/en/messages.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,23 @@
6161
// Home Page Stuff
6262
'home' => [
6363
'home' => 'Home',
64-
'welcome' => 'Add your voice...',
65-
'intro' => 'Find legislation and regulations being developed and get informed. Then get involved and collaboratively craft the documents with the sponsors. To get started, choose from the recent documents below, or search the whole repository.',
64+
'welcome' => 'Add your voice',
65+
'intro' => 'Legislation and regulations that impact your life are written every day. With Madison, you can work directly <em>with</em> the sponsors of these documents.',
66+
'learn_more' => 'Learn more',
67+
'how_it_works' => [
68+
'title' => 'How it Works',
69+
'step1' => 'Elected officials share policy documents on Madison for public collaboration.',
70+
'step2' => 'The people can read the documents, vote on the documents, and leave feedback on the documents, and their comments are sent <strong>directly to the officials</strong>.',
71+
'step3' => 'Officials respond to these comments and even make changes to the documents based on the feedback.',
72+
],
73+
'sponsor_cta' => [
74+
'title' => 'Have a document to share?',
75+
'text' => 'You can easily request to become a document sponsor and add the public\'s voice and credibility to your proposal.',
76+
'action_text' => 'Learn about how to become a sponsor.',
77+
],
78+
'featured_title' => 'Featured',
79+
'popular_title' => 'Popular',
80+
'all_documents' => 'View all documents',
6681
],
6782

6883
'search' => [
@@ -78,6 +93,7 @@
7893

7994
// Document Stuff
8095
'document' => [
96+
'read' => 'Read this document',
8197
'title' => 'Title',
8298
'title_invalid' => 'Can\'t create document with that name, please try another.',
8399
'slug' => 'Custom URL (slug)',

resources/views/home.blade.php

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,25 @@
44

55
@section('content')
66

7-
<div class="row">
8-
<div class="col-md-6">
9-
<section class="home-feature">
10-
@each('home/partials/featured-document', $featuredDocuments, 'document')
11-
</section>
7+
@include('home.partials.welcome')
128

13-
@include('home/partials/active-documents', [
14-
'mostActiveDocuments' => $mostActiveDocuments,
15-
'mostRecentDocuments' => $mostRecentDocuments,
16-
])
17-
</div>
9+
@if (collect($featuredDocuments)->count() > 0)
10+
<h2>@lang('messages.home.featured_title')</h2>
11+
<div class="row featured">
12+
@each('home.partials.document-card', $featuredDocuments, 'document')
13+
</div>
14+
@endif
1815

19-
<div class="col-md-6">
20-
@include('home/partials/welcome')
21-
@include('home/partials/search-list', [
22-
'documents' => $documents
23-
])
16+
<h2>@lang('messages.home.popular_title')</h2>
17+
<div class="row popular">
18+
@each('home.partials.document-card', $popularDocuments, 'document')
19+
</div>
20+
<div class="row">
21+
<div class="col-md-12">
22+
<a href="{{ route('documents.index') }}" class="btn btn-lg btn-primary pull-right">
23+
@lang('messages.home.all_documents') &raquo;
24+
</a>
25+
</div>
2426
</div>
25-
</div>
2627

2728
@endsection

resources/views/home/partials/active-documents.blade.php

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<div class="col-md-4">
2+
<div class="thumbnail doc-card">
3+
<a href="{{ route('documents.show', $document) }}">
4+
<img src="{{ $document->getFeaturedImageUrl() }}" class="img-responsive">
5+
</a>
6+
<div class="caption">
7+
<div class="intro">
8+
<h4>
9+
<a href="{{ route('documents.show', $document) }}">
10+
{{ $document->title }}
11+
</a>
12+
<br>
13+
<small class="text-muted">
14+
{{ $document->sponsors->implode('display_name', ', ') }}
15+
</small>
16+
</h4>
17+
<p>{{ $document->shortIntroText() }}</p>
18+
</div>
19+
20+
<hr>
21+
22+
<div class="row">
23+
<div class="col-md-6">
24+
<small class="text-muted">{{ $document->created_at->toDateString() }}</small>
25+
</div>
26+
<div class="col-md-6 text-right">
27+
<small class="text-muted">{{ $document->all_comments_count }} {{ trans('messages.document.comments') }}</small>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
</div>

0 commit comments

Comments
 (0)