mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-27 08:00:51 +01:00
Pet catalog updates
This commit is contained in:
parent
b191026ba1
commit
058f8e6dcc
BIN
src/assets/images/catalog/paint-icon.png
Normal file
BIN
src/assets/images/catalog/paint-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 B |
@ -603,7 +603,7 @@ $input-btn-font-family: null !default;
|
|||||||
$input-btn-font-size: $font-size-base !default;
|
$input-btn-font-size: $font-size-base !default;
|
||||||
$input-btn-line-height: $line-height-base !default;
|
$input-btn-line-height: $line-height-base !default;
|
||||||
|
|
||||||
$input-btn-focus-width: .25rem !default;
|
$input-btn-focus-width: 0 !default;
|
||||||
$input-btn-focus-color-opacity: .25 !default;
|
$input-btn-focus-color-opacity: .25 !default;
|
||||||
$input-btn-focus-color: rgba($component-active-bg, $input-btn-focus-color-opacity) !default;
|
$input-btn-focus-color: rgba($component-active-bg, $input-btn-focus-color-opacity) !default;
|
||||||
$input-btn-focus-blur: 0 !default;
|
$input-btn-focus-blur: 0 !default;
|
||||||
|
@ -8,4 +8,5 @@ export class CatalogEvent extends NitroEvent
|
|||||||
public static PURCHASE_SUCCESS: string = 'CE_PURCHASE_SUCCESS';
|
public static PURCHASE_SUCCESS: string = 'CE_PURCHASE_SUCCESS';
|
||||||
public static PURCHASE_FAILED: string = 'CE_PURCHASE_FAILED';
|
public static PURCHASE_FAILED: string = 'CE_PURCHASE_FAILED';
|
||||||
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
||||||
|
public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT';
|
||||||
}
|
}
|
||||||
|
25
src/events/catalog/CatalogNameResultEvent.ts
Normal file
25
src/events/catalog/CatalogNameResultEvent.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { CatalogEvent } from './CatalogEvent';
|
||||||
|
|
||||||
|
export class CatalogNameResultEvent extends CatalogEvent
|
||||||
|
{
|
||||||
|
private _result: number;
|
||||||
|
private _validationInfo: string;
|
||||||
|
|
||||||
|
constructor(result: number, validationInfo: string)
|
||||||
|
{
|
||||||
|
super(CatalogEvent.APPROVE_NAME_RESULT);
|
||||||
|
|
||||||
|
this._result = result;
|
||||||
|
this._validationInfo = validationInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get result(): number
|
||||||
|
{
|
||||||
|
return this._result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get validationInfo(): string
|
||||||
|
{
|
||||||
|
return this._validationInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export * from './CatalogEvent';
|
export * from './CatalogEvent';
|
||||||
|
export * from './CatalogNameResultEvent';
|
||||||
export * from './CatalogPurchasedEvent';
|
export * from './CatalogPurchasedEvent';
|
||||||
export * from './CatalogPurchaseFailureEvent';
|
export * from './CatalogPurchaseFailureEvent';
|
||||||
export * from './CatalogPurchaseSoldOutEvent';
|
export * from './CatalogPurchaseSoldOutEvent';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { CatalogPageEvent, CatalogPagesEvent, CatalogPurchaseEvent, CatalogPurchaseFailedEvent, CatalogPurchaseUnavailableEvent, CatalogSearchEvent, CatalogSoldOutEvent } from 'nitro-renderer';
|
import { CatalogApproveNameResultEvent, CatalogPageEvent, CatalogPagesEvent, CatalogPurchaseEvent, CatalogPurchaseFailedEvent, CatalogPurchaseUnavailableEvent, CatalogSearchEvent, CatalogSoldOutEvent, SellablePetPalettesEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CatalogPurchaseFailureEvent } from '../../events';
|
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent } from '../../events';
|
||||||
import { CatalogPurchasedEvent } from '../../events/catalog/CatalogPurchasedEvent';
|
import { CatalogPurchasedEvent } from '../../events/catalog/CatalogPurchasedEvent';
|
||||||
import { CatalogPurchaseSoldOutEvent } from '../../events/catalog/CatalogPurchaseSoldOutEvent';
|
import { CatalogPurchaseSoldOutEvent } from '../../events/catalog/CatalogPurchaseSoldOutEvent';
|
||||||
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
@ -8,6 +8,7 @@ import { CreateMessageHook } from '../../hooks/messages/message-event';
|
|||||||
import { CatalogMessageHandlerProps } from './CatalogMessageHandler.types';
|
import { CatalogMessageHandlerProps } from './CatalogMessageHandler.types';
|
||||||
import { useCatalogContext } from './context/CatalogContext';
|
import { useCatalogContext } from './context/CatalogContext';
|
||||||
import { CatalogActions } from './reducers/CatalogReducer';
|
import { CatalogActions } from './reducers/CatalogReducer';
|
||||||
|
import { CatalogPetPalette } from './utils/CatalogPetPalette';
|
||||||
|
|
||||||
export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
@ -75,6 +76,24 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
|||||||
});
|
});
|
||||||
}, [ dispatchCatalogState ]);
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
|
const onSellablePetPalettesEvent = useCallback((event: SellablePetPalettesEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
const petPalette = new CatalogPetPalette(parser.productCode, parser.palettes.slice());
|
||||||
|
|
||||||
|
dispatchCatalogState({
|
||||||
|
type: CatalogActions.SET_PET_PALETTE,
|
||||||
|
payload: { petPalette }
|
||||||
|
});
|
||||||
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
|
const onCatalogApproveNameResultEvent = useCallback((event: CatalogApproveNameResultEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchUiEvent(new CatalogNameResultEvent(parser.result, parser.validationInfo));
|
||||||
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(CatalogPagesEvent, onCatalogPagesEvent);
|
CreateMessageHook(CatalogPagesEvent, onCatalogPagesEvent);
|
||||||
CreateMessageHook(CatalogPageEvent, onCatalogPageEvent);
|
CreateMessageHook(CatalogPageEvent, onCatalogPageEvent);
|
||||||
CreateMessageHook(CatalogPurchaseEvent, onCatalogPurchaseEvent);
|
CreateMessageHook(CatalogPurchaseEvent, onCatalogPurchaseEvent);
|
||||||
@ -82,6 +101,8 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
|||||||
CreateMessageHook(CatalogPurchaseUnavailableEvent, onCatalogPurchaseUnavailableEvent);
|
CreateMessageHook(CatalogPurchaseUnavailableEvent, onCatalogPurchaseUnavailableEvent);
|
||||||
CreateMessageHook(CatalogSoldOutEvent, onCatalogSoldOutEvent);
|
CreateMessageHook(CatalogSoldOutEvent, onCatalogSoldOutEvent);
|
||||||
CreateMessageHook(CatalogSearchEvent, onCatalogSearchEvent);
|
CreateMessageHook(CatalogSearchEvent, onCatalogSearchEvent);
|
||||||
|
CreateMessageHook(SellablePetPalettesEvent, onSellablePetPalettesEvent);
|
||||||
|
CreateMessageHook(CatalogApproveNameResultEvent, onCatalogApproveNameResultEvent);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { CatalogPageOfferData, ICatalogPageData, ICatalogPageParser } from 'nitro-renderer';
|
import { CatalogPageOfferData, ICatalogPageData, ICatalogPageParser } from 'nitro-renderer';
|
||||||
import { Reducer } from 'react';
|
import { Reducer } from 'react';
|
||||||
|
import { CatalogPetPalette } from '../utils/CatalogPetPalette';
|
||||||
import { ICatalogOffers, ICatalogSearchResult, SetOffersToNodes } from '../utils/CatalogUtilities';
|
import { ICatalogOffers, ICatalogSearchResult, SetOffersToNodes } from '../utils/CatalogUtilities';
|
||||||
|
|
||||||
export interface ICatalogState
|
export interface ICatalogState
|
||||||
@ -10,6 +11,7 @@ export interface ICatalogState
|
|||||||
pageParser: ICatalogPageParser;
|
pageParser: ICatalogPageParser;
|
||||||
activeOffer: CatalogPageOfferData;
|
activeOffer: CatalogPageOfferData;
|
||||||
searchResult: ICatalogSearchResult;
|
searchResult: ICatalogSearchResult;
|
||||||
|
petPalettes: CatalogPetPalette[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICatalogAction
|
export interface ICatalogAction
|
||||||
@ -22,6 +24,7 @@ export interface ICatalogAction
|
|||||||
pageParser?: ICatalogPageParser;
|
pageParser?: ICatalogPageParser;
|
||||||
activeOffer?: CatalogPageOfferData;
|
activeOffer?: CatalogPageOfferData;
|
||||||
searchResult?: ICatalogSearchResult;
|
searchResult?: ICatalogSearchResult;
|
||||||
|
petPalette?: CatalogPetPalette;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +35,7 @@ export class CatalogActions
|
|||||||
public static SET_CATALOG_PAGE_PARSER: string = 'CA_SET_CATALOG_PAGE';
|
public static SET_CATALOG_PAGE_PARSER: string = 'CA_SET_CATALOG_PAGE';
|
||||||
public static SET_CATALOG_ACTIVE_OFFER: string = 'CA_SET_ACTIVE_OFFER';
|
public static SET_CATALOG_ACTIVE_OFFER: string = 'CA_SET_ACTIVE_OFFER';
|
||||||
public static SET_SEARCH_RESULT: string = 'CA_SET_SEARCH_RESULT';
|
public static SET_SEARCH_RESULT: string = 'CA_SET_SEARCH_RESULT';
|
||||||
|
public static SET_PET_PALETTE: string = 'CA_SET_PET_PALETTE';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialCatalog: ICatalogState = {
|
export const initialCatalog: ICatalogState = {
|
||||||
@ -40,7 +44,8 @@ export const initialCatalog: ICatalogState = {
|
|||||||
currentTab: null,
|
currentTab: null,
|
||||||
pageParser: null,
|
pageParser: null,
|
||||||
activeOffer: null,
|
activeOffer: null,
|
||||||
searchResult: null
|
searchResult: null,
|
||||||
|
petPalettes: []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, action) =>
|
export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, action) =>
|
||||||
@ -64,7 +69,7 @@ export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, ac
|
|||||||
return { ...state, currentTab, searchResult };
|
return { ...state, currentTab, searchResult };
|
||||||
}
|
}
|
||||||
case CatalogActions.SET_CATALOG_PAGE_PARSER: {
|
case CatalogActions.SET_CATALOG_PAGE_PARSER: {
|
||||||
const pageParser = action.payload.pageParser;
|
let pageParser = Object.create(action.payload.pageParser);
|
||||||
let activeOffer = null;
|
let activeOffer = null;
|
||||||
|
|
||||||
if(pageParser.layoutCode === 'single_bundle')
|
if(pageParser.layoutCode === 'single_bundle')
|
||||||
@ -91,6 +96,27 @@ export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, ac
|
|||||||
|
|
||||||
return { ...state, searchResult };
|
return { ...state, searchResult };
|
||||||
}
|
}
|
||||||
|
case CatalogActions.SET_PET_PALETTE: {
|
||||||
|
const petPalette = (action.payload.petPalette || null);
|
||||||
|
|
||||||
|
let petPalettes = [ ...state.petPalettes ];
|
||||||
|
|
||||||
|
for(let i = 0; i < petPalettes.length; i++)
|
||||||
|
{
|
||||||
|
const palette = petPalettes[i];
|
||||||
|
|
||||||
|
if(palette.breed === petPalette.breed)
|
||||||
|
{
|
||||||
|
petPalettes.splice(i, 1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
petPalettes.push(petPalette);
|
||||||
|
|
||||||
|
return { ...state, petPalettes };
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
9
src/views/catalog/utils/CatalogPetPalette.ts
Normal file
9
src/views/catalog/utils/CatalogPetPalette.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { SellablePetPaletteData } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export class CatalogPetPalette
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
public breed: string,
|
||||||
|
public palettes: SellablePetPaletteData[]
|
||||||
|
) {}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { CatalogPageOfferData, ICatalogPageData, ICatalogPageParser, IFurnitureData } from 'nitro-renderer';
|
import { CatalogPageOfferData, ICatalogPageData, ICatalogPageParser, IFurnitureData, SellablePetPaletteData } from 'nitro-renderer';
|
||||||
|
import { GetRoomEngine } from '../../../api';
|
||||||
import { GetProductDataForLocalization } from '../../../api/nitro/session/GetProductDataForLocalization';
|
import { GetProductDataForLocalization } from '../../../api/nitro/session/GetProductDataForLocalization';
|
||||||
import { GetConfiguration } from '../../../utils/GetConfiguration';
|
import { GetConfiguration } from '../../../utils/GetConfiguration';
|
||||||
|
|
||||||
@ -88,3 +89,65 @@ export function GetCatalogPageText(page: ICatalogPageParser, index: number = 0):
|
|||||||
|
|
||||||
return (message || '');
|
return (message || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function GetPetIndexFromLocalization(localization: string)
|
||||||
|
{
|
||||||
|
if(!localization.length) return 0;
|
||||||
|
|
||||||
|
let index = (localization.length - 1);
|
||||||
|
|
||||||
|
while(index >= 0)
|
||||||
|
{
|
||||||
|
if(isNaN(parseInt(localization.charAt(index)))) break;
|
||||||
|
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(index > 0) return parseInt(localization.substring(index + 1));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetPetAvailableColors(petIndex: number, palettes: SellablePetPaletteData[]): number[][]
|
||||||
|
{
|
||||||
|
switch(petIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return [[16743226], [16750435], [16764339], [0xF59500], [16498012], [16704690], [0xEDD400], [16115545], [16513201], [8694111], [11585939], [14413767], [6664599], [9553845], [12971486], [8358322], [10002885], [13292268], [10780600], [12623573], [14403561], [12418717], [14327229], [15517403], [14515069], [15764368], [16366271], [0xABABAB], [0xD4D4D4], [0xFFFFFF], [14256481], [14656129], [15848130], [14005087], [14337152], [15918540], [15118118], [15531929], [9764857], [11258085]];
|
||||||
|
case 1:
|
||||||
|
return [[16743226], [16750435], [16764339], [0xF59500], [16498012], [16704690], [0xEDD400], [16115545], [16513201], [8694111], [11585939], [14413767], [6664599], [9553845], [12971486], [8358322], [10002885], [13292268], [10780600], [12623573], [14403561], [12418717], [14327229], [15517403], [14515069], [15764368], [16366271], [0xABABAB], [0xD4D4D4], [0xFFFFFF], [14256481], [14656129], [15848130], [14005087], [14337152], [15918540], [15118118], [15531929], [9764857], [11258085]];
|
||||||
|
case 2:
|
||||||
|
return [[16579283], [15378351], [8830016], [15257125], [9340985], [8949607], [6198292], [8703620], [9889626], [8972045], [12161285], [13162269], [8620113], [12616503], [8628101], [0xD2FF00], [9764857]];
|
||||||
|
case 3:
|
||||||
|
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD]];
|
||||||
|
case 4:
|
||||||
|
return [[0xFFFFFF], [16053490], [15464440], [16248792], [15396319], [15007487]];
|
||||||
|
case 5:
|
||||||
|
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD]];
|
||||||
|
case 6:
|
||||||
|
return [[0xFFFFFF], [0xEEEEEE], [0xDDDDDD], [16767177], [16770205], [16751331]];
|
||||||
|
case 7:
|
||||||
|
return [[0xCCCCCC], [0xAEAEAE], [16751331], [10149119], [16763290], [16743786]];
|
||||||
|
default: {
|
||||||
|
const colors: number[][] = [];
|
||||||
|
|
||||||
|
for(const palette of palettes)
|
||||||
|
{
|
||||||
|
const petColorResult = GetRoomEngine().getPetColorResult(petIndex, palette.paletteId);
|
||||||
|
|
||||||
|
if(!petColorResult) continue;
|
||||||
|
|
||||||
|
if(petColorResult._Str_5845 === petColorResult._Str_6659)
|
||||||
|
{
|
||||||
|
colors.push([ petColorResult._Str_5845 ]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colors.push([ petColorResult._Str_5845, petColorResult._Str_6659 ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@import './default/CatalogLayoutDefaultView';
|
@import './default/CatalogLayoutDefaultView';
|
||||||
|
@import './pets/CatalogLayoutPetView';
|
||||||
@import './single-bundle/CatalogLayoutSingleBundleView';
|
@import './single-bundle/CatalogLayoutSingleBundleView';
|
||||||
@import './spaces-new/CatalogLayoutSpacesView';
|
@import './spaces-new/CatalogLayoutSpacesView';
|
||||||
@import './trophies/CatalogLayoutTrophiesView';
|
@import './trophies/CatalogLayoutTrophiesView';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { ICatalogPageParser, RoomPreviewer } from 'nitro-renderer';
|
import { ICatalogPageParser, RoomPreviewer } from 'nitro-renderer';
|
||||||
import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView';
|
import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView';
|
||||||
|
import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView';
|
||||||
import { CatalogLayoutSingleBundleView } from './single-bundle/CatalogLayoutSingleBundleView';
|
import { CatalogLayoutSingleBundleView } from './single-bundle/CatalogLayoutSingleBundleView';
|
||||||
import { CatalogLayoutSpacesView } from './spaces-new/CatalogLayoutSpacesView';
|
import { CatalogLayoutSpacesView } from './spaces-new/CatalogLayoutSpacesView';
|
||||||
import { CatalogLayoutTrophiesView } from './trophies/CatalogLayoutTrophiesView';
|
import { CatalogLayoutTrophiesView } from './trophies/CatalogLayoutTrophiesView';
|
||||||
@ -13,7 +14,7 @@ export function GetCatalogLayout(pageParser: ICatalogPageParser, roomPreviewer:
|
|||||||
case 'frontpage4':
|
case 'frontpage4':
|
||||||
return null;
|
return null;
|
||||||
case 'pets':
|
case 'pets':
|
||||||
return null;
|
return <CatalogLayoutPetView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'pets2':
|
case 'pets2':
|
||||||
return null;
|
return null;
|
||||||
case 'pets3':
|
case 'pets3':
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
.nitro-catalog-layout-pets {
|
||||||
|
|
||||||
|
.color-button {
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@import './name-approval/CatalogPetNameApprovalView';
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
import { CatalogRequestPetBreedsComposer, ColorConverter, SellablePetPaletteData } from 'nitro-renderer';
|
||||||
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { GetProductDataForLocalization } from '../../../../../../api/nitro/session/GetProductDataForLocalization';
|
||||||
|
import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
|
||||||
|
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||||
|
import { PetImageView } from '../../../../../pet-image/PetImageView';
|
||||||
|
import { RoomPreviewerView } from '../../../../../room-previewer/RoomPreviewerView';
|
||||||
|
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||||
|
import { CatalogActions } from '../../../../reducers/CatalogReducer';
|
||||||
|
import { GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../utils/CatalogUtilities';
|
||||||
|
import { CatalogLayoutPetViewProps } from './CatalogLayoutPetView.types';
|
||||||
|
import { CatalogLayoutPetPurchaseView } from './purchase/CatalogLayoutPetPurchaseView';
|
||||||
|
|
||||||
|
export const CatalogLayoutPetView: FC<CatalogLayoutPetViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { roomPreviewer = null, pageParser = null } = props;
|
||||||
|
const { catalogState = null, dispatchCatalogState = null } = useCatalogContext();
|
||||||
|
const { activeOffer = null, petPalettes = [] } = catalogState;
|
||||||
|
const [ petIndex, setPetIndex ] = useState(-1);
|
||||||
|
const [ sellablePalettes, setSellablePalettes ] = useState<SellablePetPaletteData[]>([]);
|
||||||
|
const [ selectedPaletteIndex, setSelectedPaletteIndex ] = useState(-1);
|
||||||
|
const [ sellableColors, setSellableColors ] = useState<number[][]>([]);
|
||||||
|
const [ selectedColorIndex, setSelectedColorIndex ] = useState(-1);
|
||||||
|
const [ colorsShowing, setColorsShowing ] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!pageParser || !pageParser.offers.length) return;
|
||||||
|
|
||||||
|
const offer = pageParser.offers[0];
|
||||||
|
|
||||||
|
dispatchCatalogState({
|
||||||
|
type: CatalogActions.SET_CATALOG_ACTIVE_OFFER,
|
||||||
|
payload: {
|
||||||
|
activeOffer: offer
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setPetIndex(GetPetIndexFromLocalization(offer.localizationId));
|
||||||
|
setColorsShowing(false);
|
||||||
|
}, [ pageParser, dispatchCatalogState ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!activeOffer) return;
|
||||||
|
|
||||||
|
const productData = GetProductDataForLocalization(activeOffer.localizationId);
|
||||||
|
|
||||||
|
if(!productData) return;
|
||||||
|
|
||||||
|
for(const paletteData of petPalettes)
|
||||||
|
{
|
||||||
|
if(paletteData.breed !== productData.type) continue;
|
||||||
|
|
||||||
|
const palettes: SellablePetPaletteData[] = [];
|
||||||
|
|
||||||
|
for(const palette of paletteData.palettes)
|
||||||
|
{
|
||||||
|
if(!palette.sellable) continue;
|
||||||
|
|
||||||
|
palettes.push(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedPaletteIndex((palettes.length ? 0 : -1));
|
||||||
|
setSellablePalettes(palettes);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectedPaletteIndex(-1);
|
||||||
|
setSellablePalettes([]);
|
||||||
|
|
||||||
|
SendMessageHook(new CatalogRequestPetBreedsComposer(productData.type));
|
||||||
|
}, [ activeOffer, petPalettes ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(petIndex === -1) return;
|
||||||
|
|
||||||
|
const colors = GetPetAvailableColors(petIndex, sellablePalettes);
|
||||||
|
|
||||||
|
setSelectedColorIndex((colors.length ? 0 : -1));
|
||||||
|
setSellableColors(colors);
|
||||||
|
}, [ petIndex, sellablePalettes ]);
|
||||||
|
|
||||||
|
const getColor = useMemo(() =>
|
||||||
|
{
|
||||||
|
if(!sellableColors.length || (selectedColorIndex === -1)) return 0xFFFFFF;
|
||||||
|
|
||||||
|
return sellableColors[selectedColorIndex][0];
|
||||||
|
}, [ sellableColors, selectedColorIndex ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!roomPreviewer) return;
|
||||||
|
|
||||||
|
roomPreviewer && roomPreviewer.reset(false);
|
||||||
|
|
||||||
|
if((petIndex === -1) || !sellablePalettes.length || (selectedPaletteIndex === -1)) return;
|
||||||
|
|
||||||
|
let petFigureString = `${ petIndex } ${ sellablePalettes[selectedPaletteIndex].paletteId }`;
|
||||||
|
|
||||||
|
if(petIndex <= 7) petFigureString += ` ${ getColor.toString(16) }`;
|
||||||
|
|
||||||
|
roomPreviewer.addPetIntoRoom(petFigureString);
|
||||||
|
}, [ roomPreviewer, petIndex, sellablePalettes, selectedPaletteIndex, getColor ]);
|
||||||
|
|
||||||
|
const petBreedName = useMemo(() =>
|
||||||
|
{
|
||||||
|
if((petIndex === -1) || !sellablePalettes.length || (selectedPaletteIndex === -1)) return '';
|
||||||
|
|
||||||
|
return LocalizeText(`pet.breed.${ petIndex }.${ sellablePalettes[selectedPaletteIndex].breedId }`);
|
||||||
|
}, [ petIndex, sellablePalettes, selectedPaletteIndex ]);
|
||||||
|
|
||||||
|
if(!activeOffer) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row h-100 nitro-catalog-layout-pets">
|
||||||
|
<div className="col-7">
|
||||||
|
<div className="row row-cols-5 align-content-start g-0 mb-n1 w-100 catalog-offers-container single-bundle-items-container">
|
||||||
|
{ colorsShowing && (sellableColors.length > 0) && sellableColors.map((colorSet, index) =>
|
||||||
|
{
|
||||||
|
return <div key={ index } className="col pe-1 pb-1 catalog-offer-item-container">
|
||||||
|
<div className={ 'position-relative border border-2 rounded catalog-offer-item cursor-pointer ' + ((selectedColorIndex === index) ? 'active ' : '') } style={ { backgroundColor: ColorConverter.int2rgb(colorSet[0]) } } onClick={ event => setSelectedColorIndex(index) }>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
})}
|
||||||
|
{ !colorsShowing && (sellablePalettes.length > 0) && sellablePalettes.map((palette, index) =>
|
||||||
|
{
|
||||||
|
return <div key={ index } className="col pe-1 pb-1 catalog-offer-item-container">
|
||||||
|
<div className={ 'position-relative border border-2 rounded catalog-offer-item cursor-pointer ' + ((selectedPaletteIndex === index) ? 'active ' : '') } onClick={ event => setSelectedPaletteIndex(index) }>
|
||||||
|
<PetImageView typeId={ petIndex } paletteId={ palette.paletteId } direction={ 2 } headOnly={ true } />
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}) }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="position-relative d-flex flex-column col-5">
|
||||||
|
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 }>
|
||||||
|
{ (petIndex > -1 && petIndex <= 7) &&
|
||||||
|
<button type="button" className= { 'btn btn-primary btn-sm color-button ' + (colorsShowing ? 'active ' : '') } onClick={ event => setColorsShowing(!colorsShowing) }>
|
||||||
|
<i className="fas fa-fill-drip" />
|
||||||
|
</button> }
|
||||||
|
</RoomPreviewerView>
|
||||||
|
<div className="fs-6 text-black mt-1 overflow-hidden">{ petBreedName }</div>
|
||||||
|
<CatalogLayoutPetPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||||
|
|
||||||
|
export interface CatalogLayoutPetViewProps extends CatalogLayoutProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../../../utils/LocalizeText';
|
||||||
|
import { CatalogPetNameApprovalViewProps } from './CatalogPetNameApprovalView.types';
|
||||||
|
|
||||||
|
export const CatalogPetNameApprovalView: FC<CatalogPetNameApprovalViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { petNameValue = null, setPetNameValue = null } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('widgets.petpackage.name.title') } value={ petNameValue } onChange={ event => setPetNameValue(event.target.value) } />
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
|
||||||
|
export interface CatalogPetNameApprovalViewProps
|
||||||
|
{
|
||||||
|
petNameValue: string;
|
||||||
|
setPetNameValue: Dispatch<SetStateAction<string>>;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import { FC, useState } from 'react';
|
||||||
|
import { CurrencyIcon } from '../../../../../../../utils/currency-icon/CurrencyIcon';
|
||||||
|
import { LocalizeText } from '../../../../../../../utils/LocalizeText';
|
||||||
|
import { CatalogPurchaseButtonView } from '../../../purchase/purchase-button/CatalogPurchaseButtonView';
|
||||||
|
import { CatalogPetNameApprovalView } from '../name-approval/CatalogPetNameApprovalView';
|
||||||
|
import { CatalogLayoutPetPurchaseViewProps } from './CatalogLayoutPetPurchaseView.types';
|
||||||
|
|
||||||
|
export const CatalogLayoutPetPurchaseView: FC<CatalogLayoutPetPurchaseViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { offer = null, pageId = -1, extra = '' } = props;
|
||||||
|
const [ petNameValue, setPetNameValue ] = useState('');
|
||||||
|
|
||||||
|
const extraData = ((extra && extra.length) ? extra : (offer?.products[0]?.extraParam || null));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="d-flex flex-grow-1 justify-content-center align-items-center">
|
||||||
|
<CatalogPetNameApprovalView petNameValue={ petNameValue } setPetNameValue={ setPetNameValue } />
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-column flex-grow-1 justify-content-end w-100">
|
||||||
|
<div className="d-flex align-items-end">
|
||||||
|
<div className="flex-grow-1 align-items-end">
|
||||||
|
<span className="text-black">{ LocalizeText('catalog.bundlewidget.price') }</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-column">
|
||||||
|
{ (offer.priceCredits > 0) &&
|
||||||
|
<div className="d-flex align-items-center justify-content-end">
|
||||||
|
<span className="text-black ms-1">{ offer.priceCredits }</span>
|
||||||
|
<CurrencyIcon type={ -1 } />
|
||||||
|
</div> }
|
||||||
|
{ (offer.priceActivityPoints > 0) &&
|
||||||
|
<div className="d-flex align-items-center justify-content-end">
|
||||||
|
<span className="text-black ms-1">{ offer.priceActivityPoints }</span>
|
||||||
|
<CurrencyIcon type={ offer.priceActivityPointsType } />
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-column mt-1">
|
||||||
|
<CatalogPurchaseButtonView className="btn-sm w-100" offer={ offer } pageId={ pageId } extra={ extraData } quantity={ 1 } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import { CatalogPageOfferData } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export interface CatalogLayoutPetPurchaseViewProps
|
||||||
|
{
|
||||||
|
offer: CatalogPageOfferData;
|
||||||
|
pageId: number;
|
||||||
|
extra?: string;
|
||||||
|
}
|
@ -6,14 +6,14 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-color: $grid-border-color !important;
|
border-color: $grid-border-color !important;
|
||||||
background-color: $grid-bg-color !important;
|
background-color: $grid-bg-color;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-color: $grid-active-border-color !important;
|
border-color: $grid-active-border-color !important;
|
||||||
background-color: $grid-active-bg-color !important;
|
background-color: $grid-active-bg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
|
@ -113,7 +113,7 @@ export const CatalogSearchView: FC<CatalogSearchViewProps> = props =>
|
|||||||
return (
|
return (
|
||||||
<div className="d-flex mb-1">
|
<div className="d-flex mb-1">
|
||||||
<div className="d-flex flex-grow-1 me-1">
|
<div className="d-flex flex-grow-1 me-1">
|
||||||
<input type="text" className="form-control form-control-sm" placeholder="search" value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<button type="button" className="btn btn-primary btn-sm">
|
<button type="button" className="btn btn-primary btn-sm">
|
||||||
|
@ -57,5 +57,5 @@ export const PetImageView: FC<PetImageViewProps> = props =>
|
|||||||
|
|
||||||
const url = `url('${ petUrl }')`;
|
const url = `url('${ petUrl }')`;
|
||||||
|
|
||||||
return <div className={ 'pet-image scale-' + scale } style={ (petUrl && url.length) ? { backgroundImage: url } : {} }></div>;
|
return <div className={ 'pet-image scale-' + scale.toString().replace('.', '-') } style={ (petUrl && url.length) ? { backgroundImage: url } : {} }></div>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user