File size: 3,980 Bytes
5240c42
 
848e268
3ebc73d
6233641
 
5033071
 
 
 
5240c42
 
6233641
 
5240c42
 
e270a74
5240c42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5033071
 
6233641
5240c42
5033071
 
 
5240c42
 
6233641
5240c42
 
 
 
 
 
d43c4c0
5240c42
 
 
 
 
 
ecc9778
5240c42
 
 
 
 
6233641
 
 
 
 
 
 
 
 
 
 
 
 
 
848e268
0b1e7da
848e268
 
 
 
2d49c67
 
 
5240c42
0b1e7da
5240c42
 
 
 
5033071
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5240c42
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { useMemo } from "react";
import { motion } from "framer-motion";
import Image from "next/image";
import { useKeyPressEvent } from "react-use";
import { BsFillTrashFill } from "react-icons/bs";
import { AiFillCheckCircle } from "react-icons/ai";
import {
  BsFillArrowLeftSquareFill,
  BsFillArrowRightSquareFill,
} from "react-icons/bs";

import { useCollection } from "./useCollection";
import { Button } from "../button";
import { useUser } from "@/utils/useUser";

interface Props {
  id: string;
  onClose: () => void;
}

const dropIn = {
  hidden: {
    opacity: 0,
  },
  visible: {
    y: "0",
    opacity: 1,
    transition: {
      duration: 0.1,
      type: "spring",
      damping: 25,
      stiffness: 500,
    },
  },
  exit: {
    opacity: 0,
  },
};

export const Modal: React.FC<Props> = ({ id, onClose }) => {
  const { collection, updateVisibility, remove, next, previous } =
    useCollection(id);
  const { user } = useUser();

  useKeyPressEvent("ArrowLeft", previous);
  useKeyPressEvent("ArrowRight", next);

  const formatDate = useMemo(() => {
    if (!collection) return;
    const date = new Date(collection?.createdAt);
    return date.toLocaleDateString();
  }, [collection?.createdAt]);

  return (
    <motion.div
      onClick={onClose}
      className="fixed top-0 w-screen h-screen left-0 bg-black/30 backdrop-blur-sm z-50 flex items-center justify-center p-6"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
    >
      <motion.div
        onClick={(e) => e.stopPropagation()}
        className="max-w-2xl h-auto w-full z-[10] rounded-3xl overflow-hidden relative flex items-center justify-center flex-col gap-4 bg-white/30 backdrop-blur-sm px-2 pb-2 pt-2"
        variants={dropIn}
        initial="hidden"
        animate="visible"
        exit="exit"
      >
        {user?.is_admin && (
          <div className="absolute p-2 rounded-full top-4 left-4 flex items-center justify-start gap-2 bg-black/20 backdrop-blur">
            {!collection?.is_visible && (
              <Button theme="white" onClick={updateVisibility}>
                <AiFillCheckCircle />
                Validate
              </Button>
            )}
            <Button theme="danger" onClick={remove}>
              <BsFillTrashFill />
              Delete
            </Button>
          </div>
        )}
        <Image
          src={`https://huggingface.co/datasets/enzostvs/stable-diffusion-tpu-generations/resolve/main/images/${collection?.file_name}.png?expose=true`}
          alt="Generated image"
          className="object-center object-contain w-full h-full rounded-2xl"
          width={1024}
          height={1024}
        />
        <div
          className="bg-cover bg-center w-full h-full rounded-2xl bg-no-repeat z-[-1] absolute top-0 left-0 opacity-90 blur-xl"
          style={{
            backgroundImage: `url(https://huggingface.co/datasets/enzostvs/stable-diffusion-tpu-generations/resolve/main/images/${collection?.file_name}.png?expose=true)`,
          }}
        />
        <div className="text-left w-full px-4 pb-3 pt-2">
          <p className="text-sm font-medium text-white/60 mb-1">{formatDate}</p>
          <div className="flex flex-col lg:flex-row items-start lg:items-end lg:justify-between">
            <p className="text-xl font-semibold text-white lowercase leading-snug">
              {collection?.prompt}
            </p>
            <div className="flex items-center justify-end gap-2">
              <BsFillArrowLeftSquareFill
                className="text-white/60 text-2xl inline-block mr-2 hover:text-white cursor-pointer"
                onClick={previous}
              />
              <BsFillArrowRightSquareFill
                className="text-white/60 text-2xl inline-block hover:text-white cursor-pointer"
                onClick={next}
              />
            </div>
          </div>
        </div>
      </motion.div>
    </motion.div>
  );
};