From 2c20069a9017f07a027cfc98a3530aa67831e728 Mon Sep 17 00:00:00 2001
From: Alvin Dimas Satria <56182633+alvin371@users.noreply.github.com>
Date: Tue, 9 May 2023 16:08:52 +0700
Subject: [PATCH] fix: Adjustment on Create Post to Timeline (#1824)

* fix: set debio tips (#1753)

feat: set debio tips

* chore(deps): bump google-github-actions/release-please-action from 3.7.4 to 3.7.5 (#1754)

chore(deps): bump google-github-actions/release-please-action

Bumps [google-github-actions/release-please-action](https://github.com/google-github-actions/release-please-action) from 3.7.4 to 3.7.5.
- [Release notes](https://github.com/google-github-actions/release-please-action/releases)
- [Changelog](https://github.com/google-github-actions/release-please-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/release-please-action/compare/d3c71f9a0a55385580de793de58da057b3560862...e0b9d1885d92e9a93d5ce8656de60e3b806e542c)

---
updated-dependencies:
- dependency-name: google-github-actions/release-please-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: adjustment view on direclty post to timeline

* fix: adjustment view on direclty post to timeline

* fix: adjustment view on direclty post to timeline

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kristian Ruben <56469224+rubenkristian@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 .../ExperienceListBarCreatePost.tsx           |   2 +-
 .../Experience.skeleton.tsx                   |  36 +
 .../Experience.style.ts                       | 123 +++
 .../ExperienceTimelineCard/Experience.tsx     | 412 ++++++++
 .../ModalAddToPost/ModalAddToPost.context.tsx |   9 +
 .../ModalAddToPost.interface.tsx              |   5 +
 .../ModalAddToPost.provider.tsx               | 327 ++++++
 .../ModalAddToPost/ModalAddToPost.styles.tsx  | 121 +++
 .../ModalAddToPost/useModalAddToPost.hook.tsx |  19 +
 .../ExperienceTimelineCard/index.ts           |   2 +
 .../Experience.container.tsx                  |  83 ++
 .../Experience.styles.ts                      | 178 ++++
 .../ExperienceEditor.stories.tsx              | 106 ++
 .../ExperienceTimelinePost.tsx                | 932 ++++++++++++++++++
 .../ExperienceTimelinePost/index.ts           |   1 +
 src/components/PostCreate/PostCreate.tsx      |  49 +-
 src/components/ProfileHeader/index.tsx        |   2 +-
 src/hooks/use-experience-hook.ts              |   3 +
 18 files changed, 2396 insertions(+), 14 deletions(-)
 create mode 100644 src/components/ExperienceTimelineCard/Experience.skeleton.tsx
 create mode 100644 src/components/ExperienceTimelineCard/Experience.style.ts
 create mode 100644 src/components/ExperienceTimelineCard/Experience.tsx
 create mode 100644 src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.context.tsx
 create mode 100644 src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.interface.tsx
 create mode 100644 src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.provider.tsx
 create mode 100644 src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.styles.tsx
 create mode 100644 src/components/ExperienceTimelineCard/ModalAddToPost/useModalAddToPost.hook.tsx
 create mode 100644 src/components/ExperienceTimelineCard/index.ts
 create mode 100644 src/components/ExperienceTimelinePost/Experience.container.tsx
 create mode 100644 src/components/ExperienceTimelinePost/Experience.styles.ts
 create mode 100644 src/components/ExperienceTimelinePost/ExperienceEditor.stories.tsx
 create mode 100644 src/components/ExperienceTimelinePost/ExperienceTimelinePost.tsx
 create mode 100644 src/components/ExperienceTimelinePost/index.ts

diff --git a/src/components/ExperienceList/ExperienceListBarCreatePost.tsx b/src/components/ExperienceList/ExperienceListBarCreatePost.tsx
index ae5e03536..40ab176cb 100644
--- a/src/components/ExperienceList/ExperienceListBarCreatePost.tsx
+++ b/src/components/ExperienceList/ExperienceListBarCreatePost.tsx
@@ -1,6 +1,6 @@
 import React, { useState } from 'react';
 
-import { Experience as ExperienceCard } from '../ExpericenceRightBar';
+import { Experience as ExperienceCard } from '../ExperienceTimelineCard';
 import { useStyles } from './ExperienceList.style';
 
 import { WrappedExperience } from 'src/interfaces/experience';
diff --git a/src/components/ExperienceTimelineCard/Experience.skeleton.tsx b/src/components/ExperienceTimelineCard/Experience.skeleton.tsx
new file mode 100644
index 000000000..39c6129b6
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/Experience.skeleton.tsx
@@ -0,0 +1,36 @@
+import Card from '@material-ui/core/Card';
+import Grid from '@material-ui/core/Grid';
+import BaseSekeleton from '@material-ui/lab/Skeleton';
+
+export const Skeleton = ({ menuDrawer = false }: { menuDrawer?: boolean }) => {
+  return (
+    <Card
+      style={{
+        padding: menuDrawer ? '5px 10px' : 20,
+        borderRadius: 10,
+        marginBottom: menuDrawer ? 10 : 30,
+        width: '100%',
+      }}>
+      <Grid
+        container
+        direction="row"
+        style={{ width: '100%' }}
+        alignItems="center">
+        <BaseSekeleton
+          variant="rect"
+          width={menuDrawer ? 40 : 68}
+          height={menuDrawer ? 40 : 68}
+        />
+
+        <Grid
+          item
+          container
+          direction="column"
+          style={{ marginLeft: 20, width: 'calc(100% - 88px)' }}>
+          <BaseSekeleton variant="text" width={'100%'} height={24} />
+          <BaseSekeleton variant="text" width={'50%'} height={16} />
+        </Grid>
+      </Grid>
+    </Card>
+  );
+};
diff --git a/src/components/ExperienceTimelineCard/Experience.style.ts b/src/components/ExperienceTimelineCard/Experience.style.ts
new file mode 100644
index 000000000..49d2d0fed
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/Experience.style.ts
@@ -0,0 +1,123 @@
+import {
+  alpha,
+  createStyles,
+  makeStyles,
+  Theme,
+} from '@material-ui/core/styles';
+
+type ExperienceStyleProps = {
+  selected: boolean;
+  selectable: boolean;
+  menuDrawer: boolean;
+};
+
+export const useStyles = makeStyles<Theme, ExperienceStyleProps>(theme =>
+  createStyles({
+    root: {
+      marginBottom: theme.spacing(1),
+      border: '1px solid',
+      borderColor: props => (props.selected ? '#6E3FC3' : '#FFF'),
+      borderRadius: 10,
+      padding: props => (props.menuDrawer ? '5px 10px' : 20),
+      width: '100%',
+      boxShadow: `0px 2px 10px rgba(0, 0, 0, 0.05)`,
+      position: 'relative',
+
+      '&:hover': {
+        backgroundColor: alpha('#FFC857', 0.15),
+        borderColor: props => (props.selected ? '#6E3FC3' : 'transparent'),
+
+        '& .MuiCardActionArea-focusHighlight': {
+          opacity: 0,
+        },
+
+        '&::before': {
+          backgroundColor: props =>
+            props.selected ? '#6E3FC3' : 'transparent',
+        },
+      },
+
+      '&::before': {
+        content: '""',
+        position: 'absolute',
+        width: 8,
+        top: 0,
+        left: 0,
+        height: '100%',
+        backgroundColor: props => (props.selected ? '#6E3FC3' : '#FFF'),
+        borderTopLeftRadius: 10,
+        borderBottomLeftRadius: 10,
+      },
+    },
+    image: {
+      width: props => (props.menuDrawer ? 40 : 68),
+      height: props => (props.menuDrawer ? 40 : 68),
+      opacity: 0.9,
+      borderRadius: 5,
+    },
+    cardContent: {
+      width: 140,
+      padding: '0px 0px 0px 20px',
+      flexGrow: 1,
+      overflow: 'hidden',
+      textOverflow: 'ellipsis',
+      whiteSpace: 'nowrap',
+
+      '&:last-child': {
+        paddingBottom: 0,
+      },
+    },
+    title: {
+      wordBreak: 'break-word',
+      whiteSpace: 'nowrap',
+      overflow: 'hidden',
+      textOverflow: 'ellipsis',
+      [theme.breakpoints.down('xs')]: {
+        fontSize: '14px',
+      },
+    },
+    subtitle: {
+      whiteSpace: 'nowrap',
+      overflow: 'hidden',
+      textOverflow: 'ellipsis',
+      [theme.breakpoints.down('xs')]: {
+        fontSize: '12px',
+        fontWeight: 500,
+      },
+    },
+    icon: {
+      [theme.breakpoints.down('xs')]: {
+        color: '#404040',
+      },
+    },
+    menu: {
+      borderRadius: 10,
+      marginTop: 8,
+    },
+    delete: {
+      color: '#FE3636',
+    },
+    error: {
+      background: '#FE3636',
+      color: '#FFF',
+      '&:hover': {
+        color: theme.palette.text.primary,
+      },
+    },
+    modal: {
+      paddingBottom: 10,
+    },
+    input: {
+      width: 560,
+      marginBottom: 0,
+      marginTop: 10,
+
+      '& .MuiInputLabel-root, .MuiInputBase-root': {
+        color: '#616161',
+      },
+      [theme.breakpoints.down('xs')]: {
+        width: '100%',
+      },
+    },
+  }),
+);
diff --git a/src/components/ExperienceTimelineCard/Experience.tsx b/src/components/ExperienceTimelineCard/Experience.tsx
new file mode 100644
index 000000000..48a1ad6b1
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/Experience.tsx
@@ -0,0 +1,412 @@
+import { DuplicateIcon } from '@heroicons/react/outline';
+
+import React, { useState } from 'react';
+import { useCookies } from 'react-cookie';
+import CopyToClipboard from 'react-copy-to-clipboard';
+
+import getConfig from 'next/config';
+import NextImage from 'next/image';
+import Link from 'next/link';
+import { useRouter } from 'next/router';
+
+import { Avatar, Grid } from '@material-ui/core';
+import { TextField, InputAdornment } from '@material-ui/core';
+import Card from '@material-ui/core/Card';
+import CardActionArea from '@material-ui/core/CardActionArea';
+import CardContent from '@material-ui/core/CardContent';
+import IconButton from '@material-ui/core/IconButton';
+import Menu from '@material-ui/core/Menu';
+import BaseMenuItem from '@material-ui/core/MenuItem';
+import SvgIcon from '@material-ui/core/SvgIcon';
+import Typography from '@material-ui/core/Typography';
+
+import useConfirm from '../common/Confirm/use-confirm.hook';
+import { useStyles } from './Experience.style';
+
+import { COOKIE_INSTANCE_URL } from 'components/SelectServer';
+import { WithAuthorizeAction } from 'components/common/Authorization/WithAuthorizeAction';
+import { useEnqueueSnackbar } from 'components/common/Snackbar/useEnqueueSnackbar.hook';
+import { Modal } from 'src/components/atoms/Modal';
+import ShowIf from 'src/components/common/show-if.component';
+import { capitalize } from 'src/helpers/string';
+import { useExperienceHook } from 'src/hooks/use-experience-hook';
+import { WrappedExperience } from 'src/interfaces/experience';
+import { User } from 'src/interfaces/user';
+import i18n from 'src/locale';
+
+type ExperienceProps = {
+  user?: User;
+  anonymous?: boolean;
+  userExperience: WrappedExperience;
+  selected: boolean;
+  selectable: boolean;
+  onSelect?: (experienceId: string) => void;
+  onClone?: (experienceId: string) => void;
+  onSubscribe?: (experienceId: string) => void;
+  onUnsubscribe?: (experienceId: string) => void;
+  onDelete?: (experienceId: string) => void;
+  menuDrawer?: boolean;
+};
+
+const MenuItem = WithAuthorizeAction(BaseMenuItem);
+
+const DEFAULT_IMAGE =
+  'https://pbs.twimg.com/profile_images/1407599051579617281/-jHXi6y5_400x400.jpg';
+
+const { publicRuntimeConfig } = getConfig();
+
+export const Experience: React.FC<ExperienceProps> = props => {
+  const {
+    userExperience,
+    user,
+    anonymous = false,
+    selectable,
+    onSelect,
+    onClone,
+    onDelete,
+    onSubscribe,
+    onUnsubscribe,
+    menuDrawer = false,
+  } = props;
+
+  const router = useRouter();
+  const styles = useStyles({ ...props, menuDrawer });
+  const confirm = useConfirm();
+  const enqueueSnackbar = useEnqueueSnackbar();
+
+  const [menuAnchorElement, setMenuAnchorElement] =
+    useState<null | HTMLElement>(null);
+  const [shareAnchorElement, setShareAnchorElement] =
+    useState<null | HTMLElement>(null);
+
+  const isOwnExperience = userExperience.experience.user.id === user?.id;
+  const experienceId = userExperience.experience.id;
+  const userExperienceId = userExperience.id;
+  const link = publicRuntimeConfig.appAuthURL + `?type=all&id=${experienceId}`;
+  const { userExperiencesMeta } = useExperienceHook();
+  const totalOwnedExperience =
+    userExperiencesMeta.additionalData?.totalOwnedExperience ?? 0;
+
+  const handleClickExperience = () => {
+    handleCloseSettings();
+
+    if (selectable && onSelect) {
+      onSelect(experienceId);
+    }
+  };
+
+  const handleCloneExperience = () => {
+    if (
+      totalOwnedExperience >= 5 &&
+      !user.fullAccess &&
+      user.fullAccess !== undefined
+    ) {
+      confirm({
+        title: i18n.t('LiteVersion.LimitTitleExperience'),
+        description: i18n.t('LiteVersion.LimitDescExperience'),
+        icon: 'warning',
+        confirmationText: i18n.t('LiteVersion.ConnectWallet'),
+        cancellationText: i18n.t('LiteVersion.MaybeLater'),
+        onConfirm: () => {
+          router.push({ pathname: '/wallet', query: { type: 'manage' } });
+        },
+        onCancel: () => {
+          undefined;
+        },
+      });
+    } else {
+      handleCloseSettings();
+
+      if (onClone) {
+        onClone(experienceId);
+      }
+    }
+  };
+
+  const [cookies] = useCookies([COOKIE_INSTANCE_URL]);
+
+  const handleSubscribeExperience = () => {
+    handleCloseSettings();
+
+    if (!user) {
+      confirm({
+        icon: 'followTimeline',
+        title: i18n.t('Confirm.Anonymous.FollowTimeline.Title'),
+        description: i18n.t('Confirm.Anonymous.FollowTimeline.Desc'),
+        confirmationText: i18n.t('General.SignIn'),
+        cancellationText: i18n.t('LiteVersion.MaybeLater'),
+        onConfirm: () => {
+          router.push(`/login?instance=${cookies[COOKIE_INSTANCE_URL]}`);
+        },
+      });
+    } else {
+      if (onSubscribe) {
+        onSubscribe(experienceId);
+      }
+    }
+  };
+
+  const handleCloseSettings = () => {
+    setMenuAnchorElement(null);
+  };
+
+  const confirmDeleteExperience = () => {
+    handleCloseSettings();
+
+    confirm({
+      title: i18n.t('Experience.List.Prompt_Delete.Title'),
+      description: i18n.t('Experience.List.Prompt_Delete.Desc'),
+      icon: 'danger',
+      confirmationText: i18n.t('Experience.List.Prompt_Delete.Btn_Yes'),
+      cancellationText: i18n.t('General.Cancel'),
+      onConfirm: () => {
+        if (onDelete && userExperienceId) {
+          onDelete(userExperienceId);
+        }
+      },
+    });
+  };
+
+  const confirmUnsubscribe = () => {
+    handleCloseSettings();
+
+    confirm({
+      title: i18n.t('Experience.List.Prompt_Unsub.Title'),
+      description: `${i18n.t('Experience.List.Prompt_Unsub.Desc_1')}\n ${i18n.t(
+        'Experience.List.Prompt_Unsub.Desc_2',
+        { experience_name: userExperience.experience.name },
+      )}`,
+      icon: 'warning',
+      confirmationText: i18n.t('Experience.List.Prompt_Unsub.Btn_Yes'),
+      onConfirm: () => {
+        if (onUnsubscribe && userExperienceId) {
+          onUnsubscribe(userExperienceId);
+        }
+      },
+    });
+  };
+
+  const openShareExperience = (event: React.MouseEvent<HTMLLIElement>) => {
+    console.log(event.currentTarget);
+    handleCloseSettings();
+
+    setShareAnchorElement(event.currentTarget);
+  };
+
+  const closeShareExperience = () => {
+    setShareAnchorElement(null);
+  };
+
+  const handleExperienceLinkCopied = () => {
+    enqueueSnackbar({
+      message: i18n.t('Experience.List.Copy'),
+      variant: 'success',
+    });
+  };
+
+  const isHidden = () => {
+    if (userExperience.private && !userExperience.friend) return true;
+    if (userExperience.private && userExperience.friend) return false;
+    return false;
+  };
+
+  return (
+    <>
+      <Card className={styles.root}>
+        <CardActionArea
+          onClick={handleClickExperience}
+          disableRipple
+          component="div">
+          <Grid
+            container
+            alignItems="center"
+            justifyContent="space-between"
+            wrap="nowrap">
+            {userExperience.experience.experienceImageURL ? (
+              <div
+                style={{
+                  maxWidth: menuDrawer ? 40 : 68,
+                  maxHeight: menuDrawer ? 40 : 68,
+                }}>
+                <NextImage
+                  alt={userExperience.experience.name}
+                  loader={() =>
+                    userExperience.experience.experienceImageURL ??
+                    DEFAULT_IMAGE
+                  }
+                  src={
+                    userExperience.experience.experienceImageURL ??
+                    DEFAULT_IMAGE
+                  }
+                  placeholder="empty"
+                  objectFit="cover"
+                  objectPosition="center"
+                  width={'100%'}
+                  height={'100%'}
+                  quality={90}
+                  className={styles.image}
+                />
+              </div>
+            ) : (
+              <Avatar
+                alt={userExperience.experience.name}
+                variant="rounded"
+                className={styles.image}>
+                {userExperience.experience.name.charAt(0)}
+              </Avatar>
+            )}
+
+            <CardContent classes={{ root: styles.cardContent }}>
+              <Typography className={styles.title} variant="body1">
+                {userExperience.experience.name}
+              </Typography>
+              <Typography
+                variant="caption"
+                color="primary"
+                className={styles.subtitle}>
+                {userExperience.experience.user.name}
+              </Typography>
+              <Typography variant="caption" color="textSecondary">
+                {isOwnExperience ? ` ${i18n.t('Experience.List.You')}` : ''}
+              </Typography>
+              <div className="">
+                <Typography
+                  variant="caption"
+                  color="error"
+                  className={styles.subtitle}>
+                  Visibility:{' '}
+                </Typography>
+                <Typography
+                  variant="caption"
+                  color="error"
+                  className={styles.subtitle}>
+                  {userExperience.experience.visibility === 'selected_user'
+                    ? 'Custom'
+                    : capitalize(userExperience.experience.visibility)}
+                </Typography>
+                <Link
+                  href={`/experience/[experienceId]`}
+                  as={`/experience/${experienceId}`}
+                  passHref>
+                  <Typography variant="body2" color="primary">
+                    {i18n.t('Experience.List.Menu.View')}
+                  </Typography>
+                </Link>
+              </div>
+            </CardContent>
+          </Grid>
+        </CardActionArea>
+      </Card>
+
+      {menuAnchorElement && (
+        <Menu
+          classes={{
+            paper: styles.menu,
+          }}
+          anchorEl={menuAnchorElement}
+          getContentAnchorEl={null}
+          anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
+          transformOrigin={{ vertical: 'bottom', horizontal: 'center' }}
+          open={Boolean(menuAnchorElement)}
+          onClose={handleCloseSettings}>
+          <Link
+            href={`/experience/[experienceId]`}
+            as={`/experience/${experienceId}`}
+            passHref>
+            <BaseMenuItem onClick={handleCloseSettings}>
+              {i18n.t('Experience.List.Menu.View')}
+            </BaseMenuItem>
+          </Link>
+
+          <ShowIf condition={isOwnExperience}>
+            <Link
+              href={`/experience/[experienceId]/edit`}
+              as={`/experience/${experienceId}/edit`}
+              passHref>
+              <MenuItem onClick={handleCloseSettings}>
+                {i18n.t('Experience.List.Menu.Edit')}
+              </MenuItem>
+            </Link>
+          </ShowIf>
+
+          <ShowIf condition={!isOwnExperience && !isHidden()}>
+            <MenuItem
+              onClick={handleCloneExperience}
+              fallback={handleCloseSettings}
+              disabled={anonymous}>
+              {i18n.t('Experience.List.Menu.Clone')}
+            </MenuItem>
+          </ShowIf>
+
+          <ShowIf
+            condition={
+              !userExperience.subscribed && !isOwnExperience && !isHidden()
+            }>
+            <MenuItem
+              onClick={handleSubscribeExperience}
+              fallback={handleCloseSettings}>
+              {i18n.t('Experience.List.Menu.Subscribe')}
+            </MenuItem>
+          </ShowIf>
+
+          <ShowIf
+            condition={Boolean(userExperience.subscribed) && !isOwnExperience}>
+            <MenuItem
+              onClick={confirmUnsubscribe}
+              fallback={handleCloseSettings}
+              className={styles.delete}>
+              {i18n.t('Experience.List.Menu.Unsubscribe')}
+            </MenuItem>
+          </ShowIf>
+          <ShowIf condition={isOwnExperience}>
+            <MenuItem
+              onClick={confirmDeleteExperience}
+              fallback={handleCloseSettings}
+              className={styles.delete}>
+              {i18n.t('Experience.List.Menu.Delete')}
+            </MenuItem>
+          </ShowIf>
+          <BaseMenuItem onClick={openShareExperience}>
+            {i18n.t('Experience.List.Menu.Share')}
+          </BaseMenuItem>
+        </Menu>
+      )}
+
+      <Modal
+        title={i18n.t('Experience.List.Modal.Title')}
+        subtitle={i18n.t('Experience.List.Modal.Subtitle')}
+        maxWidth="sm"
+        className={styles.modal}
+        open={Boolean(shareAnchorElement)}
+        onClose={closeShareExperience}>
+        <div className={styles.copy}>
+          <TextField
+            id="copy-post-url"
+            label="URL"
+            value={link}
+            variant="outlined"
+            disabled
+            fullWidth
+            margin="none"
+            className={styles.input}
+            InputProps={{
+              endAdornment: (
+                <InputAdornment position="end">
+                  <CopyToClipboard
+                    text={link}
+                    onCopy={handleExperienceLinkCopied}>
+                    <IconButton
+                      aria-label="copy-post-link"
+                      style={{ padding: 0 }}>
+                      <SvgIcon component={DuplicateIcon} color="primary" />
+                    </IconButton>
+                  </CopyToClipboard>
+                </InputAdornment>
+              ),
+            }}
+          />
+        </div>
+      </Modal>
+    </>
+  );
+};
diff --git a/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.context.tsx b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.context.tsx
new file mode 100644
index 000000000..9212a69c1
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.context.tsx
@@ -0,0 +1,9 @@
+import { createContext } from 'react';
+
+import { ModalAddPostExperienceProps } from './ModalAddToPost.interface';
+
+export type HandleConfirmAddPostExperience = (
+  props: ModalAddPostExperienceProps,
+) => void;
+
+export default createContext<HandleConfirmAddPostExperience | null>(null);
diff --git a/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.interface.tsx b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.interface.tsx
new file mode 100644
index 000000000..3af8b5010
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.interface.tsx
@@ -0,0 +1,5 @@
+import { Post } from 'src/interfaces/post';
+
+export type ModalAddPostExperienceProps = {
+  post: Post;
+};
diff --git a/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.provider.tsx b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.provider.tsx
new file mode 100644
index 000000000..6475d3008
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.provider.tsx
@@ -0,0 +1,327 @@
+import { InformationCircleIcon } from '@heroicons/react/outline';
+
+import React, { useCallback, useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
+
+import {
+  Button,
+  CardActionArea,
+  CardContent,
+  CardMedia,
+  Checkbox,
+  Grid,
+  IconButton,
+  SvgIcon,
+  Tooltip,
+  Typography,
+} from '@material-ui/core';
+
+import ModalAddToPostContext, {
+  HandleConfirmAddPostExperience,
+} from './ModalAddToPost.context';
+import { ModalAddPostExperienceProps } from './ModalAddToPost.interface';
+import { useStyles } from './ModalAddToPost.styles';
+
+import { Empty } from 'components/atoms/Empty';
+import { useEnqueueSnackbar } from 'components/common/Snackbar/useEnqueueSnackbar.hook';
+import ShowIf from 'components/common/show-if.component';
+import { Skeleton } from 'src/components/Expericence';
+import { Modal } from 'src/components/atoms/Modal';
+import { useExperienceHook } from 'src/hooks/use-experience-hook';
+import { UserExperience, WrappedExperience } from 'src/interfaces/experience';
+import * as ExperienceAPI from 'src/lib/api/experience';
+import i18n from 'src/locale';
+import { RootState } from 'src/reducers';
+import { UserState } from 'src/reducers/user/reducer';
+
+type ExperienceItemProps = {
+  item: WrappedExperience;
+  selectedExperience: string[];
+  handleSelectExperience: (propsSelectedExperience: string) => void;
+};
+
+const ExperienceItem = ({
+  item,
+  selectedExperience,
+  handleSelectExperience,
+}: ExperienceItemProps) => {
+  const styles = useStyles();
+
+  const DEFAULT_IMAGE =
+    'https://pbs.twimg.com/profile_images/1407599051579617281/-jHXi6y5_400x400.jpg';
+
+  return (
+    <div className={styles.experienceCard}>
+      <Checkbox
+        checked={
+          selectedExperience
+            ? selectedExperience.filter(ar => ar === item.experience.id)
+                .length > 0
+            : false
+        }
+        onChange={() => {
+          item.experience.id && handleSelectExperience(item.experience.id);
+        }}
+        color="primary"
+        inputProps={{ 'aria-label': 'controlled' }}
+        classes={{ root: styles.fill }}
+      />
+      <CardActionArea
+        onClick={() => {
+          item.experience.id && handleSelectExperience(item.experience.id);
+        }}
+        disableRipple
+        component="div">
+        <Grid
+          container
+          alignItems="center"
+          justifyContent="space-between"
+          wrap="nowrap">
+          <CardMedia
+            component="img"
+            className={styles.image}
+            image={item.experience.experienceImageURL ?? DEFAULT_IMAGE}
+          />
+          <CardContent classes={{ root: styles.cardContent }}>
+            <Typography className={styles.title} variant="body1">
+              {item.experience.name}
+            </Typography>
+            <Typography variant="caption" color="primary">
+              {item.experience.user.name}
+            </Typography>
+            <Typography variant="caption" color="textSecondary">
+              {item ? ` ${i18n.t('Experience.Modal_Add_Post.Card_Own')}` : ''}
+            </Typography>
+          </CardContent>
+        </Grid>
+      </CardActionArea>
+    </div>
+  );
+};
+
+export const ModalAddToPostProvider: React.ComponentType<ModalAddPostExperienceProps> =
+  ({ children }) => {
+    const styles = useStyles();
+    const { user } = useSelector<RootState, UserState>(
+      state => state.userState,
+    );
+    const {
+      loadExperiencePostList,
+      loadExperienceAdded,
+      addPostsToExperience,
+    } = useExperienceHook();
+    const enqueueSnackbar = useEnqueueSnackbar();
+
+    const [postId, setPostId] = useState<string | null>(null);
+    const [open, setOpen] = useState(false);
+    const [isSelectAll, setIsSelectAll] = useState(false);
+    const [selectedExperience, setSelectedExperience] = useState<string[]>([]);
+    const [userExperiences, setUserExperiences] = useState<UserExperience[]>(
+      [],
+    );
+    const [page, setPage] = useState<number>(1);
+    const [loading, setLoading] = useState<boolean>(true);
+
+    const toolTipText = i18n.t('Experience.Modal_Add_Post.Tooltip_Text');
+
+    const addPostToExperience = useCallback<HandleConfirmAddPostExperience>(
+      async props => {
+        setOpen(true);
+        const tmpAddedExperience: string[] = [];
+        await loadExperienceAdded(props.post.id, postsExperiences => {
+          postsExperiences.map(item => {
+            tmpAddedExperience.push(item.id);
+          });
+        });
+
+        loadExperiencePostList(props.post.id, postsExperiences => {
+          setPostId(props.post.id);
+          const tmpSelectedExperience: string[] = [];
+          postsExperiences.map(item => {
+            if (tmpAddedExperience.find(post => post === item.id)) {
+              tmpSelectedExperience.push(item.id);
+            }
+          });
+          setSelectedExperience(tmpSelectedExperience);
+        });
+
+        console.log({ userExperiences });
+      },
+      [userExperiences],
+    );
+
+    const handleClose = useCallback(() => {
+      setOpen(false);
+      setSelectedExperience([]);
+    }, []);
+
+    const handleSelectAllExperience = () => {
+      const tmpUserExperience = [...userExperiences].filter(
+        ar => ar.userId === user?.id,
+      );
+      let tmpSelectedExperience: string[] = [];
+      if (!isSelectAll) {
+        tmpUserExperience.map(item => {
+          tmpSelectedExperience.push(item.experience.id);
+        });
+      } else {
+        tmpSelectedExperience = [];
+      }
+      setSelectedExperience(tmpSelectedExperience);
+      setIsSelectAll(!isSelectAll);
+    };
+
+    const handleSelectExperience = (propsSelectedExperience: string) => {
+      const tmpSelectedExperience = [...selectedExperience];
+      if (
+        tmpSelectedExperience.filter(ar => ar === propsSelectedExperience)
+          .length > 0
+      ) {
+        const indexRemovedExperience = tmpSelectedExperience.indexOf(
+          propsSelectedExperience,
+        );
+        tmpSelectedExperience.splice(indexRemovedExperience, 1);
+      } else {
+        tmpSelectedExperience.push(propsSelectedExperience);
+      }
+      setSelectedExperience(tmpSelectedExperience);
+      console.log({ tmpSelectedExperience });
+    };
+
+    const handleConfirm = () => {
+      if (postId) {
+        addPostsToExperience(postId, selectedExperience, () => {
+          setOpen(false);
+          enqueueSnackbar({
+            message: i18n.t('Experience.Modal_Add_Post.Success_Msg'),
+            variant: 'success',
+          });
+        });
+      }
+    };
+
+    const fetchUserExperiences = async () => {
+      setLoading(true);
+      const { meta, data: experiences } =
+        await ExperienceAPI.getUserExperiences(user.id, undefined, page);
+
+      setUserExperiences([...userExperiences, ...experiences]);
+      setLoading(false);
+      if (meta.currentPage < meta.totalPageCount) setPage(page + 1);
+    };
+
+    const resetExperiences = () => {
+      setPage(1);
+      setUserExperiences([]);
+    };
+
+    useEffect(() => {
+      if (open) fetchUserExperiences();
+      else resetExperiences();
+    }, [open, page]);
+
+    return (
+      <>
+        <ModalAddToPostContext.Provider value={addPostToExperience}>
+          {children}
+        </ModalAddToPostContext.Provider>
+        <Modal
+          title={i18n.t('Experience.Modal_Add_Post.Title')}
+          subtitle={
+            <Typography>
+              <Typography>
+                {i18n.t('Experience.Modal_Add_Post.Subtitle_1')}
+              </Typography>
+              <Typography>
+                {i18n.t('Experience.Modal_Add_Post.Subtitle_2')}
+              </Typography>
+            </Typography>
+          }
+          open={open}
+          onClose={handleClose}>
+          <div className={styles.root}>
+            <div className={styles.options}>
+              <div className={styles.flex}>
+                <Typography>
+                  {i18n.t('Experience.Modal_Add_Post.Tooltip')}
+                </Typography>
+                <Tooltip title={toolTipText} arrow>
+                  <IconButton
+                    aria-label="info"
+                    className={styles.info}
+                    style={{ color: '#404040' }}>
+                    <SvgIcon
+                      component={InformationCircleIcon}
+                      viewBox="0 0 24 24"
+                    />
+                  </IconButton>
+                </Tooltip>
+              </div>
+              <div className={styles.flex}>
+                <Checkbox
+                  checked={isSelectAll}
+                  color="primary"
+                  onChange={handleSelectAllExperience}
+                  inputProps={{ 'aria-label': 'controlled' }}
+                  classes={{ root: styles.fill }}
+                  disabled={loading}
+                />
+                <Typography
+                  component="span"
+                  color="textPrimary"
+                  className={styles.selected}>
+                  {i18n.t('Experience.Modal_Add_Post.Select_All')}
+                </Typography>
+              </div>
+            </div>
+            <div></div>
+          </div>
+
+          <div
+            id="selectable-experience-list"
+            className={styles.experienceList}>
+            {userExperiences
+              .filter(ar => ar.userId === user?.id && ar.subscribed === false)
+              .map(item => {
+                return (
+                  <ExperienceItem
+                    key={item.id}
+                    item={item}
+                    selectedExperience={selectedExperience}
+                    handleSelectExperience={handleSelectExperience}
+                  />
+                );
+              })}
+            {loading && <Skeleton />}
+
+            <ShowIf
+              condition={
+                userExperiences.filter(ar => ar.userId === user?.id).length ===
+                  0 && !loading
+              }>
+              <div className={styles.containerEmpty}>
+                <Empty
+                  title={i18n.t('Experience.Modal_Add_Post.Empty_Title')}
+                  subtitle={i18n.t('Experience.Modal_Add_Post.Empty_Subtitle')}
+                  height={true}
+                  margin={false}
+                />
+              </div>
+            </ShowIf>
+          </div>
+          <Button
+            size="small"
+            variant="contained"
+            color="primary"
+            fullWidth
+            onClick={handleConfirm}
+            disabled={
+              loading ||
+              userExperiences.filter(ar => ar.userId === user?.id).length === 0
+            }>
+            {i18n.t('Experience.Modal_Add_Post.Btn_Confirm')}
+          </Button>
+        </Modal>
+      </>
+    );
+  };
diff --git a/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.styles.tsx b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.styles.tsx
new file mode 100644
index 000000000..c7bd34728
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/ModalAddToPost/ModalAddToPost.styles.tsx
@@ -0,0 +1,121 @@
+import { createStyles, makeStyles, Theme } from '@material-ui/core/styles';
+
+export const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    root: {
+      width: 438,
+      maxHeight: 580,
+
+      [theme.breakpoints.down('md')]: {
+        width: '100%',
+      },
+    },
+    subtitle: {
+      display: 'flex',
+      flexDirection: 'column',
+      justifyContent: 'center',
+      alignItems: 'center',
+    },
+    options: {
+      display: 'flex',
+      alignItems: 'center',
+      justifyContent: 'space-between',
+      marginBottom: 30,
+
+      '& . MuiMenu-paper': {
+        width: 170,
+      },
+    },
+    fill: {
+      '& .MuiSvgIcon-root': {
+        fill: 'currentColor',
+      },
+    },
+    selected: {
+      marginLeft: 4,
+      fontWeight: 600,
+    },
+    list: {
+      height: 340,
+      overflow: 'auto',
+      '& .MuiListItem-root': {
+        paddingTop: 0,
+        paddingBottom: 0,
+        marginBottom: 12,
+      },
+    },
+    action: {
+      marginTop: 8,
+      marginBottom: 24,
+    },
+    logo: {
+      height: 12,
+      width: 12,
+      marginLeft: 8,
+      marginTop: 4,
+    },
+    info: {
+      padding: 0,
+      '& .MuiSvgIcon-root': {
+        fill: 'none',
+      },
+    },
+    flex: {
+      display: 'flex',
+      gap: '8px',
+      alignItems: 'center',
+      marginBottom: theme.spacing(0.5),
+    },
+    experienceList: {
+      maxHeight: 'fit-content',
+      gap: '8px',
+      marginBottom: theme.spacing(1.5),
+      alignItems: 'center',
+      //overflow: 'scroll',
+    },
+    experienceCard: {
+      display: 'flex',
+      alignItems: 'center',
+      marginBottom: theme.spacing(2.5),
+    },
+    image: {
+      width: 68,
+      height: 68,
+      opacity: 0.9,
+      borderRadius: 5,
+    },
+    cardContent: {
+      padding: '0px 0px 0px 20px',
+      flexGrow: 1,
+
+      '&:last-child': {
+        paddingBottom: 0,
+      },
+    },
+    title: {
+      wordBreak: 'break-word',
+      [theme.breakpoints.down('xs')]: {
+        fontSize: '14px',
+      },
+    },
+    containerEmpty: {
+      display: 'flex',
+      justifyContent: 'center',
+      alignItems: 'center',
+      textAlign: 'center',
+      flexDirection: 'column',
+      background: '#FFF',
+      height: 300,
+      width: '100%',
+    },
+    emptyTitle: {
+      fontWeight: 700,
+      fontSize: '18px',
+      marginBottom: '12px',
+      textAlign: 'center',
+    },
+    emptySubtitle: {
+      fontSize: '14px',
+    },
+  }),
+);
diff --git a/src/components/ExperienceTimelineCard/ModalAddToPost/useModalAddToPost.hook.tsx b/src/components/ExperienceTimelineCard/ModalAddToPost/useModalAddToPost.hook.tsx
new file mode 100644
index 000000000..686f33741
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/ModalAddToPost/useModalAddToPost.hook.tsx
@@ -0,0 +1,19 @@
+import { useContext } from 'react';
+
+import ModalAddToPostContext, {
+  HandleConfirmAddPostExperience,
+} from './ModalAddToPost.context';
+
+const useModalAddToPost = (): HandleConfirmAddPostExperience => {
+  const addPostToExperience = useContext(ModalAddToPostContext);
+
+  if (!addPostToExperience) {
+    throw new Error(
+      'addPostToExperience must be used within a ModalAddToPostProvider',
+    );
+  }
+
+  return addPostToExperience;
+};
+
+export default useModalAddToPost;
diff --git a/src/components/ExperienceTimelineCard/index.ts b/src/components/ExperienceTimelineCard/index.ts
new file mode 100644
index 000000000..f3939f537
--- /dev/null
+++ b/src/components/ExperienceTimelineCard/index.ts
@@ -0,0 +1,2 @@
+export * from './Experience';
+export * from './Experience.skeleton';
diff --git a/src/components/ExperienceTimelinePost/Experience.container.tsx b/src/components/ExperienceTimelinePost/Experience.container.tsx
new file mode 100644
index 000000000..c0e9facd1
--- /dev/null
+++ b/src/components/ExperienceTimelinePost/Experience.container.tsx
@@ -0,0 +1,83 @@
+import React from 'react';
+
+import { useRouter } from 'next/router';
+
+import { useStyles } from './Experience.styles';
+import { ExperienceTimelinePost } from './ExperienceTimelinePost';
+
+import debounce from 'lodash/debounce';
+import { TopNavbarComponent } from 'src/components/atoms/TopNavbar';
+import { useExperienceHook } from 'src/hooks/use-experience-hook';
+import { useSearchHook } from 'src/hooks/use-search.hooks';
+import { useUpload } from 'src/hooks/use-upload.hook';
+import { ExperienceProps } from 'src/interfaces/experience';
+import i18n from 'src/locale';
+
+export const ExperienceContainer: React.FC = () => {
+  // TODO: separate hook for tag, people and experience
+  const {
+    selectedExperience,
+    tags,
+    people,
+    saveExperience,
+    searchTags,
+    searchPeople,
+    loadExperience,
+  } = useExperienceHook();
+  const { searchUsers, users } = useSearchHook();
+  const style = useStyles();
+
+  const { uploadImage } = useUpload();
+  const router = useRouter();
+
+  const onImageUpload = async (files: File[]) => {
+    const url = await uploadImage(files[0]);
+
+    return url ?? '';
+  };
+
+  const onSave = (attributes: ExperienceProps) => {
+    saveExperience(attributes, (experienceId: string) => {
+      router.push(`/experience/${experienceId}`);
+
+      loadExperience();
+    });
+  };
+
+  const handleSearchTags = debounce((query: string) => {
+    searchTags(query);
+  }, 300);
+
+  const handleSearchPeople = debounce((query: string) => {
+    searchPeople(query);
+  }, 300);
+
+  const handleSearchUser = debounce((query: string) => {
+    searchUsers(query);
+  }, 300);
+
+  return (
+    <>
+      <div className={style.mb}>
+        <TopNavbarComponent
+          description={i18n.t('TopNavbar.Subtitle.Experience_Create')}
+          sectionTitle={i18n.t('TopNavbar.Title.Experience')}
+        />
+      </div>
+      <div className={style.box}>
+        <ExperienceTimelinePost
+          isEdit={false}
+          experience={selectedExperience}
+          tags={tags}
+          people={people}
+          onSearchTags={handleSearchTags}
+          onImageUpload={onImageUpload}
+          onSearchPeople={handleSearchPeople}
+          onSave={onSave}
+          onSearchUser={handleSearchUser}
+          users={users}
+        />
+      </div>
+    </>
+  );
+};
diff --git a/src/components/ExperienceTimelinePost/Experience.styles.ts b/src/components/ExperienceTimelinePost/Experience.styles.ts
new file mode 100644
index 000000000..47b8e8295
--- /dev/null
+++ b/src/components/ExperienceTimelinePost/Experience.styles.ts
@@ -0,0 +1,178 @@
+import {
+  createStyles,
+  makeStyles,
+  Theme,
+  alpha,
+} from '@material-ui/core/styles';
+
+export const useStyles = makeStyles((theme: Theme) =>
+  createStyles({
+    '@global': {
+      ' .MuiAutocomplete-option[aria-selected="true"]': {
+        background: 'none',
+      },
+      ' .MuiAutocomplete-option[data-focus="true"]': {
+        backgroundColor: alpha('#FFC857', 0.15),
+      },
+      ' .MuiAutocomplete-tag .MuiSvgIcon-root': {
+        width: 14,
+        height: 14,
+      },
+
+      ' .MuiFormHelperText-root': {
+        marginLeft: 0,
+
+        [theme.breakpoints.down('xs')]: {
+          fontSize: 12,
+        },
+      },
+    },
+    root: {
+      background: '#FFF',
+      borderRadius: 10,
+      marginBottom: 24,
+
+      '& .MuiAutocomplete-popupIndicatorOpen': {
+        transform: 'none',
+      },
+
+      [theme.breakpoints.down('xs')]: {
+        padding: '20px',
+      },
+    },
+    header: {
+      display: 'flex',
+      justifyContent: 'space-between',
+      alignItems: 'center',
+      marginBottom: theme.spacing(2),
+    },
+    content: {
+      display: 'flex',
+      flexDirection: 'row',
+      gap: theme.spacing(3),
+    },
+    row1: {
+      minWidth: 100,
+      display: 'flex',
+      flexDirection: 'column',
+      alignItems: 'center',
+      paddingTop: 8,
+      gap: 8,
+    },
+    boxImage: {
+      width: 100,
+      height: 100,
+      borderRadius: 10,
+      border: '2px dashed #C2C2C2',
+      backgroundColor: '#F5F5F5',
+    },
+    row2: {
+      width: '100%',
+      overflow: 'hidden',
+      paddingTop: 8,
+    },
+    title: {
+      marginBottom: 30,
+      fontSize: theme.typography.h5.fontSize,
+      fontWeight: 400,
+    },
+    preview: {
+      marginBottom: 30,
+
+      '& .MuiListItem-root:hover': {
+        backgroundColor: alpha('#FFC857', 0.15),
+
+        '&::before,&::after': {
+          content: '""',
+          position: 'absolute',
+          width: 30,
+          height: '100%',
+          top: 0,
+          backgroundColor: alpha('#FFC857', 0.15),
+        },
+        '&::before': {
+          left: -30,
+        },
+        '&::after': {
+          right: -30,
+        },
+      },
+    },
+    postTextContainer: {
+      border: '1px solid #E5E5E5',
+      width: '100%',
+      padding: '20px',
+      borderRadius: '5px',
+      justifyContent: 'center',
+      alignItems: 'center',
+      textAlign: 'center',
+      marginBottom: 36,
+    },
+    textPost: {
+      fontWeight: 600,
+      fontSize: 18,
+    },
+    textPostDetail: {
+      fontWeight: 400,
+      fontSize: 14,
+      marginTop: 9,
+    },
+    label: {
+      background: '#FFF',
+      paddingLeft: 6,
+      paddingRight: 6,
+    },
+    social: {
+      color: theme.palette.primary.main,
+    },
+    people: {},
+    removePeople: {
+      '& .MuiSvgIcon-root': {
+        fill: 'currentColor',
+      },
+    },
+    mb: {
+      marginBottom: '10px',
+    },
+    loading: {
+      display: 'flex',
+      justifyContent: 'center',
+      alignItems: 'center',
+      position: 'absolute',
+      zIndex: 999,
+      width: '100%',
+      height: '100%',
+      textAlign: 'center',
+    },
+    option: {
+      width: '100%',
+    },
+    counter: {
+      position: 'absolute',
+      right: 0,
+      bottom: 0,
+      color: '#898888',
+    },
+    box: {
+      [theme.breakpoints.down('xs')]: {
+        padding: '0px 20px 20px 20px',
+      },
+    },
+    fill: {
+      fill: 'currentColor',
+      '& .MuiSvgIcon-root': {
+        fill: 'currentColor',
+      },
+    },
+    formControl: {
+      marginBottom: 0,
+    },
+    customVisibility: {
+      maxHeight: '300px',
+      overflowY: 'scroll',
+      border: '1px solid #FFD24D',
+      borderRadius: '4px',
+      padding: '0 10px',
+    },
+  }),
+);
diff --git a/src/components/ExperienceTimelinePost/ExperienceEditor.stories.tsx b/src/components/ExperienceTimelinePost/ExperienceEditor.stories.tsx
new file mode 100644
index 000000000..8f8330272
--- /dev/null
+++ b/src/components/ExperienceTimelinePost/ExperienceEditor.stories.tsx
@@ -0,0 +1,106 @@
+import { ComponentStory, ComponentMeta } from '@storybook/react';
+
+import React from 'react';
+
+import { SocialsEnum } from '../../interfaces/social';
+import { ExperienceTimelinePost } from './ExperienceTimelinePost';
+
+export default {
+  title: 'UI Revamp v2.0/components/Experience Editor',
+  component: ExperienceTimelinePost,
+  argTypes: {},
+} as ComponentMeta<typeof ExperienceTimelinePost>;
+
+const Template: ComponentStory<typeof ExperienceTimelinePost> = args => (
+  <ExperienceTimelinePost {...args} />
+);
+
+export const CreateExperience = Template.bind({});
+CreateExperience.args = {
+  onSave: console.log,
+  onImageUpload: async (files: File[]) => {
+    return 'https://res.cloudinary.com/dsget80gs/lu2f67ljt0oqnaacuu7y.jpg';
+  },
+  tags: [
+    {
+      id: 'crypto',
+      count: 0,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+    },
+    {
+      id: 'nsfw',
+      count: 0,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+    },
+  ],
+  people: [
+    {
+      id: '1',
+      name: 'Person 1',
+      originUserId: '1',
+      platform: SocialsEnum.FACEBOOK,
+      profilePictureURL:
+        'https://res.cloudinary.com/dsget80gs/bd75blw2pnmpj9aqwdxm.png',
+      username: 'personone',
+    },
+    {
+      id: '2',
+      name: 'Person 2',
+      originUserId: '2',
+      platform: SocialsEnum.FACEBOOK,
+      profilePictureURL:
+        'https://res.cloudinary.com/dsget80gs/rvi6x1stnczatom2jq2y.jpg',
+      username: 'persontwo',
+    },
+  ],
+};
+
+export const EditExperience = Template.bind({});
+EditExperience.args = {
+  onSave: console.log,
+  onImageUpload: async (files: File[]) => {
+    return 'https://res.cloudinary.com/dsget80gs/lu2f67ljt0oqnaacuu7y.jpg';
+  },
+  experience: {
+    name: 'Example experience',
+    description: 'Sample',
+    people: [],
+    allowedTags: ['crypto', 'near'],
+  },
+  tags: [
+    {
+      id: 'crypto',
+      count: 0,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+    },
+    {
+      id: 'nsfw',
+      count: 0,
+      createdAt: new Date(),
+      updatedAt: new Date(),
+    },
+  ],
+  people: [
+    {
+      id: '1',
+      name: 'Person 1',
+      originUserId: '1',
+      platform: SocialsEnum.FACEBOOK,
+      profilePictureURL:
+        'https://res.cloudinary.com/dsget80gs/bd75blw2pnmpj9aqwdxm.png',
+      username: 'personone',
+    },
+    {
+      id: '2',
+      name: 'Person 2',
+      originUserId: '2',
+      platform: SocialsEnum.FACEBOOK,
+      profilePictureURL:
+        'https://res.cloudinary.com/dsget80gs/rvi6x1stnczatom2jq2y.jpg',
+      username: 'persontwo',
+    },
+  ],
+};
diff --git a/src/components/ExperienceTimelinePost/ExperienceTimelinePost.tsx b/src/components/ExperienceTimelinePost/ExperienceTimelinePost.tsx
new file mode 100644
index 000000000..01b9cfd14
--- /dev/null
+++ b/src/components/ExperienceTimelinePost/ExperienceTimelinePost.tsx
@@ -0,0 +1,932 @@
+import {
+  SearchIcon,
+  XCircleIcon,
+  PlusCircleIcon,
+  ChevronDownIcon,
+} from '@heroicons/react/solid';
+
+import React, { useState, useEffect, useRef } from 'react';
+
+import { useRouter } from 'next/router';
+
+import {
+  FormControl,
+  FormHelperText,
+  IconButton,
+  InputLabel,
+  OutlinedInput,
+  SvgIcon,
+  TextField,
+  Typography,
+} from '@material-ui/core';
+import CircularProgress from '@material-ui/core/CircularProgress';
+import {
+  Autocomplete,
+  AutocompleteChangeReason,
+  AutocompleteRenderOptionState,
+} from '@material-ui/lab';
+
+import {
+  ExperienceProps,
+  VisibilityItem,
+  Tag,
+  SelectedUserIds,
+} from '../../interfaces/experience';
+import { People } from '../../interfaces/people';
+import { Dropzone } from '../atoms/Dropzone';
+import { ListItemPeopleComponent } from '../atoms/ListItem/ListItemPeople';
+import { Loading } from '../atoms/Loading';
+import ShowIf from '../common/show-if.component';
+import { useStyles } from './Experience.styles';
+
+import { debounce, isEmpty } from 'lodash';
+import { useExperienceHook } from 'src/hooks/use-experience-hook';
+import { useSearchHook } from 'src/hooks/use-search.hooks';
+import { User } from 'src/interfaces/user';
+import * as UserAPI from 'src/lib/api/user';
+import i18n from 'src/locale';
+
+type ExperienceEditorProps = {
+  type?: 'Clone' | 'Edit' | 'Create';
+  isEdit?: boolean;
+  experience?: ExperienceProps;
+  tags: Tag[];
+  people: People[];
+  onSearchTags: (query: string) => void;
+  onSearchPeople: (query: string) => void;
+  onSave: (experience: ExperienceProps) => void;
+  onImageUpload: (files: File[]) => Promise<string>;
+  onSearchUser?: (query: string) => void;
+  users?: User[];
+  onCancel?: () => void;
+};
+
+enum TagsProps {
+  ALLOWED = 'allowed',
+  PROHIBITED = 'prohibited',
+}
+
+const DEFAULT_EXPERIENCE: ExperienceProps = {
+  name: '',
+  allowedTags: [],
+  people: [],
+  prohibitedTags: [],
+  visibility: '',
+  selectedUserIds: [],
+};
+
+export const ExperienceTimelinePost: React.FC<ExperienceEditorProps> =
+  props => {
+    const {
+      experience = DEFAULT_EXPERIENCE,
+      people,
+      tags,
+      onSave,
+      onImageUpload,
+      onSearchTags,
+      onSearchPeople,
+      onSearchUser,
+      users,
+      onCancel,
+    } = props;
+    const styles = useStyles();
+
+    const { loadPostExperience } = useExperienceHook();
+    const router = useRouter();
+    const { clearUsers } = useSearchHook();
+
+    const ref = useRef(null);
+    const [experienceId, setExperienceId] = useState<string | undefined>();
+    console.log(experienceId);
+    const [newExperience, setNewExperience] =
+      useState<ExperienceProps>(experience);
+    const [image, setImage] = useState<string | undefined>(
+      experience.experienceImageURL,
+    );
+    const [, setDetailChanged] = useState<boolean>(false);
+    const [isLoading, setIsloading] = useState<boolean>(false);
+    const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
+    const [selectedVisibility, setSelectedVisibility] =
+      useState<VisibilityItem>();
+    const [selectedUserIds, setSelectedUserIds] = useState<User[]>([]);
+    const [pageUserIds, setPageUserIds] = React.useState<number>(1);
+    const [isLoadingSelectedUser, setIsLoadingSelectedUser] =
+      useState<boolean>(false);
+    const [errors, setErrors] = useState({
+      name: false,
+      picture: false,
+      tags: false,
+      people: false,
+      visibility: false,
+      selectedUserId: false,
+    });
+
+    useEffect(() => {
+      const experienceId = router.query.experienceId as string | null;
+      if (experienceId) {
+        setExperienceId(experienceId);
+        loadPostExperience(experienceId);
+      }
+    }, []);
+
+    useEffect(() => {
+      if (isSubmitted) {
+        validateExperience();
+      }
+    }, [isSubmitted, newExperience]);
+
+    const handleSearchTags = (event: React.ChangeEvent<HTMLInputElement>) => {
+      const debounceSubmit = debounce(() => {
+        onSearchTags(event.target.value);
+      }, 300);
+
+      debounceSubmit();
+    };
+
+    const handleSearchPeople = (event: React.ChangeEvent<HTMLInputElement>) => {
+      const debounceSubmit = debounce(() => {
+        onSearchPeople(event.target.value);
+      }, 300);
+
+      debounceSubmit();
+    };
+
+    const clearSearchedPeople = () => {
+      const debounceSubmit = debounce(() => {
+        onSearchPeople('');
+      }, 300);
+
+      debounceSubmit();
+    };
+
+    const handleImageUpload = async (files: File[]) => {
+      if (files.length > 0) {
+        setIsloading(true);
+        const url = await onImageUpload(files);
+
+        setIsloading(false);
+        setImage(url);
+        setNewExperience({ ...newExperience, experienceImageURL: url });
+      } else {
+        setNewExperience({ ...newExperience, experienceImageURL: undefined });
+      }
+
+      setDetailChanged(true);
+    };
+
+    const handleChange =
+      (field: keyof ExperienceProps) =>
+      (event: React.ChangeEvent<HTMLInputElement>) => {
+        const value = event.target.value.trimStart();
+
+        setNewExperience(prevExperience => ({
+          ...prevExperience,
+          [field]: value,
+        }));
+
+        setDetailChanged(experience[field] !== value);
+      };
+
+    const handleTagsInputChange = (
+      // eslint-disable-next-line @typescript-eslint/ban-types
+      event: React.ChangeEvent<{}>,
+      newValue: string,
+      type: TagsProps,
+    ) => {
+      const options = newValue.split(/[ ,]+/);
+
+      let tmpTags: string[] = [];
+      if (type === TagsProps.ALLOWED) {
+        tmpTags = newExperience.allowedTags;
+      } else if (type === TagsProps.PROHIBITED) {
+        tmpTags = newExperience.prohibitedTags ?? [];
+      }
+
+      const fieldValue = tmpTags
+        .concat(options)
+        .map(x => x.trim())
+        .filter(x => x);
+
+      if (options.length > 1) {
+        handleTagsChange(event, fieldValue, 'create-option', type);
+      }
+    };
+
+    const handleTagsChange = (
+      // eslint-disable-next-line @typescript-eslint/ban-types
+      event: React.ChangeEvent<{}>,
+      value: string[],
+      reason: AutocompleteChangeReason,
+      type: TagsProps,
+    ) => {
+      const data = [...new Set(value.map(tag => tag.replace('#', '')))];
+
+      const prohibitedTagsChanged =
+        type === TagsProps.PROHIBITED &&
+        (data.filter(
+          tag =>
+            !experience?.prohibitedTags ||
+            !experience.prohibitedTags.includes(tag),
+        ).length > 0 ||
+          experience?.prohibitedTags?.length !== data.length);
+      const allowedTagsChanged =
+        type === TagsProps.ALLOWED &&
+        (data.filter(tag => !experience.allowedTags.includes(tag)).length > 0 ||
+          data.length !== experience.allowedTags.length);
+
+      setDetailChanged(prohibitedTagsChanged || allowedTagsChanged);
+
+      if (reason === 'remove-option') {
+        if (type === TagsProps.ALLOWED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            allowedTags: data,
+          }));
+        } else if (type === TagsProps.PROHIBITED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            prohibitedTags: data,
+          }));
+        }
+      }
+
+      if (reason === 'create-option') {
+        if (type === TagsProps.ALLOWED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            allowedTags: data,
+          }));
+        } else if (type === TagsProps.PROHIBITED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            prohibitedTags: data,
+          }));
+        }
+      }
+
+      if (reason === 'select-option') {
+        if (type === TagsProps.ALLOWED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            allowedTags: data,
+          }));
+        } else if (type === TagsProps.PROHIBITED) {
+          setNewExperience(prevExperience => ({
+            ...prevExperience,
+            prohibitedTags: data,
+          }));
+        }
+      }
+    };
+
+    const handlePeopleChange = (
+      // eslint-disable-next-line @typescript-eslint/ban-types
+      event: React.ChangeEvent<{}>,
+      value: People[],
+      reason: AutocompleteChangeReason,
+    ) => {
+      const people = newExperience?.people ? newExperience.people : [];
+      if (reason === 'select-option') {
+        setNewExperience(prevExperience => ({
+          ...prevExperience,
+          people: [
+            ...people,
+            ...value.filter(option => people.indexOf(option) === -1),
+          ],
+        }));
+        clearSearchedPeople();
+      }
+
+      setDetailChanged(true);
+    };
+
+    const removeSelectedPeople = (selected: People) => () => {
+      setNewExperience(prevExperience => ({
+        ...prevExperience,
+        people: prevExperience?.people
+          ? prevExperience?.people.filter(people => people.id != selected.id)
+          : [],
+      }));
+
+      setDetailChanged(true);
+    };
+
+    const validateExperience = (): boolean => {
+      const validName = newExperience.name.length > 0;
+      // const validPicture = Boolean(newExperience.experienceImageURL);
+      const validTags = newExperience.allowedTags.length >= 0;
+      const validPeople =
+        newExperience.people.filter(people => !isEmpty(people.id)).length >= 0;
+      const validSelectedUserIds =
+        selectedVisibility && selectedVisibility?.id === 'selected_user'
+          ? selectedUserIds.length > 0
+          : !isEmpty(selectedVisibility?.id);
+      const validVisibility = !isEmpty(selectedVisibility?.id);
+
+      setErrors({
+        name: !validName,
+        picture: false,
+        tags: !validTags,
+        people: !validPeople,
+        visibility: !validVisibility,
+        selectedUserId: !validSelectedUserIds,
+      });
+
+      return (
+        validName &&
+        validTags &&
+        validPeople &&
+        validVisibility &&
+        validSelectedUserIds
+      );
+    };
+
+    const saveExperience = () => {
+      setIsSubmitted(true);
+
+      const valid = validateExperience();
+
+      if (valid) {
+        onSave(newExperience);
+      } else {
+        ref.current?.scrollIntoView({
+          behavior: 'smooth',
+          block: 'start',
+        });
+      }
+    };
+
+    const visibilityList: VisibilityItem[] = [
+      {
+        id: 'public',
+        name: i18n.t('Experience.Editor.Visibility.Public'),
+      },
+      {
+        id: 'private',
+        name: i18n.t('Experience.Editor.Visibility.OnlyMe'),
+      },
+      {
+        id: 'selected_user',
+        name: i18n.t('Experience.Editor.Visibility.Custom'),
+      },
+      {
+        id: 'friend',
+        name: i18n.t('Experience.Editor.Visibility.Friend_Only'),
+      },
+    ];
+
+    const handleVisibilityChange = (
+      // eslint-disable-next-line @typescript-eslint/ban-types
+      event: React.ChangeEvent<{}>,
+      value: VisibilityItem,
+      reason: AutocompleteChangeReason,
+    ) => {
+      setSelectedVisibility(value);
+      setNewExperience(prevExperience => ({
+        ...prevExperience,
+        visibility: value?.id,
+      }));
+
+      setDetailChanged(true);
+    };
+
+    const handleSearchUser = (event: React.ChangeEvent<HTMLInputElement>) => {
+      const debounceSubmit = debounce(() => {
+        onSearchUser(event.target.value);
+      }, 300);
+
+      debounceSubmit();
+    };
+
+    const clearSearchedUser = () => {
+      const debounceSubmit = debounce(() => {
+        onSearchUser('');
+      }, 300);
+
+      debounceSubmit();
+    };
+
+    const handleVisibilityPeopleChange = (
+      // eslint-disable-next-line @typescript-eslint/ban-types
+      event: React.ChangeEvent<{}>,
+      value: User[],
+      reason: AutocompleteChangeReason,
+    ) => {
+      const people = selectedUserIds ? selectedUserIds : [];
+      console.log({ value });
+      if (reason === 'select-option') {
+        setSelectedUserIds([
+          ...people,
+          ...value.filter(option => people.indexOf(option) === -1),
+        ]);
+        clearSearchedUser();
+        clearUsers();
+      }
+
+      setDetailChanged(true);
+    };
+
+    const removeVisibilityPeople = (selected: User) => () => {
+      setSelectedUserIds(
+        selectedUserIds
+          ? selectedUserIds.filter(people => people.id != selected.id)
+          : [],
+      );
+
+      setDetailChanged(true);
+    };
+
+    const mappingUserIds = () => {
+      console.log({ selectedVisibility });
+      if (selectedVisibility?.id === 'selected_user') {
+        const timestamp = Date.now();
+        const mapIds = Object.values(
+          selectedUserIds.map(option => {
+            return {
+              userId: option.id,
+              addedAt: timestamp,
+            };
+          }),
+        );
+        setNewExperience(prevExperience => ({
+          ...prevExperience,
+          selectedUserIds: mapIds,
+        }));
+      } else {
+        setNewExperience(prevExperience => ({
+          ...prevExperience,
+          selectedUserIds: [],
+        }));
+      }
+    };
+
+    useEffect(() => {
+      mappingUserIds();
+      setDetailChanged(true);
+      // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, [selectedUserIds, experience]);
+
+    const getSelectedIds = async (selected: SelectedUserIds[]) => {
+      setIsLoadingSelectedUser(true);
+      const userIds = selected.map(e => e.userId);
+      const response = await UserAPI.getUserByIds(userIds, pageUserIds);
+      setSelectedUserIds([
+        ...selectedUserIds,
+        ...(response?.data as unknown as User[]),
+      ]);
+      setIsLoadingSelectedUser(false);
+      if (pageUserIds < response.meta.totalPageCount)
+        setPageUserIds(pageUserIds + 1);
+    };
+
+    React.useEffect(() => {
+      getSelectedIds(experience?.selectedUserIds);
+    }, [experience, pageUserIds]);
+
+    useEffect(() => {
+      if (experience) {
+        const visibility = visibilityList.find(
+          option => option.id === experience?.visibility,
+        );
+        setSelectedVisibility(visibility);
+
+        getSelectedIds(experience?.selectedUserIds);
+      }
+    }, [experience]);
+
+    return (
+      <div className={styles.root} ref={ref}>
+        <div className={styles.header}>
+          <FormControl
+            classes={{ root: styles.formControl }}
+            style={{
+              display: 'flex',
+              flexDirection: 'row',
+              justifyContent: 'flex-end',
+              marginLeft: 'auto',
+            }}>
+            <Typography
+              variant="h5"
+              color="primary"
+              onClick={saveExperience}
+              style={{ cursor: 'pointer' }}>
+              Save
+            </Typography>
+            <Typography
+              variant="h5"
+              style={{ color: 'red', marginLeft: 10, cursor: 'pointer' }}
+              onClick={onCancel}>
+              Cancel
+            </Typography>
+          </FormControl>
+        </div>
+        <div className={styles.content}>
+          <div className={styles.row1}>
+            <FormControl
+              fullWidth
+              variant="outlined"
+              style={{ position: 'relative', zIndex: 100 }}
+              error={errors.picture}>
+              <Dropzone
+                error={errors.picture}
+                onImageSelected={handleImageUpload}
+                value={image}
+                border="solid"
+                maxSize={3}
+                width={100}
+                height={100}
+                usage="experience"
+                label={i18n.t('Dropzone.Btn.Exp_Add')}
+              />
+              <ShowIf condition={isLoading}>
+                <div className={styles.loading}>
+                  <CircularProgress size={32} color="primary" />
+                </div>
+              </ShowIf>
+            </FormControl>
+          </div>
+          <div className={styles.row2}>
+            <FormControl fullWidth variant="outlined" error={errors.name}>
+              <InputLabel htmlFor="experience-name">
+                {i18n.t('Experience.Editor.Subtitle_1')}
+              </InputLabel>
+              <OutlinedInput
+                id="experience-name"
+                placeholder={i18n.t('Experience.Editor.Subtitle_1')}
+                value={newExperience?.name || ''}
+                onChange={handleChange('name')}
+                labelWidth={110}
+                inputProps={{ maxLength: 50 }}
+              />
+              <FormHelperText id="experience-name-error">
+                {i18n.t('Experience.Editor.Helper.Name')}
+              </FormHelperText>
+              <Typography variant="subtitle1" className={styles.counter}>
+                {newExperience?.name.length ?? 0}/50
+              </Typography>
+            </FormControl>
+
+            <Autocomplete
+              id="experience-visibility"
+              options={visibilityList}
+              getOptionLabel={option => option.name}
+              getOptionSelected={(option, value) => option?.id === value.id}
+              autoHighlight={false}
+              disableClearable
+              onChange={handleVisibilityChange}
+              value={selectedVisibility || null}
+              popupIcon={
+                <SvgIcon
+                  classes={{ root: styles.fill }}
+                  component={ChevronDownIcon}
+                  viewBox={'0 0 20 20'}
+                />
+              }
+              renderInput={({ inputProps, ...rest }) => (
+                <TextField
+                  {...rest}
+                  error={errors.visibility}
+                  label={i18n.t('Experience.Editor.Label_4')}
+                  placeholder={i18n.t('Experience.Editor.Placeholder_4')}
+                  variant="outlined"
+                  inputProps={{ ...inputProps, readOnly: true }}
+                />
+              )}
+            />
+
+            {selectedVisibility?.id === 'selected_user' && (
+              <>
+                <Autocomplete
+                  id="experience-custom-visibility-people"
+                  onBlur={clearUsers}
+                  className={styles.people}
+                  value={(selectedUserIds as User[]) ?? []}
+                  multiple
+                  options={users}
+                  getOptionSelected={(option, value) => option.id === value.id}
+                  filterSelectedOptions={true}
+                  getOptionLabel={option => `${option.username} ${option.name}`}
+                  disableClearable
+                  autoHighlight={false}
+                  popupIcon={
+                    <SvgIcon
+                      classes={{ root: styles.fill }}
+                      component={SearchIcon}
+                      viewBox={'0 0 20 20'}
+                    />
+                  }
+                  onChange={handleVisibilityPeopleChange}
+                  renderTags={() => null}
+                  renderInput={params => (
+                    <TextField
+                      {...params}
+                      error={errors.selectedUserId}
+                      label={i18n.t('Experience.Editor.Placeholder_5')}
+                      placeholder={i18n.t('Experience.Editor.Placeholder_5')}
+                      variant="outlined"
+                      onChange={handleSearchUser}
+                      InputProps={{
+                        ...params.InputProps,
+                        endAdornment: (
+                          <React.Fragment>
+                            {params.InputProps.endAdornment}
+                          </React.Fragment>
+                        ),
+                      }}
+                      helperText={i18n.t('Experience.Editor.Helper.People')}
+                    />
+                  )}
+                  renderOption={(
+                    option,
+                    state: AutocompleteRenderOptionState,
+                  ) => {
+                    if (option.id === '') return null;
+                    return (
+                      <div className={styles.option}>
+                        <ListItemPeopleComponent
+                          id="selectable-experience-list-item"
+                          title={option.name}
+                          subtitle={
+                            <Typography variant="caption">
+                              @{option.username}
+                            </Typography>
+                          }
+                          avatar={option.profilePictureURL}
+                          platform={'myriad'}
+                          action={
+                            <IconButton className={styles.removePeople}>
+                              {state.selected ? (
+                                <SvgIcon
+                                  classes={{ root: styles.fill }}
+                                  component={XCircleIcon}
+                                  color="error"
+                                  viewBox={'0 0 20 20'}
+                                />
+                              ) : (
+                                <SvgIcon
+                                  classes={{ root: styles.fill }}
+                                  component={PlusCircleIcon}
+                                  viewBox={'0 0 20 20'}
+                                />
+                              )}
+                            </IconButton>
+                          }
+                        />
+                      </div>
+                    );
+                  }}
+                />
+
+                <div className={styles.preview}>
+                  <div className={styles.customVisibility}>
+                    <ShowIf condition={isLoadingSelectedUser}>
+                      <Loading />
+                    </ShowIf>
+                    {selectedUserIds
+                      .filter(people => !isEmpty(people.id))
+                      .map(people => (
+                        <ListItemPeopleComponent
+                          id="selected-experience-list-item"
+                          key={people.id}
+                          title={people.name}
+                          subtitle={
+                            <Typography variant="caption">
+                              @{people.username}
+                            </Typography>
+                          }
+                          avatar={people.profilePictureURL}
+                          platform={'myriad'}
+                          action={
+                            <IconButton
+                              onClick={removeVisibilityPeople(people)}>
+                              <SvgIcon
+                                classes={{ root: styles.fill }}
+                                component={XCircleIcon}
+                                color="error"
+                                viewBox={'0 0 20 20'}
+                              />
+                            </IconButton>
+                          }
+                        />
+                      ))}
+                  </div>
+                </div>
+              </>
+            )}
+
+            <FormControl
+              fullWidth
+              variant="outlined"
+              style={{ position: 'relative' }}>
+              <InputLabel htmlFor="experience-description">
+                {i18n.t('Experience.Editor.Subtitle_2')}
+              </InputLabel>
+              <OutlinedInput
+                id="experience-description"
+                placeholder={i18n.t('Experience.Editor.Subtitle_2')}
+                value={newExperience?.description || ''}
+                onChange={handleChange('description')}
+                labelWidth={70}
+                inputProps={{ maxLength: 280 }}
+                multiline
+              />
+              <FormHelperText id="experience-description-error">
+                &nbsp;
+              </FormHelperText>
+              <Typography variant="subtitle1" className={styles.counter}>
+                {newExperience?.description?.length ?? 0}/280
+              </Typography>
+            </FormControl>
+
+            <Autocomplete<string, true, true, true>
+              className={styles.fill}
+              id="experience-tags-include"
+              freeSolo
+              multiple
+              value={newExperience.allowedTags ?? []}
+              options={tags
+                .map(tag => tag.id)
+                .filter(tag => !newExperience.allowedTags.includes(tag))}
+              disableClearable
+              onChange={(event, value, reason) => {
+                handleTagsChange(event, value, reason, TagsProps.ALLOWED);
+              }}
+              onInputChange={(event, value) => {
+                handleTagsInputChange(event, value, TagsProps.ALLOWED);
+              }}
+              getOptionLabel={option => `#${option}`}
+              renderInput={params => (
+                <TextField
+                  {...params}
+                  error={errors.tags}
+                  label={i18n.t('Experience.Editor.Label_1')}
+                  variant="outlined"
+                  placeholder={
+                    newExperience.allowedTags.length === 0
+                      ? i18n.t('Experience.Editor.Placeholder_1')
+                      : undefined
+                  }
+                  onChange={handleSearchTags}
+                  helperText={''}
+                  InputProps={{
+                    ...params.InputProps,
+                    endAdornment: (
+                      <React.Fragment>
+                        {params.InputProps.endAdornment}
+                      </React.Fragment>
+                    ),
+                  }}
+                />
+              )}
+            />
+
+            <Autocomplete
+              className={styles.fill}
+              id="experience-tags-exclude"
+              freeSolo
+              multiple
+              value={newExperience?.prohibitedTags ?? []}
+              options={tags
+                .map(tag => tag.id)
+                .filter(tag => !newExperience.prohibitedTags?.includes(tag))}
+              disableClearable
+              onChange={(event, value, reason) => {
+                handleTagsChange(event, value, reason, TagsProps.PROHIBITED);
+              }}
+              onInputChange={(event, value) => {
+                handleTagsInputChange(event, value, TagsProps.PROHIBITED);
+              }}
+              getOptionLabel={option => `#${option}`}
+              renderInput={params => (
+                <TextField
+                  {...params}
+                  label={i18n.t('Experience.Editor.Label_2')}
+                  variant="outlined"
+                  placeholder={
+                    newExperience.prohibitedTags?.length === 0
+                      ? i18n.t('Experience.Editor.Placeholder_2')
+                      : undefined
+                  }
+                  onChange={handleSearchTags}
+                  InputProps={{
+                    ...params.InputProps,
+                    endAdornment: (
+                      <React.Fragment>
+                        {params.InputProps.endAdornment}
+                      </React.Fragment>
+                    ),
+                  }}
+                />
+              )}
+            />
+
+            <Autocomplete
+              id="experience-people"
+              className={styles.people}
+              value={(newExperience?.people as People[]) ?? []}
+              multiple
+              options={people}
+              getOptionSelected={(option, value) => option.id === value.id}
+              filterSelectedOptions={true}
+              getOptionLabel={option => `${option.username} ${option.name}`}
+              disableClearable
+              autoHighlight={false}
+              popupIcon={
+                <SvgIcon
+                  classes={{ root: styles.fill }}
+                  component={SearchIcon}
+                  viewBox={'0 0 20 20'}
+                />
+              }
+              onChange={handlePeopleChange}
+              renderTags={() => null}
+              renderInput={params => (
+                <TextField
+                  {...params}
+                  error={errors.people}
+                  label={i18n.t('Experience.Editor.Label_3')}
+                  placeholder={i18n.t('Experience.Editor.Placeholder_3')}
+                  variant="outlined"
+                  onChange={handleSearchPeople}
+                  InputProps={{
+                    ...params.InputProps,
+                    endAdornment: (
+                      <React.Fragment>
+                        {params.InputProps.endAdornment}
+                      </React.Fragment>
+                    ),
+                  }}
+                  helperText={''}
+                />
+              )}
+              renderOption={(option, state: AutocompleteRenderOptionState) => {
+                if (option.id === '') return null;
+                return (
+                  <div className={styles.option}>
+                    <ListItemPeopleComponent
+                      id="selectable-experience-list-item"
+                      title={option.name}
+                      subtitle={
+                        <Typography variant="caption">
+                          @{option.username}
+                        </Typography>
+                      }
+                      avatar={option.profilePictureURL}
+                      platform={option.platform}
+                      action={
+                        <IconButton className={styles.removePeople}>
+                          {state.selected ? (
+                            <SvgIcon
+                              classes={{ root: styles.fill }}
+                              component={XCircleIcon}
+                              color="error"
+                              viewBox={'0 0 20 20'}
+                            />
+                          ) : (
+                            <SvgIcon
+                              classes={{ root: styles.fill }}
+                              component={PlusCircleIcon}
+                              viewBox={'0 0 20 20'}
+                            />
+                          )}
+                        </IconButton>
+                      }
+                    />
+                  </div>
+                );
+              }}
+            />
+
+            <div className={styles.preview}>
+              {newExperience.people
+                .filter(people => !isEmpty(people.id))
+                .map(people => (
+                  <ListItemPeopleComponent
+                    id="selected-experience-list-item"
+                    key={people.id}
+                    title={people.name}
+                    subtitle={
+                      <Typography variant="caption">
+                        @{people.username}
+                      </Typography>
+                    }
+                    avatar={people.profilePictureURL}
+                    platform={people.platform}
+                    action={
+                      <IconButton onClick={removeSelectedPeople(people)}>
+                        <SvgIcon
+                          classes={{ root: styles.fill }}
+                          component={XCircleIcon}
+                          color="error"
+                          viewBox={'0 0 20 20'}
+                        />
+                      </IconButton>
+                    }
+                  />
+                ))}
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  };
diff --git a/src/components/ExperienceTimelinePost/index.ts b/src/components/ExperienceTimelinePost/index.ts
new file mode 100644
index 000000000..84314daf5
--- /dev/null
+++ b/src/components/ExperienceTimelinePost/index.ts
@@ -0,0 +1 @@
+export * from './ExperienceTimelinePost';
diff --git a/src/components/PostCreate/PostCreate.tsx b/src/components/PostCreate/PostCreate.tsx
index 4e4c7a12a..5cda3af1f 100644
--- a/src/components/PostCreate/PostCreate.tsx
+++ b/src/components/PostCreate/PostCreate.tsx
@@ -1,6 +1,6 @@
 import { ArrowLeftIcon, GiftIcon, TrashIcon } from '@heroicons/react/outline';
 
-import React, { useRef, useState } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
 import { shallowEqual, useDispatch, useSelector } from 'react-redux';
 
 import dynamic from 'next/dynamic';
@@ -23,8 +23,7 @@ import ExclusiveCreate from 'components/ExclusiveContentCreate/ExclusiveCreate';
 import Reveal from 'components/ExclusiveContentCreate/Reveal/Reveal';
 import ExperienceListBarCreatePost from 'components/ExperienceList/ExperienceListBarCreatePost';
 import { useExperienceList } from 'components/ExperienceList/hooks/use-experience-list.hook';
-import { ExperiencePost } from 'components/ExperiencePost';
-import { SearchBox } from 'components/atoms/Search';
+import { ExperienceTimelinePost } from 'components/ExperienceTimelinePost';
 import useConfirm from 'components/common/Confirm/use-confirm.hook';
 import { getEditorSelectors } from 'components/common/Editor/store';
 import { useEnqueueSnackbar } from 'components/common/Snackbar/useEnqueueSnackbar.hook';
@@ -37,10 +36,15 @@ import { useSearchHook } from 'src/hooks/use-search.hooks';
 import { useUpload } from 'src/hooks/use-upload.hook';
 import { InfoIconYellow } from 'src/images/Icons';
 import { ExclusiveContentPost } from 'src/interfaces/exclusive';
-import { ExperienceProps, WrappedExperience } from 'src/interfaces/experience';
+import {
+  ExperienceProps,
+  UserExperience,
+  WrappedExperience,
+} from 'src/interfaces/experience';
 import { Post, PostVisibility } from 'src/interfaces/post';
 import { TimelineType } from 'src/interfaces/timeline';
 import { User } from 'src/interfaces/user';
+import * as ExperienceAPI from 'src/lib/api/experience';
 import i18n from 'src/locale';
 import { RootState } from 'src/reducers';
 import { createExclusiveContent } from 'src/reducers/timeline/actions';
@@ -93,6 +97,8 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
     [],
   );
   const [commonUser, setCommonUser] = useState<string[]>([]);
+  const [userExperiences, setUserExperiences] = useState<UserExperience[]>([]);
+  const [page, setPage] = useState<number>(1);
 
   const Editor = isMobile ? CKEditor : PlateEditor;
 
@@ -332,7 +338,7 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
     state => state.userState.anonymous,
     shallowEqual,
   );
