Added ShopPanel to home sidebar
• Added: - ShopPanel to home sidebar - DIssenter shop redux, api route/controller
This commit is contained in:
parent
0ca346b169
commit
095e646661
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ShopController < Api::BaseController
|
||||
before_action :require_user!
|
||||
|
||||
respond_to :json
|
||||
|
||||
skip_before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
type = params[:type]
|
||||
if type == 'featured_products'
|
||||
body = Redis.current.get("gabstore:featuredproducts")
|
||||
|
||||
if body.nil?
|
||||
uri = URI("https://shop.dissenter.com/product/group/json")
|
||||
uri.query = URI.encode_www_form({})
|
||||
|
||||
res = Net::HTTP.get_response(uri)
|
||||
if res.is_a?(Net::HTTPSuccess)
|
||||
body = res.body
|
||||
Redis.current.set("gabstore:featuredproducts", res.body)
|
||||
Redis.current.expire("gabstore:featuredproducts", 15.minutes.seconds)
|
||||
end
|
||||
end
|
||||
|
||||
render json: body
|
||||
else
|
||||
raise GabSocial::NotPermittedError
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
import api from '../api'
|
||||
import { me } from '../initial_state'
|
||||
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_REQUEST = 'SHOP_FEATURED_PRODUCTS_FETCH_REQUEST'
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS = 'SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS'
|
||||
export const SHOP_FEATURED_PRODUCTS_FETCH_FAIL = 'SHOP_FEATURED_PRODUCTS_FETCH_FAIL'
|
||||
|
||||
export const fetchFeaturedProducts = () => {
|
||||
return function (dispatch, getState) {
|
||||
if (!me) return
|
||||
|
||||
dispatch(fetchFeaturedProductsRequest('featured'))
|
||||
|
||||
api(getState).get(`/api/v1/shop?type=featured_products`).then((response) => {
|
||||
try {
|
||||
dispatch(fetchFeaturedProductsSuccess(response.data.data, 'featured'))
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}).catch(function (error) {
|
||||
dispatch(fetchFeaturedProductsFail(error, 'featured'))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function fetchFeaturedProductsRequest(listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_REQUEST,
|
||||
listType,
|
||||
}
|
||||
}
|
||||
|
||||
function fetchFeaturedProductsSuccess(items, listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS,
|
||||
items,
|
||||
listType,
|
||||
}
|
||||
}
|
||||
|
||||
function fetchFeaturedProductsFail(error, listType) {
|
||||
return {
|
||||
type: SHOP_FEATURED_PRODUCTS_FETCH_FAIL,
|
||||
error,
|
||||
listType,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { fetchFeaturedProducts } from '../../actions/shop'
|
||||
import PanelLayout from './panel_layout'
|
||||
import Image from '../image'
|
||||
import Text from '../text'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'shop_panel.title', defaultMessage: 'Dissenter Shop' },
|
||||
shop_now: { id: 'shop_panel.shop_now', defaultMessage: 'Visit the Dissenter Shop' },
|
||||
})
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
items: state.getIn(['shop', 'featured', 'items']),
|
||||
isError: state.getIn(['shop', 'featured', 'isError']),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
onFetchFeaturedProducts: () => dispatch(fetchFeaturedProducts()),
|
||||
})
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class ShopPanel extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
products: PropTypes.array,
|
||||
isLazy: PropTypes.bool,
|
||||
onFetchFeaturedProducts: PropTypes.func.isRequired,
|
||||
isError: PropTypes.bool.isRequired,
|
||||
}
|
||||
|
||||
state = {
|
||||
fetched: !this.props.isLazy,
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
if (nextProps.shouldLoad && !prevState.fetched) {
|
||||
return { fetched: true }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (!prevState.fetched && this.state.fetched) {
|
||||
this.props.onFetchFeaturedProducts()
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.isLazy) {
|
||||
this.props.onFetchFeaturedProducts()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
intl,
|
||||
items,
|
||||
isError,
|
||||
} = this.props
|
||||
|
||||
if (!items || isError || !Array.isArray(items)) return null
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
noPadding
|
||||
title={intl.formatMessage(messages.title)}
|
||||
footerButtonTitle={intl.formatMessage(messages.shop_now)}
|
||||
footerButtonTo='/'
|
||||
>
|
||||
<div className={[_s.default, _s.flexRow, _s.flexWrap, _s.pl5, _s.pt5].join(' ')}>
|
||||
{
|
||||
items.map((block) => (
|
||||
<a
|
||||
className={[_s.default, _s.width50PC, _s.noUnderline, _s.overflowHidden, _s.cursorPointer, _s.pb5, _s.pr5].join(' ')}
|
||||
target='_blank'
|
||||
rel='noreferrer noopener'
|
||||
href={block.link}
|
||||
title={block.name}
|
||||
>
|
||||
<Image
|
||||
src={block.image}
|
||||
className={[_s.width100PC, _s.height122PX].join(' ')}
|
||||
/>
|
||||
|
||||
<Text
|
||||
align='center'
|
||||
className={[_s.py10, _s.px10].join(' ')}
|
||||
>
|
||||
{block.name}
|
||||
</Text>
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PanelLayout>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import GroupsPanel from '../components/panel/groups_panel'
|
|||
import ListsPanel from '../components/panel/lists_panel'
|
||||
import LinkFooter from '../components/link_footer'
|
||||
import WhoToFollowPanel from '../components/panel/who_to_follow_panel'
|
||||
import ShopPanel from '../components/panel/shop_panel'
|
||||
import ProgressPanel from '../components/panel/progress_panel'
|
||||
import ProPanel from '../components/panel/pro_panel'
|
||||
import UserPanel from '../components/panel/user_panel'
|
||||
|
@ -103,6 +104,7 @@ class HomePage extends PureComponent {
|
|||
<ProgressPanel />
|
||||
<ProPanel isPro={isPro} />
|
||||
<TrendsPanel />
|
||||
<ShopPanel isLazy shouldLoad={lazyLoaded} />
|
||||
<ListsPanel isLazy shouldLoad={lazyLoaded} />
|
||||
<WhoToFollowPanel isLazy shouldLoad={lazyLoaded} />
|
||||
<GroupsPanel isLazy shouldLoad={lazyLoaded} />
|
||||
|
|
|
@ -29,6 +29,7 @@ import relationships from './relationships'
|
|||
import reports from './reports'
|
||||
import search from './search'
|
||||
import settings from './settings'
|
||||
import shop from './shop'
|
||||
import sidebar from './sidebar'
|
||||
import statuses from './statuses'
|
||||
import status_lists from './status_lists'
|
||||
|
@ -69,6 +70,7 @@ const reducers = {
|
|||
reports,
|
||||
search,
|
||||
settings,
|
||||
shop,
|
||||
sidebar,
|
||||
statuses,
|
||||
status_lists,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import {
|
||||
SHOP_FEATURED_PRODUCTS_FETCH_REQUEST,
|
||||
SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS,
|
||||
SHOP_FEATURED_PRODUCTS_FETCH_FAIL,
|
||||
} from '../actions/shop'
|
||||
import {
|
||||
Map as ImmutableMap,
|
||||
List as ImmutableList,
|
||||
fromJS,
|
||||
} from 'immutable'
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
featured: ImmutableMap({
|
||||
items: ImmutableList(),
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
}),
|
||||
})
|
||||
|
||||
export default function suggestionsReducer(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case SHOP_FEATURED_PRODUCTS_FETCH_REQUEST:
|
||||
return state.withMutations((map) => {
|
||||
map.setIn([action.listType, 'isError'], false)
|
||||
map.setIn([action.listType, 'isLoading'], true)
|
||||
})
|
||||
case SHOP_FEATURED_PRODUCTS_FETCH_SUCCESS:
|
||||
return state.withMutations((map) => {
|
||||
map.setIn([action.listType, 'items'], action.items)
|
||||
map.setIn([action.listType, 'isError'], false)
|
||||
map.setIn([action.listType, 'isLoading'], false)
|
||||
})
|
||||
case SHOP_FEATURED_PRODUCTS_FETCH_FAIL:
|
||||
return state.withMutations((map) => {
|
||||
map.setIn([action.listType, 'isError'], true)
|
||||
map.setIn([action.listType, 'isLoading'], false)
|
||||
})
|
||||
default:
|
||||
return state
|
||||
}
|
||||
}
|
|
@ -327,6 +327,7 @@ Rails.application.routes.draw do
|
|||
end
|
||||
|
||||
resources :gab_trends, only: [:index]
|
||||
resources :shop, only: [:index]
|
||||
resources :streaming, only: [:index]
|
||||
resources :custom_emojis, only: [:index]
|
||||
resources :suggestions, only: [:index, :destroy]
|
||||
|
|
Loading…
Reference in New Issue