Skip to content

Commit

Permalink
wip: launchpad admin marketing edition: finish banner
Browse files Browse the repository at this point in the history
  • Loading branch information
WaDadidou committed Aug 21, 2024
1 parent 1668e29 commit e7f059a
Show file tree
Hide file tree
Showing 12 changed files with 336 additions and 87 deletions.
23 changes: 23 additions & 0 deletions packages/components/carousels/LeftRightButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React, { FC } from "react";
import { TouchableOpacity, View } from "react-native";

import chevronLeftSVG from "@/assets/icons/chevron-left.svg";
import chevronRightSVG from "@/assets/icons/chevron-right.svg";
import { SVG } from "@/components/SVG";

export const LeftRightButtons: FC<{
onPressPrev?: () => void;
onPressNext?: () => void;
}> = ({ onPressPrev, onPressNext }) => {
return (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<TouchableOpacity onPress={onPressPrev} style={{ marginRight: 24 }}>
<SVG width={16} height={16} source={chevronLeftSVG} />
</TouchableOpacity>

<TouchableOpacity onPress={onPressNext}>
<SVG width={16} height={16} source={chevronRightSVG} />
</TouchableOpacity>
</View>
);
};
30 changes: 10 additions & 20 deletions packages/components/carousels/NewsCarouselSection.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import React, { useEffect, useRef } from "react";
import { View, TouchableOpacity } from "react-native";
import Carousel, { ICarouselInstance } from "react-native-reanimated-carousel";

import chevronLeftSVG from "../../../assets/icons/chevron-left.svg";
import chevronRightSVG from "../../../assets/icons/chevron-right.svg";
import { News } from "../../api/marketplace/v1/marketplace";
import { useMaxResolution } from "../../hooks/useMaxResolution";
import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork";
import { FullWidthSeparator } from "../FullWidthSeparator";
import { SVG } from "../SVG";
import { Section } from "../Section";
import { NewsBox } from "../hub/NewsBox";

import { LeftRightButtons } from "@/components/carousels/LeftRightButtons";
import { useNews } from "@/hooks/marketing/useNews";

