diff --git a/src/components/node/NodeImageSlideBlock/index.tsx b/src/components/node/NodeImageSlideBlock/index.tsx
index f3b4705a..a971b181 100644
--- a/src/components/node/NodeImageSlideBlock/index.tsx
+++ b/src/components/node/NodeImageSlideBlock/index.tsx
@@ -47,7 +47,7 @@ const NodeImageSlideBlock: FC<IProps> = ({ node, is_loading, updateLayout }) =>
   const images = useMemo(
     () =>
       (node && node.files && node.files.filter(({ type }) => type === UPLOAD_TYPES.IMAGE)) || [],
-    [node]
+    [node.files]
   );
 
   useEffect(() => {
diff --git a/src/components/node/NodePanel/index.tsx b/src/components/node/NodePanel/index.tsx
index 9a828841..22cf50e5 100644
--- a/src/components/node/NodePanel/index.tsx
+++ b/src/components/node/NodePanel/index.tsx
@@ -3,7 +3,6 @@ import * as styles from './styles.scss';
 import { INode } from '~/redux/types';
 import { createPortal } from 'react-dom';
 import { NodePanelInner } from '~/components/node/NodePanelInner';
-import pick from 'ramda/es/pick';
 
 interface IProps {
   node: Partial<INode>;
@@ -18,10 +17,11 @@ interface IProps {
   onEdit: () => void;
   onLike: () => void;
   onStar: () => void;
+  onLock: () => void;
 }
 
 const NodePanel: FC<IProps> = memo(
-  ({ node, layout, can_edit, can_like, can_star, is_loading, onEdit, onLike, onStar }) => {
+  ({ node, layout, can_edit, can_like, can_star, is_loading, onEdit, onLike, onStar, onLock }) => {
     const [stack, setStack] = useState(false);
 
     const ref = useRef(null);
@@ -51,14 +51,15 @@ const NodePanel: FC<IProps> = memo(
           createPortal(
             <NodePanelInner
               node={node}
-              stack
-              onEdit={onEdit}
-              onLike={onLike}
-              onStar={onStar}
               can_edit={can_edit}
               can_like={can_like}
               can_star={can_star}
+              onEdit={onEdit}
+              onLike={onLike}
+              onStar={onStar}
+              onLock={onLock}
               is_loading={is_loading}
+              stack
             />,
             document.body
           )
@@ -68,6 +69,7 @@ const NodePanel: FC<IProps> = memo(
             onEdit={onEdit}
             onLike={onLike}
             onStar={onStar}
+            onLock={onLock}
             can_edit={can_edit}
             can_like={can_like}
             can_star={can_star}
diff --git a/src/components/node/NodePanelInner/index.tsx b/src/components/node/NodePanelInner/index.tsx
index 8d112757..1ae279ce 100644
--- a/src/components/node/NodePanelInner/index.tsx
+++ b/src/components/node/NodePanelInner/index.tsx
@@ -1,11 +1,11 @@
-import React, { FC } from "react";
-import * as styles from "./styles.scss";
-import { Group } from "~/components/containers/Group";
-import { Filler } from "~/components/containers/Filler";
-import { Icon } from "~/components/input/Icon";
-import { INode } from "~/redux/types";
-import classNames from "classnames";
-import { Placeholder } from "~/components/placeholders/Placeholder";
+import React, { FC } from 'react';
+import * as styles from './styles.scss';
+import { Group } from '~/components/containers/Group';
+import { Filler } from '~/components/containers/Filler';
+import { Icon } from '~/components/input/Icon';
+import { INode } from '~/redux/types';
+import classNames from 'classnames';
+import { Placeholder } from '~/components/placeholders/Placeholder';
 
 interface IProps {
   node: Partial<INode>;
@@ -20,10 +20,11 @@ interface IProps {
   onEdit: () => void;
   onLike: () => void;
   onStar: () => void;
+  onLock: () => void;
 }
 
 const NodePanelInner: FC<IProps> = ({
-  node: { title, user, is_liked, is_heroic },
+  node: { title, user, is_liked, is_heroic, deleted_at },
   stack,
 
   can_star,
@@ -34,7 +35,8 @@ const NodePanelInner: FC<IProps> = ({
 
   onStar,
   onEdit,
-  onLike
+  onLike,
+  onLock,
 }) => {
   return (
     <div className={classNames(styles.wrap, { stack })}>
@@ -42,15 +44,11 @@ const NodePanelInner: FC<IProps> = ({
         <Group horizontal className={styles.panel}>
           <Filler>
             <div className={styles.title}>
-              {is_loading ? <Placeholder width="40%" /> : title || "..."}
+              {is_loading ? <Placeholder width="40%" /> : title || '...'}
             </div>
             {user && user.username && (
               <div className={styles.name}>
-                {is_loading ? (
-                  <Placeholder width="100px" />
-                ) : (
-                  `~${user.username}`
-                )}
+                {is_loading ? <Placeholder width="100px" /> : `~${user.username}`}
               </div>
             )}
           </Filler>
@@ -66,11 +64,19 @@ const NodePanelInner: FC<IProps> = ({
               )}
             </div>
           )}
+
           {can_edit && (
-            <div>
-              <Icon icon="edit" size={24} onClick={onEdit} />
-            </div>
+            <>
+              <div>
+                <Icon icon={deleted_at ? 'locked' : 'unlocked'} size={24} onClick={onLock} />
+              </div>
+
+              <div>
+                <Icon icon="edit" size={24} onClick={onEdit} />
+              </div>
+            </>
           )}
+
           {can_like && (
             <div className={classNames(styles.like, { is_liked })}>
               {is_liked ? (
@@ -87,5 +93,3 @@ const NodePanelInner: FC<IProps> = ({
 };
 
 export { NodePanelInner };
-
-// <div className={styles.mark} />
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 2fdc7c95..b0691569 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -25,6 +25,7 @@ export const API = {
     UPDATE_TAGS: (id: INode['id']) => `/node/${id}/tags`,
     POST_LIKE: (id: INode['id']) => `/node/${id}/like`,
     POST_STAR: (id: INode['id']) => `/node/${id}/heroic`,
+    POST_LOCK: (id: INode['id']) => `/node/${id}/lock`,
     SET_CELL_VIEW: (id: INode['id']) => `/node/${id}/cell-view`,
   },
 };
diff --git a/src/containers/node/NodeLayout/index.tsx b/src/containers/node/NodeLayout/index.tsx
index ca16655e..2d000fcc 100644
--- a/src/containers/node/NodeLayout/index.tsx
+++ b/src/containers/node/NodeLayout/index.tsx
@@ -32,6 +32,7 @@ const mapDispatchToProps = {
   nodeEdit: NODE_ACTIONS.nodeEdit,
   nodeLike: NODE_ACTIONS.nodeLike,
   nodeStar: NODE_ACTIONS.nodeStar,
+  nodeLock: NODE_ACTIONS.nodeLock,
 };
 
 type IProps = ReturnType<typeof mapStateToProps> &
@@ -51,6 +52,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
     nodeEdit,
     nodeLike,
     nodeStar,
+    nodeLock,
     nodeSetCoverImage,
   }) => {
     // const is_loading = true;
@@ -81,6 +83,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
     const onEdit = useCallback(() => nodeEdit(node.id), [nodeEdit, node]);
     const onLike = useCallback(() => nodeLike(node.id), [nodeLike, node]);
     const onStar = useCallback(() => nodeStar(node.id), [nodeStar, node]);
+    const onLock = useCallback(() => nodeLock(node.id, !node.deleted_at), [nodeStar, node]);
 
     useEffect(() => {
       if (!node.cover) return;
@@ -93,7 +96,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
         {block && createElement(block, { node, is_loading, updateLayout, layout })}
 
         <NodePanel
-          node={pick(['title', 'user', 'is_liked', 'is_heroic'], node)}
+          node={pick(['title', 'user', 'is_liked', 'is_heroic', 'deleted_at'], node)}
           layout={layout}
           can_edit={can_edit}
           can_like={can_like}
@@ -101,6 +104,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
           onEdit={onEdit}
           onLike={onLike}
           onStar={onStar}
+          onLock={onLock}
           is_loading={is_loading}
         />
 
diff --git a/src/index.tsx b/src/index.tsx
index 35799244..68237153 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -19,7 +19,6 @@ render(
 );
 
 /*
-
   [Stage 0]:
   - set file target on comment save, node save, profile upload
   - check if email is registered at social login
@@ -28,10 +27,10 @@ render(
   - delete nodes
   
   - illustrate 404
-  - illustrate restoreRequestDialog
-  - illustrate login  
   
   [stage 1]
+  - illustrate login  
+  - illustrate restoreRequestDialog
   - friendship
   - signup?
   - import videos
diff --git a/src/redux/node/actions.ts b/src/redux/node/actions.ts
index 4262b48a..1cff016f 100644
--- a/src/redux/node/actions.ts
+++ b/src/redux/node/actions.ts
@@ -96,6 +96,12 @@ export const nodeStar = (id: INode['id']) => ({
   id,
 });
 
+export const nodeLock = (id: INode['id'], is_locked: boolean) => ({
+  type: NODE_ACTIONS.LOCK,
+  id,
+  is_locked,
+});
+
 export const nodeSetEditor = (editor: INode) => ({
   type: NODE_ACTIONS.SET_EDITOR,
   editor,
diff --git a/src/redux/node/api.ts b/src/redux/node/api.ts
index 5a79b79b..5a0f21e7 100644
--- a/src/redux/node/api.ts
+++ b/src/redux/node/api.ts
@@ -1,17 +1,12 @@
-import {
-  api,
-  configWithToken,
-  resultMiddleware,
-  errorMiddleware
-} from "~/utils/api";
-import { INode, IResultWithStatus, IComment } from "../types";
-import { API } from "~/constants/api";
-import { nodeUpdateTags, nodeLike, nodeStar } from "./actions";
-import { INodeState } from "./reducer";
+import { api, configWithToken, resultMiddleware, errorMiddleware } from '~/utils/api';
+import { INode, IResultWithStatus, IComment } from '../types';
+import { API } from '~/constants/api';
+import { nodeUpdateTags, nodeLike, nodeStar, nodeLock } from './actions';
+import { INodeState } from './reducer';
 
 export const postNode = ({
   access,
-  node
+  node,
 }: {
   access: string;
   node: INode;
@@ -24,7 +19,7 @@ export const postNode = ({
 
 export const getNodes = ({
   from = null,
-  access
+  access,
 }: {
   from?: string;
   access: string;
@@ -42,7 +37,7 @@ export const getNodeDiff = ({
   with_updated,
   with_recent,
   with_valid,
-  access
+  access,
 }: {
   start?: string;
   end?: string;
@@ -64,8 +59,8 @@ export const getNodeDiff = ({
           with_heroes,
           with_updated,
           with_recent,
-          with_valid
-        }
+          with_valid,
+        },
       })
     )
     .then(resultMiddleware)
@@ -73,7 +68,7 @@ export const getNodeDiff = ({
 
 export const getNode = ({
   id,
-  access
+  access,
 }: {
   id: string | number;
   access: string;
@@ -86,7 +81,7 @@ export const getNode = ({
 export const postNodeComment = ({
   id,
   data,
-  access
+  access,
 }: {
   access: string;
   id: number;
@@ -100,11 +95,11 @@ export const postNodeComment = ({
 export const getNodeComments = ({
   id,
   access,
-  order = "ASC"
+  order = 'ASC',
 }: {
   id: number;
   access: string;
-  order: "ASC" | "DESC";
+  order: 'ASC' | 'DESC';
 }): Promise<IResultWithStatus<{ comments: Comment[] }>> =>
   api
     .get(API.NODE.COMMENT(id), configWithToken(access, { params: { order } }))
@@ -113,11 +108,11 @@ export const getNodeComments = ({
 
 export const getNodeRelated = ({
   id,
-  access
+  access,
 }: {
   id: number;
   access: string;
-}): Promise<IResultWithStatus<{ related: INodeState["related"] }>> =>
+}): Promise<IResultWithStatus<{ related: INodeState['related'] }>> =>
   api
     .get(API.NODE.RELATED(id), configWithToken(access))
     .then(resultMiddleware)
@@ -126,7 +121,7 @@ export const getNodeRelated = ({
 export const updateNodeTags = ({
   id,
   tags,
-  access
+  access,
 }: ReturnType<typeof nodeUpdateTags> & { access: string }): Promise<
   IResultWithStatus<{ node: INode }>
 > =>
@@ -137,9 +132,9 @@ export const updateNodeTags = ({
 
 export const postNodeLike = ({
   id,
-  access
+  access,
 }: ReturnType<typeof nodeLike> & { access: string }): Promise<
-  IResultWithStatus<{ is_liked: INode["is_liked"] }>
+  IResultWithStatus<{ is_liked: INode['is_liked'] }>
 > =>
   api
     .post(API.NODE.POST_LIKE(id), {}, configWithToken(access))
@@ -148,11 +143,23 @@ export const postNodeLike = ({
 
 export const postNodeStar = ({
   id,
-  access
+  access,
 }: ReturnType<typeof nodeStar> & { access: string }): Promise<
-  IResultWithStatus<{ is_liked: INode["is_liked"] }>
+  IResultWithStatus<{ is_liked: INode['is_liked'] }>
 > =>
   api
     .post(API.NODE.POST_STAR(id), {}, configWithToken(access))
     .then(resultMiddleware)
     .catch(errorMiddleware);
+
+export const postNodeLock = ({
+  id,
+  is_locked,
+  access,
+}: ReturnType<typeof nodeLock> & { access: string }): Promise<
+  IResultWithStatus<{ deleted_at: INode['deleted_at'] }>
+> =>
+  api
+    .post(API.NODE.POST_LOCK(id), { is_locked }, configWithToken(access))
+    .then(resultMiddleware)
+    .catch(errorMiddleware);
diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts
index db8e5afc..6e858db0 100644
--- a/src/redux/node/constants.ts
+++ b/src/redux/node/constants.ts
@@ -23,6 +23,7 @@ export const NODE_ACTIONS = {
   EDIT: `${prefix}EDIT`,
   LIKE: `${prefix}LIKE`,
   STAR: `${prefix}STAR`,
+  LOCK: `${prefix}LOCK`,
   CREATE: `${prefix}CREATE`,
 
   SET_SAVE_ERRORS: `${prefix}SET_SAVE_ERRORS`,
diff --git a/src/redux/node/sagas.ts b/src/redux/node/sagas.ts
index bd6e3a61..1cfc8fdf 100644
--- a/src/redux/node/sagas.ts
+++ b/src/redux/node/sagas.ts
@@ -21,6 +21,7 @@ import {
   nodeLike,
   nodeSetRelated,
   nodeGotoNode,
+  nodeLock,
 } from './actions';
 import {
   postNode,
@@ -31,6 +32,7 @@ import {
   postNodeLike,
   postNodeStar,
   getNodeRelated,
+  postNodeLock,
 } from './api';
 import { reqWrapper } from '../auth/sagas';
 import { flowSetNodes, flowSetUpdated } from '../flow/actions';
@@ -234,6 +236,23 @@ function* onStarSaga({ id }: ReturnType<typeof nodeLike>) {
   yield call(updateNodeEverywhere, { ...current, is_heroic });
 }
 
+function* onLockSaga({ id, is_locked }: ReturnType<typeof nodeLock>) {
+  const {
+    current,
+    current: { deleted_at },
+  } = yield select(selectNode);
+
+  yield call(updateNodeEverywhere, {
+    ...current,
+    deleted_at: is_locked ? new Date().toISOString() : null,
+  });
+
+  const { data, error } = yield call(reqWrapper, postNodeLock, { id, is_locked });
+
+  if (error || !data.deleted_at)
+    return yield call(updateNodeEverywhere, { ...current, deleted_at }); // ok and matches
+}
+
 export default function* nodeSaga() {
   yield takeLatest(NODE_ACTIONS.SAVE, onNodeSave);
   yield takeLatest(NODE_ACTIONS.GOTO_NODE, onNodeGoto);
@@ -244,4 +263,5 @@ export default function* nodeSaga() {
   yield takeLatest(NODE_ACTIONS.EDIT, onEditSaga);
   yield takeLatest(NODE_ACTIONS.LIKE, onLikeSaga);
   yield takeLatest(NODE_ACTIONS.STAR, onStarSaga);
+  yield takeLatest(NODE_ACTIONS.LOCK, onLockSaga);
 }
diff --git a/src/redux/types.ts b/src/redux/types.ts
index 4e21edc9..894a12f2 100644
--- a/src/redux/types.ts
+++ b/src/redux/types.ts
@@ -132,6 +132,7 @@ export interface INode {
 
   created_at?: string;
   updated_at?: string;
+  deleted_at?: string;
   commented_at?: string;
 }
 
diff --git a/src/sprites/Sprites.tsx b/src/sprites/Sprites.tsx
index 97fe173b..3ebcd592 100644
--- a/src/sprites/Sprites.tsx
+++ b/src/sprites/Sprites.tsx
@@ -192,6 +192,16 @@ const Sprites: FC<{}> = () => (
       <path d="M3 4V1h2v3h3v2H5v3H3V6H0V4h3zm3 6V7h3V4h7l1.83 2H21c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V10h3zm7 9c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-3.2-5c0 1.77 1.43 3.2 3.2 3.2s3.2-1.43 3.2-3.2-1.43-3.2-3.2-3.2-3.2 1.43-3.2 3.2z" />
     </g>
 
+    <g id="locked" stroke="none">
+      <path fill="none" d="M0 0h24v24H0V0z" />
+      <path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" />
+    </g>
+
+    <g id="unlocked" stroke="none">
+      <path fill="none" d="M0 0h24v24H0V0z" />
+      <path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z" />
+    </g>
+
     <g id="youtube" stroke="none">
       <path fill="none" d="M0 0h24v24H0V0z" />
       <g transform="scale(0.1) translate(-30 -30)">