Skip to content

Commit

Permalink
feat: change social media links in custom store with prefixes (#898)
Browse files Browse the repository at this point in the history
* feat: change regex to accept more urls

* feat: change social media links in custom store with prefixes

* remove log

* remove unused code

* fix: tests

* change ui
  • Loading branch information
albertfolch-redeemeum authored Oct 31, 2023
1 parent 7ecd051 commit a61653a
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/components/form/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const customStyles = (error: any): StylesConfig<any, true> => ({
zIndex: state.isFocused ? zIndex.Select + 1 : zIndex.Select,
position: "relative",
width: "100%",
height: "25px"
minHeight: "25px"
}),
option: (provided: any, state: any) => ({
...provided,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { lensHandleMaxLength } from "../../../../../lib/config";
import { validationMessage } from "../../../../../lib/constants/validationMessage";
import { FileProps } from "../../../../form/Upload/types";
import { validationOfRequiredIpfsImage } from "../../../../product/utils/validationUtils";
import { getCommonFieldsValidation } from "../valitationSchema";
import { getCommonFieldsValidation } from "../validationSchema";

// const MAX_LOGO_SIZE = 300 * 1024; // 300 KB
const maxLensHandleLength = 31 - lensHandleMaxLength;
Expand Down
2 changes: 0 additions & 2 deletions src/components/modal/components/Profile/ProfileFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useAccount } from "lib/utils/hooks/connection/connection";
import { ReactNode } from "react";

import { getIpfsGatewayUrl } from "../../../../lib/utils/ipfs";
import { websitePattern } from "../../../../lib/validation/regex/url";
import { FormField, Input, Select, Textarea, Upload } from "../../../form";
import {
CreateProfile,
Expand Down Expand Up @@ -128,7 +127,6 @@ export function ProfileFormFields({
<Input
name="website"
placeholder="www.example.com OR www.instagram.com/example"
pattern={websitePattern}
/>
</FormField>
<FormField
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Yup from "yup";

import { validationOfRequiredIpfsImage } from "../../../../product/utils/validationUtils";
import { getCommonFieldsValidation } from "../valitationSchema";
import { getCommonFieldsValidation } from "../validationSchema";

export const createYourProfileSchema = Yup.object({
logo: validationOfRequiredIpfsImage(),
Expand Down
2 changes: 1 addition & 1 deletion src/components/product/utils/validationSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { fixformattedString } from "../../../lib/utils/number";
import Yup from "../../../lib/validation/index";
import { Token } from "../../convertion-rate/ConvertionRateContext";
import { FileProps } from "../../form/Upload/types";
import { getCommonFieldsValidation } from "../../modal/components/Profile/valitationSchema";
import { getCommonFieldsValidation } from "../../modal/components/Profile/validationSchema";
import { CONFIG, DappConfig } from "./../../../lib/config";
import { SelectDataProps } from "./../../form/types";
import {
Expand Down
54 changes: 54 additions & 0 deletions src/lib/validation/regex/url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { checkValidUrl, preAppendHttps } from "./url";

const validUrls = [
"https://www.example.com/search?q=a",
"https://example.com/path/123/path-1-a",
"https://example.com",
"http://example.com",
"example.com",
"https://example.com",
"https://www.example",
"www.example",
"www.example.com",
"www.example.com:80",
"www.example.com:80/",
"https://example.com/path",
"https://example.com:8080/path",
"http://example.com.local/path",
"https://example.com/index.html",
"https://example.com/index.html#my-section",
"https://example.com/search?q=hello+world",
"http://example.com/?q=hello%20world",
"http://example.com/index.html?q=hello%20world#my-section",
"http://example.com:8080/path?q=hello%20world#my-section",
"http://example.com/foo%20bar",
"https://example.com/#bar%20foo",
"http://example.com/path?q=hello%20world&another_param=value",
"https://example.com/#my-section%20with%20spaces",
"https://example.com/%E2%98%85%E2%98%85%E2%98%85",
"http://example.com/%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C"
];
describe("url", () => {
describe("test valid urls", () => {
test.each(validUrls)("%s is a valid url", (...urls) => {
urls.forEach((url) => {
expect(checkValidUrl(url, { addHttpPrefix: true })).toBe(true);
});
});
});

describe("preAppendHttps", () => {
test("url starts with https:// if it did not", () => {
const url = "example.com";
expect(preAppendHttps(url)).toBe(`https://${url}`);
});
test("url is not modified if it already starts with https://", () => {
const url = "https://example.com";
expect(preAppendHttps(url)).toBe(url);
});
test("url is not modified if it already starts with http://", () => {
const url = "http://example.com";
expect(preAppendHttps(url)).toBe(url);
});
});
});
14 changes: 13 additions & 1 deletion src/lib/validation/regex/url.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const socialLinkPattern =
"^(http://|https://)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{1}.([-a-z-0-9:_+.?/@]+)?$";
"^(http://|https://)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{1}.([-a-z-A-Z-0-9:_+.?/@#%&=]+)?$";

export const websitePattern = socialLinkPattern;

Expand All @@ -8,3 +8,15 @@ export const preAppendHttps = (url: string) => {
? url
: `https://${url}`;
};

export const checkValidUrl = (
url: string,
{ addHttpPrefix }: { addHttpPrefix: boolean } = { addHttpPrefix: true }
) => {
try {
new URL(addHttpPrefix ? preAppendHttps(url) : url);
return true;
} catch (err) {
return false;
}
};
13 changes: 10 additions & 3 deletions src/pages/custom-store/CustomStoreFormContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ export const formValuesWithOneLogoUrl = (
}
return {
value: val.value.trim(),
url: preAppendHttps((val.url as string)?.trim()),
url: preAppendHttps(
`${val.prefix ?? ""}${(val.url as string)?.trim() ?? ""}`
),
label: val.label.trim()
};
}
Expand All @@ -132,7 +134,7 @@ export const formValuesWithOneLogoUrl = (
) {
return {
label: val.label,
value: preAppendHttps(val.value || "")
value: preAppendHttps((val.value as string) || "")
};
}
return null;
Expand All @@ -158,6 +160,7 @@ export default function CustomStoreFormContent({ hasSubmitError }: Props) {
const { showModal } = useModal();
const { setFieldValue, values, isValid, setValues, isSubmitting } =
useFormikContext<StoreFormFields>();

const { sellerIds } = useCurrentSellers();

const queryParams = new URLSearchParams(
Expand Down Expand Up @@ -387,9 +390,13 @@ export default function CustomStoreFormContent({ hasSubmitError }: Props) {
}
);
if (option) {
const urlWithoutPrefix =
socialMediaObject.url.startsWith(option.prefix)
? socialMediaObject.url.replace(option.prefix, "")
: socialMediaObject.url;
return {
...option,
url: socialMediaObject.url
url: urlWithoutPrefix
};
}
return null;
Expand Down
35 changes: 18 additions & 17 deletions src/pages/custom-store/SocialMediaLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import Typography from "../../components/ui/Typography";
import SocialLogo from "./SocialLogo";
import { storeFields } from "./store-fields";
import { StoreFormFields } from "./store-fields-types";
import {
firstSubFieldBasis,
gap,
logoSize,
secondSubFieldBasis
} from "./styles";
import { firstSubFieldBasis, gap, logoSize } from "./styles";

const Global = createGlobalStyle`
.dragged {
Expand Down Expand Up @@ -54,31 +49,37 @@ const SocialMediaLinks: React.FC<SocialMediaLinksProps> = ({
<Grid flexBasis={firstSubFieldBasis}>
<Typography>Logo</Typography>
</Grid>
<Grid flexBasis={secondSubFieldBasis}>
<Grid justifyContent="flex-end">
<Typography>URL</Typography>
</Grid>
</Grid>
)}
<Global />
<StyledSortableList onSortEnd={onSortEnd} draggedItemClassName="dragged">
{(links || []).map((selection, index) => {
const { label, value } = selection || {};

const { label, value, prefix } = selection || {};
return (
<SortableItem key={label}>
<Grid gap={gap}>
<Grid gap={gap} alignItems="baseline">
<Grid flexBasis={firstSubFieldBasis}>
<SocialLogo logo={value} size={logoSize} />
</Grid>
<Grid
flexBasis={secondSubFieldBasis}
flexDirection="column"
alignItems="flex-start"
alignItems="baseline"
gap={"0.25rem"}
justifyContent="flex-end"
>
<Input
name={`${storeFields.socialMediaLinks}[${index}].url`}
placeholder={`${label} URL`}
/>
<span style={{ fontSize: "0.7rem" }}>{prefix}</span>
<Grid
flexDirection="column"
alignItems="flex-start"
flexBasis="50%"
>
<Input
name={`${storeFields.socialMediaLinks}[${index}].url`}
placeholder={`${label} handle`}
/>
</Grid>
</Grid>
</Grid>
</SortableItem>
Expand Down
9 changes: 7 additions & 2 deletions src/pages/custom-store/store-fields-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ export type StoreFields = {
navigationBarPosition?: SelectType;
copyright: string;
showFooter?: SelectType;
socialMediaLinks?: SelectType<SocialLogoValues>[];
contactInfoLinks?: SelectType<ContactInfoLinkIconValues>[];
socialMediaLinks?: (SelectType<SocialLogoValues> & {
url: string;
prefix: string;
})[];
contactInfoLinks?: (SelectType<ContactInfoLinkIconValues> & {
text: string;
})[];
additionalFooterLinks?: AdditionalFooterLink[];
withOwnProducts?: SelectType<"mine" | "all" | "custom">;
sellerCurationList?: string;
Expand Down
Loading

0 comments on commit a61653a

Please sign in to comment.