mirror of
https://github.com/Steffo99/festa.git
synced 2024-12-22 22:54:22 +00:00
Do more prototyping!
This commit is contained in:
parent
91359e7299
commit
e1409f3545
21 changed files with 264 additions and 103 deletions
28
components/InputEventSlug.tsx
Normal file
28
components/InputEventSlug.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
export interface InputSlug extends React.HTMLProps<HTMLInputElement> {
|
||||||
|
onSlugChange?: (val: string) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function InputSlug(props: InputSlug) {
|
||||||
|
const [text, setText] = React.useState("")
|
||||||
|
|
||||||
|
const handleChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
props.onChange?.(event)
|
||||||
|
|
||||||
|
let slug = event.target.value.toLowerCase().replaceAll(/[^a-z0-9]/g, "-")
|
||||||
|
props.onSlugChange?.(slug)
|
||||||
|
setText(slug)
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={text}
|
||||||
|
onChange={handleChange}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,31 +1,50 @@
|
||||||
import { Trans, useTranslation } from "next-i18next"
|
import { Trans, useTranslation } from "next-i18next"
|
||||||
import { LoginContext } from "../contexts/login"
|
import { LoginContext } from "../contexts/login"
|
||||||
import { useDefinedContext } from "../hooks/useDefinedContext"
|
import { useDefinedContext } from "../utils/definedContext"
|
||||||
|
import { InputSlug } from "./InputEventSlug"
|
||||||
import { LoginButton } from "./LoginButton"
|
import { LoginButton } from "./LoginButton"
|
||||||
import { TelegramUserLink } from "./TelegramUserLink"
|
import { LogoutLink } from "./LogoutLink"
|
||||||
|
import { TelegramUser } from "./TelegramUser"
|
||||||
|
|
||||||
|
|
||||||
export function Intro() {
|
export function Intro() {
|
||||||
const {t} = useTranslation("common")
|
const {t} = useTranslation("common")
|
||||||
const [login, setLogin] = useDefinedContext(LoginContext)
|
const [login, _] = useDefinedContext(LoginContext)
|
||||||
|
|
||||||
const loginMessage = login ? (
|
const loginMessage = login ? <>
|
||||||
<Trans i18nKey="introTelegramLoggedIn">
|
<Trans i18nKey="introTelegramLoggedIn">
|
||||||
Sei connesso come <TelegramUserLink u={login}/>!
|
introTelegramLoggedIn(1: <TelegramUser u={login}/>)
|
||||||
</Trans>
|
</Trans>
|
||||||
) : (
|
<br/>
|
||||||
<Trans i18nKey="introTelegramLogin">
|
<LogoutLink/>
|
||||||
Effettua il login con Telegram per iniziare a creare il tuo evento.
|
</> : <>
|
||||||
</Trans>
|
{t("introTelegramLogin")}
|
||||||
)
|
</>
|
||||||
|
|
||||||
|
const input = login ? <>
|
||||||
|
<p>
|
||||||
|
{t("introCreateEvent")}
|
||||||
|
</p>
|
||||||
|
<form>
|
||||||
|
{window.location.protocol}//
|
||||||
|
{window.location.host}/events/
|
||||||
|
<InputSlug
|
||||||
|
placeholder={t("introCreateEventSlugPlaceholder")}
|
||||||
|
/>
|
||||||
|
<button aria-label="Continue" className="input-square input-positive">
|
||||||
|
→
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</> : <>
|
||||||
|
<LoginButton
|
||||||
|
botName="festaappbot"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<p>
|
<p>
|
||||||
{loginMessage}
|
{loginMessage}
|
||||||
</p>
|
</p>
|
||||||
<LoginButton
|
{input}
|
||||||
botName="festaappbot"
|
|
||||||
/>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
|
@ -1,17 +1,12 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {LoginContext} from "../contexts/login"
|
import {LoginContext} from "../contexts/login"
|
||||||
import OriginalTelegramLoginButton from 'react-telegram-login'
|
import OriginalTelegramLoginButton from 'react-telegram-login'
|
||||||
import { useDefinedContext } from '../hooks/useDefinedContext';
|
import { useDefinedContext } from '../utils/definedContext';
|
||||||
|
|
||||||
export function LoginButton(props: any) {
|
export function LoginButton(props: any) {
|
||||||
const [login, setLogin] = useDefinedContext(LoginContext)
|
const [login, setLogin] = useDefinedContext(LoginContext)
|
||||||
|
|
||||||
return React.useMemo(() => (
|
return (
|
||||||
login ?
|
|
||||||
<button onClick={() => setLogin(null)} className="btn-telegram">
|
|
||||||
Log out
|
|
||||||
</button>
|
|
||||||
:
|
|
||||||
<div className="container-btn-telegram">
|
<div className="container-btn-telegram">
|
||||||
<OriginalTelegramLoginButton
|
<OriginalTelegramLoginButton
|
||||||
dataOnauth={setLogin}
|
dataOnauth={setLogin}
|
||||||
|
@ -19,7 +14,5 @@ export function LoginButton(props: any) {
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
),
|
|
||||||
[login]
|
|
||||||
)
|
)
|
||||||
}
|
}
|
16
components/LogoutLink.tsx
Normal file
16
components/LogoutLink.tsx
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { useTranslation } from "next-i18next"
|
||||||
|
import { LoginContext } from "../contexts/login"
|
||||||
|
import { useDefinedContext } from "../utils/definedContext"
|
||||||
|
|
||||||
|
export function LogoutLink() {
|
||||||
|
const [login, setLogin] = useDefinedContext(LoginContext)
|
||||||
|
const {t} = useTranslation("common")
|
||||||
|
|
||||||
|
return (
|
||||||
|
<small>
|
||||||
|
<a href="javascript:void(0)" onClick={() => setLogin(null)}>
|
||||||
|
{t("introTelegramLogout")}
|
||||||
|
</a>
|
||||||
|
</small>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { PostcardContext } from "../contexts/postcard";
|
import { PostcardContext } from "../contexts/postcard";
|
||||||
import { useDefinedContext } from "../hooks/useDefinedContext";
|
import { useDefinedContext } from "../utils/definedContext";
|
||||||
|
|
||||||
export function Postcard() {
|
export function Postcard() {
|
||||||
const [postcard, _] = useDefinedContext(PostcardContext)
|
const [postcard, _] = useDefinedContext(PostcardContext)
|
||||||
|
|
21
components/TelegramAvatar.tsx
Normal file
21
components/TelegramAvatar.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { LoginContext } from "../contexts/login";
|
||||||
|
import { useDefinedContext } from "../utils/definedContext";
|
||||||
|
import { UserData } from "../utils/telegram";
|
||||||
|
|
||||||
|
|
||||||
|
export interface TelegramAvatarProps {
|
||||||
|
u: UserData
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function TelegramAvatar({u}: TelegramAvatarProps) {
|
||||||
|
const [login, _] = useDefinedContext(LoginContext)
|
||||||
|
|
||||||
|
return login ?
|
||||||
|
<img
|
||||||
|
src={u.photo_url}
|
||||||
|
className="avatar-telegram-inline"
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
null
|
||||||
|
}
|
|
@ -1,24 +1,28 @@
|
||||||
import { UserData } from "../utils/telegram";
|
import { UserData } from "../utils/telegram";
|
||||||
|
import { TelegramAvatar } from "./TelegramAvatar";
|
||||||
|
|
||||||
interface TelegramUserLinkProps {
|
interface TelegramUserLinkProps {
|
||||||
u: UserData
|
u: UserData
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TelegramUserLink({u}: TelegramUserLinkProps) {
|
export function TelegramUser({u}: TelegramUserLinkProps) {
|
||||||
|
|
||||||
if(u.username) return (
|
if(u.username) return (
|
||||||
<a href={`https://t.me/${u.username}`}>
|
<a href={`https://t.me/${u.username}`}>
|
||||||
|
<TelegramAvatar u={u}/>
|
||||||
{u.username}
|
{u.username}
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
else if(u.last_name) return (
|
else if(u.last_name) return (
|
||||||
<span>
|
<span>
|
||||||
|
<TelegramAvatar u={u}/>
|
||||||
{u.first_name} {u.last_name}
|
{u.first_name} {u.last_name}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
else return (
|
else return (
|
||||||
<span>
|
<span>
|
||||||
u.first_name
|
<TelegramAvatar u={u}/>
|
||||||
|
{u.first_name}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
import { LoginContext } from "../contexts/login";
|
|
||||||
import { useDefinedContext } from "../hooks/useDefinedContext";
|
|
||||||
|
|
||||||
export function UserAvatar() {
|
|
||||||
const [login, _] = useDefinedContext(LoginContext)
|
|
||||||
|
|
||||||
return login ?
|
|
||||||
<img
|
|
||||||
src={login?.photo_url}
|
|
||||||
className="avatar-telegram"
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { createStateContext } from "../hooks/useStateContext";
|
import { useStorageState } from "react-storage-hooks";
|
||||||
|
import { createStateContext } from "../utils/stateContext";
|
||||||
import * as Telegram from "../utils/telegram"
|
import * as Telegram from "../utils/telegram"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createStateContext } from "../hooks/useStateContext";
|
import { createStateContext } from "../utils/stateContext";
|
||||||
import { StaticImageData } from "next/image";
|
import { StaticImageData } from "next/image";
|
||||||
import * as Telegram from "../utils/telegram"
|
import * as Telegram from "../utils/telegram"
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,13 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "3.14.0",
|
"@prisma/client": "3.14.0",
|
||||||
|
"classnames": "^2.3.1",
|
||||||
"next": "12.1.6",
|
"next": "12.1.6",
|
||||||
"next-i18next": "^11.0.0",
|
"next-i18next": "^11.0.0",
|
||||||
"prisma": "^3.14.0",
|
"prisma": "^3.14.0",
|
||||||
"react": "18.1.0",
|
"react": "18.1.0",
|
||||||
"react-dom": "18.1.0",
|
"react-dom": "18.1.0",
|
||||||
|
"react-storage-hooks": "^4.0.1",
|
||||||
"react-telegram-login": "^1.1.2"
|
"react-telegram-login": "^1.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -4,21 +4,47 @@ import '../styles/postcard.css'
|
||||||
import "../styles/index.css"
|
import "../styles/index.css"
|
||||||
import type { AppProps } from 'next/app'
|
import type { AppProps } from 'next/app'
|
||||||
import { LoginContext } from '../contexts/login'
|
import { LoginContext } from '../contexts/login'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import * as Telegram from "../utils/telegram"
|
import * as Telegram from "../utils/telegram"
|
||||||
import defaultPostcard from "../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
import defaultPostcard from "../public/postcards/adi-goldstein-Hli3R6LKibo-unsplash.jpg"
|
||||||
import { Postcard } from '../components/Postcard'
|
import { Postcard } from '../components/Postcard'
|
||||||
import { PostcardContext } from '../contexts/postcard'
|
import { PostcardContext } from '../contexts/postcard'
|
||||||
import { StaticImageData } from 'next/image'
|
import { StaticImageData } from 'next/image'
|
||||||
import { appWithTranslation } from 'next-i18next'
|
import { appWithTranslation } from 'next-i18next'
|
||||||
|
import { useStorageState } from 'react-storage-hooks'
|
||||||
|
|
||||||
|
const dummyStorage = {
|
||||||
|
getItem: () => null,
|
||||||
|
setItem: () => {},
|
||||||
|
removeItem: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||||
const loginHook = useState<Telegram.LoginData | null>(null)
|
const [login, setLogin] = useState<Telegram.LoginData | null>(null)
|
||||||
const postcardHook = useState<string | StaticImageData>(defaultPostcard)
|
const [postcard, setPostcard] = useState<string | StaticImageData>(defaultPostcard)
|
||||||
|
|
||||||
|
// Ha ha ha. Fooled you again, silly SSR!
|
||||||
|
const thatStorageOverThere = typeof sessionStorage !== "undefined" ? sessionStorage : undefined
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
if(thatStorageOverThere === undefined) return
|
||||||
|
|
||||||
|
const raw = sessionStorage.getItem("login")
|
||||||
|
if(raw === null) return
|
||||||
|
|
||||||
|
const parsed = JSON.parse(raw) as Telegram.LoginData
|
||||||
|
const response = new Telegram.LoginResponse(parsed)
|
||||||
|
if(!response.isRecent) return
|
||||||
|
|
||||||
|
setLogin(parsed)
|
||||||
|
},
|
||||||
|
[thatStorageOverThere]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PostcardContext.Provider value={postcardHook}>
|
<PostcardContext.Provider value={[postcard, setPostcard]}>
|
||||||
<LoginContext.Provider value={loginHook}>
|
<LoginContext.Provider value={[login, setLogin]}>
|
||||||
<Postcard/>
|
<Postcard/>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</LoginContext.Provider>
|
</LoginContext.Provider>
|
||||||
|
|
|
@ -1,6 +1 @@
|
||||||
{
|
{}
|
||||||
"siteTitle": "Festa",
|
|
||||||
"siteSubtitle": "Organizza il tuo evento ora!",
|
|
||||||
"introTelegramLogin": "Effettua il login con Telegram per iniziare a creare il tuo evento.",
|
|
||||||
"introTelegramLoggedIn": "Sei connesso come <1/>! Non sei tu?"
|
|
||||||
}
|
|
8
public/locales/it-IT/common.json.disabled
Normal file
8
public/locales/it-IT/common.json.disabled
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"siteTitle": "Festa",
|
||||||
|
"siteSubtitle": "Organizza il tuo evento ora!",
|
||||||
|
"introTelegramLogin": "Effettua il login con Telegram per iniziare a creare il tuo evento.",
|
||||||
|
"introTelegramLoggedIn": "Sei connesso come <1/>!",
|
||||||
|
"introTelegramLogout": "Non sei tu?",
|
||||||
|
"introCreateEvent": ""
|
||||||
|
}
|
|
@ -1,7 +1,43 @@
|
||||||
html, body {
|
@media (prefers-color-scheme: light) {
|
||||||
|
body {
|
||||||
|
--background: #fafafa;
|
||||||
|
--foreground: black;
|
||||||
|
--border: darkgray;
|
||||||
|
|
||||||
|
--anchor: #4444ff;
|
||||||
|
--anchor-visited: #aa44ff;
|
||||||
|
--anchor-active: #ff4444;
|
||||||
|
|
||||||
|
--positive: #008800;
|
||||||
|
--negative: #880000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
--background: #050505;
|
||||||
|
--foreground: white;
|
||||||
|
--border: darkgray;
|
||||||
|
|
||||||
|
--anchor: #8888ff;
|
||||||
|
--anchor-visited: #aa88ff;
|
||||||
|
--anchor-active: #ff8888;
|
||||||
|
|
||||||
|
--positive: #88ff88;
|
||||||
|
--negative: #ff8888;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
background-color: var(--background);
|
||||||
|
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
color: var(--foreground);
|
||||||
|
text-shadow: 1px 1px 1px var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
|
@ -10,43 +46,61 @@ html, body {
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
text-shadow: 2px 2px 2px var(--background);
|
||||||
|
|
||||||
@media (prefers-color-scheme: light) {
|
|
||||||
body {
|
|
||||||
background-color: white;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
text-shadow: 1px 1px 1px white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #4444ff;
|
color: var(--anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
color: #aa44ff;
|
color: var(--anchor-visited);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
a:active {
|
||||||
body {
|
color: var(--anchor-active);
|
||||||
background-color: black;
|
|
||||||
color: white;
|
|
||||||
text-shadow: 1px 1px 1px black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
input, button {
|
||||||
text-shadow: 2px 2px 2px black;
|
padding: 8px;
|
||||||
|
margin: 2px 4px;
|
||||||
|
|
||||||
|
color: var(--foreground);
|
||||||
|
background-color: var(--background);
|
||||||
|
|
||||||
|
border-width: 2px;
|
||||||
|
border-color: var(--border);
|
||||||
|
border-radius: 16px;
|
||||||
|
|
||||||
|
font-size: medium;
|
||||||
|
height: 40px;
|
||||||
|
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
input[type="text"] {
|
||||||
color: #8888ff;
|
border-style: inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
input[type="submit"], button {
|
||||||
color: #aa88ff;
|
border-style: outset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="submit"]:active, button:active {
|
||||||
|
border-style: inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-square {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-positive {
|
||||||
|
border-color: var(--positive);
|
||||||
|
color: var(--positive);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-negative {
|
||||||
|
border-color: var(--negative);
|
||||||
|
color: var(--negative);
|
||||||
}
|
}
|
|
@ -21,10 +21,8 @@
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-telegram {
|
.avatar-telegram-inline {
|
||||||
width: 40px;
|
height: 1em;
|
||||||
height: 40px;
|
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
|
margin-right: 3px;
|
||||||
margin-left: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import { useContext } from "react"
|
import { useContext } from "react"
|
||||||
import { createDefinedContext } from "./useDefinedContext"
|
import { createDefinedContext } from "./definedContext"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new defined context (see {@link createDefinedContext}) containing the tuple returned by {@link React.useState} for the given type.
|
* Create a new defined context (see {@link createDefinedContext}) containing the tuple returned by {@link React.useState} for the given type.
|
|
@ -1,6 +1,6 @@
|
||||||
import nodecrypto from "crypto"
|
import nodecrypto from "crypto"
|
||||||
import { ParsedUrlQuery } from "querystring"
|
import { ParsedUrlQuery } from "querystring"
|
||||||
import * as QueryString from "./querystring"
|
import * as QueryString from "./queryString"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializable Telegram user data without any technical information.
|
* Serializable Telegram user data without any technical information.
|
||||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -391,6 +391,11 @@ chalk@^4.0.0:
|
||||||
ansi-styles "^4.1.0"
|
ansi-styles "^4.1.0"
|
||||||
supports-color "^7.1.0"
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
|
classnames@^2.3.1:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||||
|
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||||
|
|
||||||
color-convert@^2.0.1:
|
color-convert@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||||
|
@ -1504,6 +1509,11 @@ react-is@^16.13.1, react-is@^16.7.0:
|
||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-storage-hooks@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.npmjs.org/react-storage-hooks/-/react-storage-hooks-4.0.1.tgz#e30ed5cda48c77c431ecc02ec3824bd615f5b7fb"
|
||||||
|
integrity sha512-fetDkT5RDHGruc2NrdD1iqqoLuXgbx6AUpQSQLLkrCiJf8i97EtwJNXNTy3+GRfsATLG8TZgNc9lGRZOaU5yQA==
|
||||||
|
|
||||||
react-telegram-login@^1.1.2:
|
react-telegram-login@^1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npmjs.org/react-telegram-login/-/react-telegram-login-1.1.2.tgz#28b9bdd68bb2710afca19354ac1f9428092836f0"
|
resolved "https://registry.npmjs.org/react-telegram-login/-/react-telegram-login-1.1.2.tgz#28b9bdd68bb2710afca19354ac1f9428092836f0"
|
||||||
|
|
Loading…
Reference in a new issue