-  const { list: experiences } = useExperienceList(ExperienceOwner.CURRENT_USER);
+  const { list: experiences } = useExperienceList(ExperienceOwner.PERSONAL);
   const { searchUsers, users } = useSearchHook();
   const { uploadImage } = useUpload();
   const onImageUpload = async (files: File[]) => {
@@ -359,6 +365,28 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
     handleCloseExperience();
   };
 
+  const fetchUserExperiences = async () => {
+    const { meta, data: experiences } = await ExperienceAPI.getUserExperiences(
+      user.id,
+      'personal',
+      page,
+    );
+
+    setUserExperiences([...userExperiences, ...experiences]);
+
+    if (meta.currentPage < meta.totalPageCount) setPage(page + 1);
+  };
+
+  const resetExperiences = () => {
+    setPage(1);
+    setUserExperiences([]);
+  };
+
+  useEffect(() => {
+    if (open) fetchUserExperiences();
+    else resetExperiences();
+  }, [open, page]);
+
   const handleRemoveExperience = (experienceId: string) => {
     removeExperience(experienceId, () => {
       loadExperience();
@@ -531,16 +559,13 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
           onChange={handleVisibilityChange}
         />
       </div>
-      <div className={styles.timelineVisibility}>
-        <SearchBox placeholder="Search Timeline" />
-      </div>
       <div className={styles.warningVisibility}>
         <InfoIconYellow />
         <Typography
           component="span"
           variant="body1"
           style={{
-            fontWeight: 700,
+            fontWeight: 500,
             marginLeft: '10px',
           }}>
           Your post visibility will be visible to{' '}
@@ -574,7 +599,7 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
       </div>
       <ShowIf condition={showTimelineCreate}>
         <div className={styles.experienceCreate}>
-          <ExperiencePost
+          <ExperienceTimelinePost
             isEdit={false}
             experience={selectedExperience}
             tags={tags}
@@ -591,11 +616,11 @@ export const PostCreate: React.FC<PostCreateProps> = props => {
       </ShowIf>
       {/* Select Timeline */}
       {/* Timeline list */}
-      <div className={styles.timelineVisibility}>
+      <div>
         <ExperienceListBarCreatePost
           onDelete={handleRemoveExperience}
           onUnsubscribe={handleUnsubscribeExperience}
-          experiences={experiences}
+          experiences={userExperiences}
           selectable={true}
           viewPostList={handleViewPostList}
           user={user}
diff --git a/src/components/ProfileHeader/index.tsx b/src/components/ProfileHeader/index.tsx
index ea80e3416..8b5d2b759 100644
--- a/src/components/ProfileHeader/index.tsx
+++ b/src/components/ProfileHeader/index.tsx
@@ -239,7 +239,7 @@ export const ProfileHeaderComponent: React.FC<Props> = props => {
                 variant="body1"
                 component="p"
                 className={style.username}>
-                @{person.username || 'username'}
+                @{person.username || 'username'} halo
               </Typography>
             </div>
           </Grid>
diff --git a/src/hooks/use-experience-hook.ts b/src/hooks/use-experience-hook.ts
index dd9f09914..5e62c0163 100644
--- a/src/hooks/use-experience-hook.ts
+++ b/src/hooks/use-experience-hook.ts
@@ -44,6 +44,7 @@ export enum ExperienceOwner {
   PROFILE = 'profile',
   TRENDING = 'trending',
   DISCOVER = 'DISCOVER',
+  PERSONAL = 'personal',
 }
 
 //TODO: isn't it better to rename this to something more general like, useSearchHook?
@@ -74,6 +75,8 @@ export const useExperienceHook = () => {
     { data: WrappedExperience[]; meta: ListMeta }
   >(state => state.userState.experiences, shallowEqual);
 
+  console.log(experiences, 'dataaa');
+
   const loadExperience = () => {
     dispatch(loadExperiences());
   };