Skip to content

Commit

Permalink
Merge pull request #416 from wlonk/user-group-crates-list
Browse files Browse the repository at this point in the history
Show user details.
  • Loading branch information
steveklabnik authored Sep 28, 2016
2 parents cb4e083 + 6f7fc78 commit 09b3e7b
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 4 deletions.
19 changes: 19 additions & 0 deletions app/controllers/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Ember from 'ember';
import PaginationMixin from '../mixins/pagination';

const { computed } = Ember;

// TODO: reduce duplication with controllers/crates

export default Ember.Controller.extend(PaginationMixin, {
queryParams: ['page', 'per_page', 'sort'],
page: '1',
per_page: 10,
sort: 'alpha',

totalItems: computed.readOnly('model.crates.meta.total'),

currentSortBy: computed('sort', function() {
return (this.get('sort') === 'downloads') ? 'Downloads' : 'Alphabetical';
}),
});
1 change: 1 addition & 0 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Router.map(function() {
this.route('crates');
this.route('following');
});
this.route('user', { path: '/users/:user_id' });
this.route('install');
this.route('search');
this.route('dashboard');
Expand Down
37 changes: 37 additions & 0 deletions app/routes/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Ember from 'ember';

export default Ember.Route.extend({
queryParams: {
page: { refreshModel: true },
sort: { refreshModel: true },
},
data: {},

setupController(controller, model) {
this._super(controller, model);

controller.set('fetchingFeed', true);
controller.set('crates', this.get('data.crates'));
},

model(params) {
const { user_id } = params;
return this.store.find('user', user_id).then(
(user) => {
params.user_id = user.get('id');
return Ember.RSVP.hash({
crates: this.store.query('crate', params),
user
});
},
(e) => {
if (e.errors.any(e => e.detail === 'Not Found')) {
this
.controllerFor('application')
.set('nextFlashError', `User '${params.user_id}' does not exist`);
return this.replaceWith('index');
}
}
);
},
});
5 changes: 4 additions & 1 deletion app/styles/crate.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
@include display-flex;
@include align-items(center);
}
h1 { padding-left: 10px; }
h1 {
padding-left: 10px;
padding-right: 10px;
}
h2 { color: $main-color-light; padding-left: 10px; }
.right {
@include flex(2);
Expand Down
6 changes: 3 additions & 3 deletions app/templates/crate/version.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@
<ul class='owners'>
{{#each crate.owners as |owner|}}
<li>
{{#user-link user=owner}}
{{user-avatar user=owner size='medium-small'}}
{{/user-link}}
{{#link-to 'user' owner.login}}
{{user-avatar user=owner size='medium-small'}}
{{/link-to}}
</li>
{{/each}}
</ul>
Expand Down
67 changes: 67 additions & 0 deletions app/templates/user.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<div id='crates-heading'>
{{user-avatar user=model.user size='medium'}}
<h1>
{{ model.user.login }}
</h1>
{{#user-link user=model.user}}
<img alt="GitHub profile" title="GitHub profile" src="/assets/GitHub-Mark-32px.png"/>
{{/user-link}}
</div>

<div id='user-profile'>
<div class='info'>
{{! TODO: reduce duplication with templates/crates.hbs }}

<div id='results'>
<div class='nav'>
<span class='amt small'>
Displaying
<span class='cur'>{{ currentPageStart }}-{{ currentPageEnd }}</span>
of <span class='total'>{{ totalItems }}</span> total results
</span>
</div>

<div class='sort'>
<span class='small'>Sort by</span>
{{#rl-dropdown-container class="dropdown-container"}}
{{#rl-dropdown-toggle tagName="a" class="dropdown"}}
<img class="sort" src="/assets/sort.png"/>
{{ currentSortBy }}
<span class='arrow'></span>
{{/rl-dropdown-toggle}}

{{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}}
<li>
{{#link-to (query-params sort="alpha")}}
Alphabetical
{{/link-to}}
</li>
<li>
{{#link-to (query-params sort="downloads")}}
Downloads
{{/link-to}}
</li>
{{/rl-dropdown}}
{{/rl-dropdown-container}}
</div>
</div>

<div id='crates' class='white-rows'>
{{#each model.crates as |crate|}}
{{crate-row crate=crate}}
{{/each}}
</div>

<div class='pagination'>
{{#link-to (query-params page=prevPage) class="prev" rel="prev" title="previous page"}}
<img class="left-pag" src="/assets/left-pag.png"/>
{{/link-to}}
{{#each pages as |page|}}
{{#link-to (query-params page=page)}}{{ page }}{{/link-to}}
{{/each}}
{{#link-to (query-params page=nextPage) class="next" rel="next" title="next page"}}
<img class="right-pag" src="/assets/right-pag.png"/>
{{/link-to}}
</div>
</div>
</div>
Binary file added public/assets/GitHub-Mark-32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
api_router.get("/versions/:version_id", C(version::show));
api_router.get("/keywords", C(keyword::index));
api_router.get("/keywords/:keyword_id", C(keyword::show));
api_router.get("/users/:user_id", C(user::show));
let api_router = Arc::new(R404(api_router));

let mut router = RouteBuilder::new();
Expand Down
15 changes: 15 additions & 0 deletions src/user/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;

use conduit::{Request, Response};
use conduit_cookie::{RequestSession};
use conduit_router::RequestParams;
use pg::GenericConnection;
use pg::rows::Row;
use pg::types::Slice;
Expand Down Expand Up @@ -288,6 +289,20 @@ pub fn me(req: &mut Request) -> CargoResult<Response> {
Ok(req.json(&R{ user: user.clone().encodable(), api_token: token }))
}

/// Handles the `GET /users/:user_id` route.
pub fn show(req: &mut Request) -> CargoResult<Response> {
let name = &req.params()["user_id"];
let conn = try!(req.tx());
let user = try!(User::find_by_login(conn, &name));

#[derive(RustcEncodable)]
struct R {
user: EncodableUser,
}
Ok(req.json(&R{ user: user.clone().encodable() }))
}


/// Handles the `GET /me/updates` route.
pub fn updates(req: &mut Request) -> CargoResult<Response> {
let user = try!(req.user());
Expand Down

0 comments on commit 09b3e7b

Please sign in to comment.