Catalog done for now

This commit is contained in:
Bill 2022-02-05 23:28:18 -05:00
parent 6f4a41ff33
commit 52810938df
7 changed files with 50 additions and 30 deletions

View File

@ -10,6 +10,14 @@
min-width: 30px;
width: 30px;
}
.quantity-input {
min-height: 17px;
height: 17px;
width: 20px;
padding: 0 4px;
text-align: right;
}
}
.catalog-icon-image {

View File

@ -3,6 +3,7 @@ import { PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer';
import classNames from 'classnames';
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { GetSessionDataManager, LocalizeText } from '../../../../api';
import { Base } from '../../../../common/Base';
import { Button } from '../../../../common/Button';
import { ButtonGroup } from '../../../../common/ButtonGroup';
import { Column } from '../../../../common/Column';
@ -16,12 +17,14 @@ import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGi
import { CurrencyIcon } from '../../../../views/shared/currency-icon/CurrencyIcon';
import { FurniImageView } from '../../../../views/shared/furni-image/FurniImageView';
import { useCatalogContext } from '../../CatalogContext';
import { ProductTypeEnum } from '../../common/ProductTypeEnum';
export const CatalogGiftView: FC<{}> = props =>
{
const [ isVisible, setIsVisible ] = useState<boolean>(false);
const [ pageId, setPageId ] = useState<number>(0);
const [ offerId, setOfferId ] = useState<number>(0);
const [ extraData, setExtraData ] = useState<string>('');
const [ receiverName, setReceiverName ] = useState<string>('');
const [ showMyFace, setShowMyFace ] = useState<boolean>(true);
const [ message, setMessage ] = useState<string>('');
@ -42,6 +45,7 @@ export const CatalogGiftView: FC<{}> = props =>
setIsVisible(false);
setPageId(0);
setOfferId(0);
setExtraData('');
setReceiverName('');
setShowMyFace(true);
setMessage('');
@ -68,6 +72,7 @@ export const CatalogGiftView: FC<{}> = props =>
setPageId(castedEvent.pageId);
setOfferId(castedEvent.offerId);
setExtraData(castedEvent.extraData);
setIsVisible(true);
});
return;
@ -86,7 +91,7 @@ export const CatalogGiftView: FC<{}> = props =>
return giftConfiguration ? (giftConfiguration.defaultStuffTypes.findIndex(s => (s === giftConfiguration.boxTypes[selectedBoxIndex])) > -1) : true;
}, [ giftConfiguration, selectedBoxIndex ]);
const extraData = useMemo(() =>
const boxExtraData = useMemo(() =>
{
if(!giftConfiguration) return '';
@ -176,18 +181,19 @@ export const CatalogGiftView: FC<{}> = props =>
<FormGroup column>
<Text>{ LocalizeText('catalog.gift_wrapping.receiver') }</Text>
<input type="text" className={ 'form-control form-control-sm' + classNames({ ' is-invalid': receiverNotFound }) } value={ receiverName } onChange={ (e) => setReceiverName(e.target.value) } />
{ receiverNotFound && <div className="invalid-feedback">{ LocalizeText('catalog.gift_wrapping.receiver_not_found.title') }</div> }
{ receiverNotFound &&
<Base className="invalid-feedback">{ LocalizeText('catalog.gift_wrapping.receiver_not_found.title') }</Base> }
</FormGroup>
<NitroLayoutGiftCardView figure={ GetSessionDataManager().figure } userName={ GetSessionDataManager().userName } message={ message } editable={ true } onChange={ (value) => setMessage(value) } />
<div className="form-check">
<Base className="form-check">
<input className="form-check-input" type="checkbox" name="showMyFace" checked={ showMyFace } onChange={ (e) => setShowMyFace(value => !value) } />
<label className="form-check-label">{ LocalizeText('catalog.gift_wrapping.show_face.title') }</label>
</div>
</Base>
<Flex alignItems="center" gap={ 2 }>
{ selectedColorId &&
<div className="gift-preview">
<FurniImageView spriteId={ selectedColorId } type="s" extras={ extraData } />
</div> }
<Base className="gift-preview">
<FurniImageView productType={ ProductTypeEnum.FLOOR } productClassId={ selectedColorId } extraData={ boxExtraData } />
</Base> }
<Column gap={ 1 }>
<Flex gap={ 2 }>
<ButtonGroup>

View File

@ -25,7 +25,6 @@ export const CatalogLayoutVipGiftsView: FC<CatalogLayoutProps> = props =>
if(subscriptionInfo.isVip) return LocalizeText('catalog.club_gift.not_available');
return LocalizeText('catalog.club_gift.no_club');
}, [ clubGifts, subscriptionInfo ]);
const selectGift = useCallback((localizationId: string) =>

View File

@ -3,9 +3,10 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { CreateLinkEvent, GetClubMemberLevel, LocalizeText } from '../../../../../api';
import { Button } from '../../../../../common/Button';
import { CatalogEvent, CatalogPurchasedEvent, CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent } from '../../../../../events';
import { CatalogInitGiftEvent } from '../../../../../events/catalog/CatalogInitGiftEvent';
import { CatalogInitPurchaseEvent } from '../../../../../events/catalog/CatalogInitPurchaseEvent';
import { CatalogWidgetEvent } from '../../../../../events/catalog/CatalogWidgetEvent';
import { SendMessageHook, useUiEvent } from '../../../../../hooks';
import { dispatchUiEvent, SendMessageHook, useUiEvent } from '../../../../../hooks';
import { LoadingSpinnerView } from '../../../../../layout';
import { GetCurrencyAmount } from '../../../../../views/purse/common/CurrencyHelper';
import { useCatalogContext } from '../../../CatalogContext';
@ -87,6 +88,13 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
return;
}
if(isGift)
{
dispatchUiEvent(new CatalogInitGiftEvent(currentOffer.page.pageId, currentOffer.offerId, extraData));
return;
}
setPurchaseState(CatalogPurchaseState.PURCHASE);
if(purchaseCallback)
@ -108,8 +116,6 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
SendMessageHook(new PurchaseFromCatalogComposer(pageId, currentOffer.offerId, extraData, quantity));
}, [ currentOffer, purchaseCallback, extraData, quantity, getNodesByOfferId ]);
// dispatchUiEvent(new CatalogInitGiftEvent(pageId, offer.offerId, extra)); setup gift
useEffect(() =>
{
if(!currentOffer) return;
@ -171,7 +177,7 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
<>
<PurchaseButton />
{ (!noGiftOption && !currentOffer.isRentOffer) &&
<Button disabled={ ((quantity > 1) || !currentOffer.giftable || isLimitedSoldOut || (extraParamRequired && (!extraData || !extraData.length))) }>
<Button disabled={ ((quantity > 1) || !currentOffer.giftable || isLimitedSoldOut || (extraParamRequired && (!extraData || !extraData.length))) } onClick={ event => purchase(true) }>
{ LocalizeText('catalog.purchase_confirmation.gift') }
</Button> }
</>

View File

@ -15,6 +15,8 @@ export const CatalogSpinnerWidgetView: FC<{}> = props =>
const updateQuantity = (value: number) =>
{
if(isNaN(value)) value = 1;
value = Math.max(value, MIN_VALUE);
value = Math.min(value, MAX_VALUE);

View File

@ -1,20 +1,27 @@
import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react';
import { GetRoomEngine } from '../../../api';
import { Base } from '../../../common/Base';
import { ProductTypeEnum } from '../../../components/catalog/common/ProductTypeEnum';
import { FurniImageViewProps } from './FurniImageView.types';
interface FurniImageViewProps
{
productType: string;
productClassId: number;
direction?: number;
extraData?: string;
scale?: number;
}
export const FurniImageView: FC<FurniImageViewProps> = props =>
{
const { type = 's', spriteId = -1, direction = 0, extras = '', scale = 1 } = props;
const { productType = 's', productClassId = -1, direction = 0, extraData = '', scale = 1 } = props;
const [ imageElement, setImageElement ] = useState<HTMLImageElement>(null);
const buildImage = useCallback(() =>
{
let imageResult: ImageResult = null;
const furniType = type.toLocaleLowerCase();
const listener: IGetImageListener = {
imageReady: (id, texture, image) =>
{
@ -28,13 +35,13 @@ export const FurniImageView: FC<FurniImageViewProps> = props =>
imageFailed: null
};
switch(furniType)
switch(productType.toLocaleLowerCase())
{
case ProductTypeEnum.FLOOR:
imageResult = GetRoomEngine().getFurnitureFloorImage(spriteId, new Vector3d(direction), 64, listener, 0, extras);
imageResult = GetRoomEngine().getFurnitureFloorImage(productClassId, new Vector3d(direction), 64, listener, 0, extraData);
break;
case ProductTypeEnum.WALL:
imageResult = GetRoomEngine().getFurnitureWallImage(spriteId, new Vector3d(direction), 64, listener, 0, extras);
imageResult = GetRoomEngine().getFurnitureWallImage(productClassId, new Vector3d(direction), 64, listener, 0, extraData);
break;
}
@ -44,7 +51,7 @@ export const FurniImageView: FC<FurniImageViewProps> = props =>
image.onload = () => setImageElement(image);
}
}, [ type, spriteId, direction, extras ]);
}, [ productType, productClassId, direction, extraData ]);
useEffect(() =>
{
@ -55,5 +62,5 @@ export const FurniImageView: FC<FurniImageViewProps> = props =>
const imageUrl = `url('${ imageElement.src }')`;
return <div className={ 'furni-image scale-' + scale } style={ { backgroundImage: imageUrl, width: imageElement.width, height: imageElement.height } }></div>;
return <Base classNames={ [ 'furni-image', `scale-${ scale }` ] } style={ { backgroundImage: imageUrl, width: imageElement.width, height: imageElement.height } } />;
}

View File

@ -1,8 +0,0 @@
export interface FurniImageViewProps
{
type: string;
spriteId: number;
direction?: number;
extras?: string;
scale?: number;
}