Skip to content

Commit

Permalink
Merge pull request #14 from git-init-priyanshu/nextjs
Browse files Browse the repository at this point in the history
Search bar implementation & UI changes
  • Loading branch information
git-init-priyanshu authored Aug 10, 2024
2 parents ffb7cd3 + 07f38e8 commit f17a885
Show file tree
Hide file tree
Showing 22 changed files with 561 additions and 157 deletions.
10 changes: 5 additions & 5 deletions app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import Image from "next/image";

import SignInImage from '@/public/signin.webp'

export default function AuthLayout({ children }: { children: React.ReactNode }) {
return (
<div className="w-full h-dvh lg:grid lg:grid-cols-2 ">
<div className="w-full h-dvh lg:grid lg:grid-cols-2 overflow-hidden">
<div className="flex items-center justify-center py-12">
<div className="mx-auto grid w-[350px] gap-6">
{children}
</div>
</div>
<div className="hidden bg-muted lg:block">
<Image
src="/placeholder.svg"
src={SignInImage}
alt="Image"
width="1920"
height="1080"
className="h-full w-full object-cover dark:brightness-[0.2] dark:grayscale"
className="h-full w-full dark:brightness-[0.2] dark:grayscale"
/>
</div>
</div>
Expand Down
18 changes: 13 additions & 5 deletions app/(auth)/signin/components/LogInForm.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
import Link from "next/link"
import { useState } from "react"
import { useRouter } from "next/navigation"
import { useForm } from 'react-hook-form'
import Link from "next/link"
import { z } from 'zod'

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

import { SigninAction } from "../../actions"
import { signinSchema } from '../../zodSchema'
import { toast } from "sonner"
import LoaderButton from "@/components/LoaderButton"


export default function LogInForm() {
const router = useRouter()

const [isSubmitting, setIsSubmitting] = useState(false);

const { register, handleSubmit } = useForm<z.infer<typeof signinSchema>>();

const submitForm = async (data: z.infer<typeof signinSchema>) => {
setIsSubmitting(true);
const parsedData = signinSchema.parse({
email: data.email,
password: data.password
Expand All @@ -26,8 +30,10 @@ export default function LogInForm() {
if (response.success) {
toast.success("login completed")
router.push('/')
setIsSubmitting(false);
} else {
toast.error(response.error)
setIsSubmitting(false);
}
};

Expand Down Expand Up @@ -56,9 +62,11 @@ export default function LogInForm() {
{...register('password', { required: true })}
/>
</div>
<Button type="submit" className="w-full bg-blue-500">
Sign in
</Button>
<LoaderButton
className="w-full bg-blue-500 hover:bg-blue-600"
isLoading={isSubmitting}
type="submit"
>Sign in</LoaderButton>
</form>
)
}
16 changes: 12 additions & 4 deletions app/(auth)/signup/components/SignInForm.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
"use client"

import { useState } from "react"
import { useRouter } from "next/navigation"
import { useForm } from 'react-hook-form'
import { toast } from "sonner"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { z } from 'zod'

import { signupSchema } from '../../zodSchema'
import { SignupAction } from '../../actions'
import LoaderButton from "@/components/LoaderButton"

export default function CredentialsForm() {
const router = useRouter();

const { register, handleSubmit } = useForm<z.infer<typeof signupSchema>>();

const [isSubmitting, setIsSubmitting] = useState(false);

const submitForm = async (data: z.infer<typeof signupSchema>) => {
setIsSubmitting(true);
const parsedData = signupSchema.parse({
name: data.name,
username: data.username,
Expand All @@ -29,9 +33,11 @@ export default function CredentialsForm() {
if (response.success) {
toast.success("Signin completed")
router.push('/')
setIsSubmitting(false);
} else {
console.log(response.error);
toast.error(response.error);
setIsSubmitting(false);
}
};
return (
Expand Down Expand Up @@ -67,9 +73,11 @@ export default function CredentialsForm() {
{...register('password', { required: true })}
/>
</div>
<Button type="submit" className="w-full bg-blue-500">
Sign up
</Button>
<LoaderButton
className="w-full bg-blue-500 hover:bg-blue-600"
isLoading={isSubmitting}
type="submit"
>Sign up</LoaderButton>
</form>
)
}
35 changes: 17 additions & 18 deletions app/components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { useCallback, useMemo, useRef, useState } from "react"
import { useRef, useState } from "react"
import { useRouter } from "next/navigation"

import {
Expand All @@ -13,9 +13,9 @@ import { Input } from "@/components/ui/input"

import prettifyDate from '@/helpers/prettifyDates'
import CardOptions from "./components/Options"
import { debounce } from "lodash"
import { RenameDocument } from "./actions"
import useClientSession from "@/lib/customHooks/useClientSession"
import { CircleCheck } from "lucide-react"

type DocCardPropType = {
docId: string;
Expand All @@ -39,13 +39,6 @@ export default function DocCard({ docId, thumbnail, title, updatedAt, users }: D

const [name, setName] = useState(title)

const saveName = useCallback(async () => {
if (!inputRef.current || !session?.id) return;
await RenameDocument(docId, session.id, inputRef.current.value);
}, [])

const debounceSaveName = useMemo(() => debounce(saveName, 2000), [saveName])

const getInitials = (name: string) => {
let initials = name.split(" ");

Expand All @@ -62,15 +55,21 @@ export default function DocCard({ docId, thumbnail, title, updatedAt, users }: D
>
</CardContent>
<CardFooter className="flex flex-col items-start gap-2 border-t p-4">
<Input
ref={inputRef}
value={name}
className="w-full text-md border-none focus:outline-none"
onChange={e => {
setName(e.target.value)
debounceSaveName();
}}
/>
<div className="relative">
<Input
ref={inputRef}
value={name}
className="w-full text-md border-none focus-visible:bg-slate-50"
onChange={e => setName(e.target.value)}
/>
<CircleCheck
onClick={async () => {
if (!inputRef.current || !session?.id) return;
await RenameDocument(docId, session.id, inputRef.current.value);
}}
className={`${title != name ? "" : "hidden"} size-4 text-slate-500 hover:cursor-pointer absolute right-3 top-1/2 transform -translate-y-1/2`}>
</CircleCheck>
</div>
<div className="flex items-center w-full justify-between">
<div className="flex gap-2 items-center">
{users.map((e, index) => {
Expand Down
28 changes: 12 additions & 16 deletions app/components/Card/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
'use client'

import { Input } from "@/components/ui/input";
import { useRef, useState } from "react"

type InputPropType = {
title: string;
}

export default function CardInput({title}:InputPropType) {
const inputRef = useRef<HTMLInputElement>(null);

const [name, setName] = useState(title)
import { CircleCheck } from "lucide-react";

export default function CardInput({ title, value, ...props }: any) {
console.log(value)
return (
<Input
ref={inputRef}
value={name}
className="w-full text-md border-none focus:outline-none"
onChange={(e) => setName(e.target.value)}
/>
<div className="relative">
<Input
{...props}
value={value}
/>
<CircleCheck
className={`size-4 text-slate-500 hover:cursor-pointer absolute right-3 top-1/2 transform -translate-y-1/2`}>
</CircleCheck>
</div>
)
}
15 changes: 10 additions & 5 deletions app/components/Card/components/Options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Button } from "@/components/ui/button"

import { DeleteDocument } from "../actions"
import useClientSession from "@/lib/customHooks/useClientSession"
import LoaderButton from "@/components/LoaderButton"

type CardOptionsPropType = {
docId: string,
Expand All @@ -43,8 +44,9 @@ export default function CardOptions({ docId, inputRef }: CardOptionsPropType) {
{ icon: Trash2, color: "#f94848", title: "Delete", onClick: () => deleteDocument() },
]

const [isOptionsOpen, setIsOptionsOpen] = useState(false)
const [isOpen, setIsOpen] = useState(false)
const [isOptionsOpen, setIsOptionsOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [isDeleting, setIsDeleting] = useState(false);

const renameDocument = () => {
if (!inputRef.current) return;
Expand All @@ -62,6 +64,7 @@ export default function CardOptions({ docId, inputRef }: CardOptionsPropType) {
}

const confirmDeleteDocument = async () => {
setIsDeleting(true);
if (!session.id) return;

const response = await DeleteDocument(docId, session.id);
Expand All @@ -70,6 +73,7 @@ export default function CardOptions({ docId, inputRef }: CardOptionsPropType) {
} else {
toast.error(response.error)
}
setIsDeleting(false);
}
return (
<>
Expand Down Expand Up @@ -108,13 +112,14 @@ export default function CardOptions({ docId, inputRef }: CardOptionsPropType) {
</DialogHeader>
<div className="flex gap-4">
<Button variant="outline" onClick={() => setIsOpen(false)}>Cancel</Button>
<Button
<LoaderButton
variant="outline"
onClick={confirmDeleteDocument}
onClickFunc={confirmDeleteDocument}
isLoading={isDeleting}
className="border-red-200 bg-red-100 hover:bg-red-200"
>
Confirm
</Button>
</LoaderButton>
</div>
</DialogContent>
</Dialog>
Expand Down
93 changes: 6 additions & 87 deletions app/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,99 +1,18 @@
"use client"

import { useState } from "react"
import { useRouter } from "next/navigation"
import Image from "next/image"
import { toast } from "sonner"
import {
CloudUpload,
LogOut,
Plus,
Search,
} from "lucide-react"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { CreateNewDocument, LogoutAction } from "./actions"
import logo from "@/public/doc.svg"
import useClientSession from "@/lib/customHooks/useClientSession"
import logo from "@/public/output-onlinepngtools.svg"
import SearchBar from "./components/SearchBar"
import HeaderButtons from "./components/HeaderButtons"

export default function Header() {
const router = useRouter();

const session = useClientSession();

const [isLoading, setIsLoading] = useState(false);

const createDocument = async () => {
setIsLoading(true);

if (!session?.id) return;
const response = await CreateNewDocument(session.id);
if (response.success) {
setIsLoading(false);
toast.success("Successfully created new document")
router.push(`/writer/${response.data?.id}`)
} else {
setIsLoading(false);
toast.error(response.error)
}
}

const logout = async () => {
const response = await LogoutAction();
console.log(response);
if (response.success) {
toast.success("Successfully logged out")
router.push('/api/auth/signin')
} else {
toast.error(response.error)
}
}

return (
<div className="flex border-b bg-white justify-between items-center py-2 px-4">
<div className="flex gap-2 items-center">
<Image src={logo} width={45} alt="logo" />
<p className="text-2xl">Docx</p>
</div>
<div>
<Input className="relative pl-8 rounded-full" placeholder="Search documents..." />
<Search size={20} className="absolute text-slate-500 top-5 ml-2" />
</div>
<div className="flex gap-4">
<Button
variant="outline"
className="flex gap-2 text-blue-500 hover:text-blue-500 hover:border-blue-200 rounded-full"
>
<CloudUpload size={15} />
Upload
</Button>
<Button
className="flex gap-2 bg-blue-500 text-white hover:bg-blue-600 rounded-full"
onClick={createDocument}
disabled={isLoading}
>
{isLoading ? <svg
className="animate-spin lucide lucide-loader-circle"
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 24 24"
fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
</svg> : <Plus size={20} />}
Create New
</Button>
<Button
variant="outline"
className="flex gap-2 text-blue-500 hover:text-blue-500 hover:border-blue-200 rounded-full"
onClick={logout}
>
<LogOut size={15} />
</Button>
{/* <p className="text-2xl">Docx</p> */}
</div>
<SearchBar />
<HeaderButtons />
</div>
)
}
Loading

0 comments on commit f17a885

Please sign in to comment.