export const NewsCarouselSection: React.FC = () => {
Expand All @@ -21,27 +18,20 @@ export const NewsCarouselSection: React.FC = () => {
const networkId = useSelectedNetworkId();
const news = useNews(networkId);

const topRightChild = (
<View style={{ flexDirection: "row", alignItems: "center" }}>
<TouchableOpacity
onPress={() => carouselRef.current?.prev()}
style={{ marginRight: 24 }}
>
<SVG width={16} height={16} source={chevronLeftSVG} />
</TouchableOpacity>

<TouchableOpacity onPress={() => carouselRef.current?.next()}>
<SVG width={16} height={16} source={chevronRightSVG} />
</TouchableOpacity>
</View>
);

useEffect(() => {
carouselRef.current?.next();
}, [width]);

return (
<Section title="Highlighted News" topRightChild={topRightChild}>
<Section
title="Highlighted News"
topRightChild={
<LeftRightButtons
onPressNext={() => carouselRef.current?.next()}
onPressPrev={() => carouselRef.current?.prev()}
/>
}
>
<FullWidthSeparator />
{/*TODO: Async fetchMore for these data ?*/}

Expand Down
26 changes: 0 additions & 26 deletions packages/components/hub/HubBanner.tsx

This file was deleted.

17 changes: 17 additions & 0 deletions packages/components/hub/HubBanner/HubBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { FC } from "react";

import { Banner } from "@/api/marketplace/v1/marketplace";
import { Link } from "@/components/Link";
import { HubBannerImage } from "@/components/hub/HubBanner/HubBannerImage";
import { useMaxResolution } from "@/hooks/useMaxResolution";

export const HubBanner: FC<{
banner: Banner;
}> = ({ banner }) => {
const { width } = useMaxResolution();
return (
<Link to={banner?.url} style={{ width: "100%", maxHeight: 500 }}>
<HubBannerImage sourceURI={banner?.image} width={width} />
</Link>
);
};
21 changes: 21 additions & 0 deletions packages/components/hub/HubBanner/HubBannerImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { FC } from "react";

import { OptimizedImage } from "@/components/OptimizedImage";

export const HubBannerImage: FC<{
sourceURI: string;
width: number;
}> = ({ sourceURI, width }) => {
return (
<OptimizedImage
sourceURI={sourceURI}
width={width}
height={350}
style={{
height: 350,
width,
borderRadius: 20,
}}
/>
);
};
12 changes: 8 additions & 4 deletions packages/components/hub/HubLanding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
SortDirection,
} from "../../api/marketplace/v1/marketplace";
import { useBanners } from "../../hooks/marketing/useBanners";
import { useMaxResolution } from "../../hooks/useMaxResolution";
import { useSelectedNetworkId } from "../../hooks/useSelectedNetwork";
import { Section } from "../Section";
import { DAppCard } from "../cards/DAppCard";
Expand All @@ -21,21 +20,26 @@ import { MyWalletsCard } from "../cards/MyWalletsCard";
import { CollectionsCarouselSection } from "../carousels/CollectionsCarouselSection";
import { NewsCarouselSection } from "../carousels/NewsCarouselSection";

import { HubBanner } from "@/components/hub/HubBanner";
import { HubBanner } from "@/components/hub/HubBanner/HubBanner";
import { SpacerColumn } from "@/components/spacer";
import { useAppNavigation } from "@/hooks/navigation/useAppNavigation";

const gridHalfGutter = 12;

export const HubLanding: React.FC = () => {
const navigation = useAppNavigation();
const { width } = useMaxResolution();
const networkId = useSelectedNetworkId();
const banners = useBanners(networkId);
const banner = banners?.length ? banners[0] : undefined;
return (
<View style={{ alignItems: "center", width: "100%" }}>
<View style={{ flex: 1 }}>
{!!banner && <HubBanner width={width} banner={banner} />}
{!!banner && (
<>
<SpacerColumn size={7} />
<HubBanner banner={banner} />
</>
)}

<NewsCarouselSection />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,156 @@
import React, { FC, useState } from "react";
import { useWindowDimensions, View } from "react-native";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { FC, useMemo, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { View } from "react-native";

import { HubBanner } from "@/components/hub/HubBanner";
import { Banner } from "@/api/marketplace/v1/marketplace";
import cameraSVG from "@/assets/icons/camera.svg";
import { BrandText } from "@/components/BrandText";
import { SVG } from "@/components/SVG";
import { BoxStyle } from "@/components/boxes/Box";
import { CustomPressable } from "@/components/buttons/CustomPressable";
import { HubBanner } from "@/components/hub/HubBanner/HubBanner";
import { HubBannerImage } from "@/components/hub/HubBanner/HubBannerImage";
import { TextInputCustom } from "@/components/inputs/TextInputCustom";
import { FileUploader } from "@/components/inputs/fileUploader";
import { SpacerColumn, SpacerRow } from "@/components/spacer";
import { useBanners } from "@/hooks/marketing/useBanners";
import { useMaxResolution } from "@/hooks/useMaxResolution";
import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork";
import { EditButton } from "@/screens/Launchpad/LaunchpadAdmin/LaunchpadAdministrationOverview/component/MarketingEdition/EditButton";
import { IMAGE_MIME_TYPES } from "@/utils/mime";
import { neutral17, primaryColor } from "@/utils/style/colors";
import { fontSemibold13 } from "@/utils/style/fonts";
import { layout } from "@/utils/style/layout";
import { BannerForm, ZodBannerForm } from "@/utils/types/banners";

// Multiple Banners ?
// TODO: Multiple Banners ?
export const BannersEdition: FC = () => {
const networkId = useSelectedNetworkId();
const banners = useBanners(networkId);
const banner = banners?.length ? banners[0] : undefined;
const { width } = useWindowDimensions();

const { width } = useMaxResolution();
const [isEditing, setIsEditing] = useState(false);
const bannerForm = useForm<BannerForm>({
mode: "all",
resolver: zodResolver(ZodBannerForm),
});
const url = bannerForm.watch("url");
const image = bannerForm.watch("image");
const newBanner: Banner = useMemo(() => {
return {
image: image?.url || banner?.image || "",
url: url || banner?.url || "",
};
}, [url, image?.url, banner?.url, banner?.image]);

return (
<View>
<EditButton
isEditing={isEditing}
setIsEditing={setIsEditing}
saveChanges={() => {
// TODO
<View style={{ width, alignSelf: "center" }}>
<View
style={{
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
}}
/>
>
<EditButton
isEditing={isEditing}
setIsEditing={setIsEditing}
isSaveDisabled={!bannerForm.formState.isValid}
onPressSave={() => {
bannerForm.handleSubmit(() => {
// TODO
bannerForm.reset();
})();
}}
onPressCancel={() => bannerForm.reset()}
/>

{isEditing && (
<View
style={{
flexDirection: "row",
alignItems: "center",
flex: 1,
justifyContent: "flex-end",
}}
>
<TextInputCustom
label=""
name="url"
noBrokenCorners
variant="regular"
placeHolder="Banner redirection URL"
control={bannerForm.control}
containerStyle={{
maxWidth: 400,
width: "100%",
}}
height={40}
/>
<SpacerRow size={2} />

<Controller<BannerForm>
control={bannerForm.control}
name="image"
render={({ field: { onChange } }) => (
<FileUploader
onUpload={(files) => {
onChange(files[0]);
}}
mimeTypes={IMAGE_MIME_TYPES}
>
{({ onPress }) => (
<CustomPressable
onPress={onPress}
style={changeImageButton}
>
<SVG
width={16}
height={16}
source={cameraSVG}
color={neutral17}
/>
<BrandText
numberOfLines={1}
style={[
fontSemibold13,
{
color: neutral17,
marginLeft: layout.spacing_x1_25,
},
]}
>
Change Banner's image
</BrandText>
</CustomPressable>
)}
</FileUploader>
)}
/>
</View>
)}
</View>
<SpacerColumn size={3} />

{/*TODO: Edition*/}
{banner && <HubBanner width={width} banner={banner} />}
{isEditing && (
<HubBannerImage sourceURI={newBanner.image} width={width} />
)}

{!isEditing && banner && <HubBanner banner={banner} />}
</View>
);
};

const changeImageButton: BoxStyle = {
flexDirection: "row",
alignSelf: "flex-start",
borderRadius: 6,
alignItems: "center",
justifyContent: "center",
paddingRight: layout.spacing_x1_5,
paddingLeft: layout.spacing_x2,
paddingVertical: layout.spacing_x1,
backgroundColor: primaryColor,
height: 40,
};
Loading

0 comments on commit e7f059a

Please sign in to comment.