diff --git a/src/components/common/SkeletonCommon/SkeletonCommon.module.scss b/src/components/common/SkeletonCommon/SkeletonCommon.module.scss
deleted file mode 100644
index e388525e5..000000000
--- a/src/components/common/SkeletonCommon/SkeletonCommon.module.scss
+++ /dev/null
@@ -1,32 +0,0 @@
-@import '../../../styles/utilities';
-
-$base-color: #ddd;
-$shine-color: #e8e8e8;
-$animation-duration: 1.6s;
-
-@mixin background-gradient {
- background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
- background-size: 600px;
-}
-
-.skeletonCommon:empty {
- margin: auto;
- height: 14rem;
- width: 14rem;
- animation: name duration timing-function delay iteration-count direction fill-mode;
-
- @include background-gradient;
- animation: shine-lines $animation-duration infinite linear;
-}
-
-@keyframes shine-lines {
- 0% {
- background-position: -100px;
- }
- 40% {
- background-position: 140px;
- }
- 100% {
- background-position: 140px;
- }
-}
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/SkeletonCommon.tsx b/src/components/common/SkeletonCommon/SkeletonCommon.tsx
deleted file mode 100644
index 6b0631aef..000000000
--- a/src/components/common/SkeletonCommon/SkeletonCommon.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from "react";
-import s from './SkeletonCommon.module.scss'
-
-interface SkeletonCommonProps {
- children? : React.ReactNode;
-}
-
-const SkeletonCommon = ({ children }: SkeletonCommonProps) => {
-
- return (
-
- {children}
-
- )
-}
-
-export default SkeletonCommon
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss
new file mode 100644
index 000000000..57fdf3ebc
--- /dev/null
+++ b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.module.scss
@@ -0,0 +1,53 @@
+@import '../../../../styles/utilities';
+
+.skeletonImage:empty {
+ @apply relative;
+ background: #DDDBDD;
+
+ &.small {
+ width: 10rem;
+ height: 10rem;
+ }
+
+ &.default {
+ width: 15rem;
+ height: 15rem;
+ }
+
+ &.large {
+ width: 20rem;
+ height: 20rem;
+ }
+
+ &.left {
+ margin-left: 0;
+ }
+
+ &.center {
+ margin: auto;
+ }
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ transform: translateX(-100%);
+ background-image: linear-gradient(
+ 90deg,
+ rgba(#fff, 0) 0,
+ rgba(#fff, 0.2) 20%,
+ rgba(#fff, 0.5) 60%,
+ rgba(#fff, 0)
+ );
+ animation: shimmer 2s infinite;
+ content: '';
+ }
+}
+
+@keyframes shimmer {
+ 100% {
+ transform: translateX(100%);
+ }
+}
diff --git a/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx
new file mode 100644
index 000000000..7ab20b037
--- /dev/null
+++ b/src/components/common/SkeletonCommon/SkeletonImage/SkeletonImage.tsx
@@ -0,0 +1,22 @@
+import classNames from "classnames";
+import React from "react";
+import s from './SkeletonImage.module.scss'
+
+interface SkeletonImageProps {
+ align?: "left" | "center"
+ size?: "small" | "default" | "large"
+ children?: React.ReactNode
+}
+
+const SkeletonImage = ({ align="center", size="default", children }: SkeletonImageProps) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export default SkeletonImage
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss
new file mode 100644
index 000000000..2c98d00e5
--- /dev/null
+++ b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.module.scss
@@ -0,0 +1,63 @@
+@import '../../../../styles/utilities';
+
+.skeletonParagraph {
+ .row {
+ display: inline-block;
+ height: 2rem;
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+ background-color: #DDDBDD;
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ transform: translateX(-100%);
+ background-image: linear-gradient(
+ 90deg,
+ rgba(#fff, 0) 0,
+ rgba(#fff, 0.2) 20%,
+ rgba(#fff, 0.5) 60%,
+ rgba(#fff, 0)
+ );
+ animation: shimmer 2s infinite;
+ content: '';
+ }
+ }
+
+ .lastRow {
+ display: inline-block;
+ height: 2rem;
+ width: 80%;
+ position: relative;
+ overflow: hidden;
+ background-color: #DDDBDD;
+
+ &::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ transform: translateX(-100%);
+ background-image: linear-gradient(
+ 90deg,
+ rgba(#fff, 0) 0,
+ rgba(#fff, 0.2) 20%,
+ rgba(#fff, 0.5) 60%,
+ rgba(#fff, 0)
+ );
+ animation: shimmer 2s infinite;
+ content: '';
+ }
+ }
+}
+
+@keyframes shimmer {
+ 100% {
+ transform: translateX(100%);
+ }
+}
diff --git a/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx
new file mode 100644
index 000000000..4baa35a52
--- /dev/null
+++ b/src/components/common/SkeletonCommon/SkeletonParagraph/SkeletonParagraph.tsx
@@ -0,0 +1,31 @@
+import React, { useEffect, useState } from "react";
+import s from './SkeletonParagraph.module.scss'
+
+interface SkeletonParagraphProps {
+ rows?: number // number of rows in paragraph
+ children?: React.ReactNode
+}
+
+const SkeletonParagraph = ({ rows=2, children }: SkeletonParagraphProps) => {
+
+ const [isChildLoaded, setIsChildLoaded] = useState(false)
+
+ useEffect(() => {
+ setIsChildLoaded(true);
+ }, [])
+
+ return (
+
+ {
+ isChildLoaded ? children : [...Array(rows)].map((e, i) => {
+ if (i === rows-1) {
+ return
+ }
+ return
+ })
+ }
+
+ )
+}
+
+export default SkeletonParagraph
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss b/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss
deleted file mode 100644
index 82286d7a0..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.module.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-@import '../../../../../styles/utilities';
-
-$base-color: #8F8F8F;
-$shine-color: #ebebeb;
-$animation-duration: 1.6s;
-$avatar-offset: 52 + 16;
-
-@mixin background-gradient {
- background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
- background-size: 600px;
-}
-
-.skeletonAvatar {
-
- &.active {
- @include background-gradient;
- animation: shine-avatar $animation-duration infinite linear;
- }
-
- &.circle {
- border-radius: 50%;
- }
-
- &.square {
- border-radius: 0;
- }
-
- &.small {
- width: 3.2rem;
- height: 3.2rem;
- }
- &.default {
- width: 4.8rem;
- height: 4.8rem;
- }
- &.large {
- width: 6.4rem;
- height: 6.4rem;
- }
-}
-
-@keyframes shine-avatar {
- 0% {
- background-position: -100px + $avatar-offset
- }
-
- 40%, 100% {
- background-position: 140px + $avatar-offset
- }
-
-}
diff --git a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx b/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx
deleted file mode 100644
index d5d20165b..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonAvatar/SkeletonAvatar.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import classNames from "classnames";
-import React from "react";
-import s from './SkeletonAvatar.module.scss'
-
-interface SkeletonAvatarProps {
- active?: boolean,
- shape?: "circle" | "square",
- size?: "small" | "default" | "large",
- children: React.ReactNode
-}
-
-const SkeletonAvatar = ({ active=true, shape="circle", size="default", children }: SkeletonAvatarProps) => {
-
- return (
-
- {children}
-
- )
-}
-
-export default SkeletonAvatar
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss b/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss
deleted file mode 100644
index 259c1574c..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.module.scss
+++ /dev/null
@@ -1,41 +0,0 @@
-@import '../../../../../styles/utilities';
-
-$base-color: #DDD;
-$shine-color: #ebebeb;
-$animation-duration: 2s;
-
-@mixin background-gradient {
- background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
- background-size: 100%;
-}
-
-.skeletonParagraph {
- @apply bg-white;
- height: fit-content;
- width: 100%;
-
- .row {
- height: 2rem;
- margin: 1rem;
- animation: shine-lines $animation-duration infinite linear;
- @include background-gradient;
- }
-
- .lastRow {
- height: 2rem;
- margin: 1rem;
- width: 85%;
- animation: shine-lines $animation-duration infinite linear;
- @include background-gradient;
- }
-}
-
-@keyframes shine-lines {
- 0% {
- background-position: -100px;
- }
- 40%, 100% {
- background-position: 100%;
- }
-}
-
diff --git a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx b/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx
deleted file mode 100644
index 5c3620f0a..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonParagraph/SkeletonParagraph.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import classNames from "classnames";
-import React from "react";
-import s from './SkeletonParagraph.module.scss'
-
-interface SkeletonParagraphProps {
- active?: boolean,
- rows?: number // number of rows in paragraph
- children: React.ReactNode
-}
-
-const SkeletonParagraph = ({ active=true, rows=2, children }: SkeletonParagraphProps) => {
-
- return (
-
- {
- [...Array(rows)].map((e, i) => {
- if (i === rows-1) {
- return
- }
- return
- })
- }
- {children}
-
- )
-}
-
-export default SkeletonParagraph
\ No newline at end of file
diff --git a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss b/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss
deleted file mode 100644
index 0dbb139d3..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.module.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-@import '../../../../../styles/utilities';
-
-$base-color: #8F8F8F;
-$shine-color: #ebebeb;
-$animation-duration: 1.6s;
-
-@mixin background-gradient {
- background-image: linear-gradient(90deg, $base-color 0px, $shine-color 40px, $base-color 80px) ;
- background-size: 600px;
-}
-
-.skeletonTitle {
- &.active {
- @include background-gradient;
- animation: shine-lines $animation-duration infinite linear;
- }
-}
-
-@keyframes shine-lines {
- 0% {
- background-position: -100px;
- }
- 40%, 100% {
- background-position: 50rem;
- }
-}
-
diff --git a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx b/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx
deleted file mode 100644
index 40d747d8f..000000000
--- a/src/components/common/SkeletonCommon/components/SkeletonTitle/SkeletonTitle.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import classNames from "classnames";
-import React from "react";
-import s from './SkeletonTitle.module.scss'
-
-interface SkeletonTitleProps {
- active?: boolean,
- width: string | number, // number px
- height: string | number,
- children: React.ReactNode
-}
-
-const SkeletonTitle = ({ active=true, width, height, children }: SkeletonTitleProps) => {
-
- const styles = {
- width: width,
- height: height
- }
-
- return (
-
- {children}
-
- )
-}
-
-export default SkeletonTitle
\ No newline at end of file