您准备好彻底改变您的工作场所管理了吗?在这个综合教程中,我们将深入研究如何创建一个利用面部身份验证的最先进的员工仪表板。我们将使用 Web 开发中一些最热门的工具:Next.js、FACEIO 和 Shadcn UI。在本指南结束时,您将拥有一个时尚、安全的仪表板,让您的员工感觉他们生活在未来!
在我们开始之前,让我们确保你已经把所有的事情都安排好了:
明白了吗?伟大的!让我们开始这场演出吧。
首先,让我们创建 Next.js 项目。打开你的终端并输入这些神奇的单词:
npx create-next-app@latest faceio-app cd faceio-app
系统会问您几个问题。以下是如何回答这些问题:
现在,让我们去获取我们需要的所有好东西。运行此命令来安装我们的依赖项:
npm install @faceio/fiojs @shadcn/ui class-variance-authority clsx tailwind-merge
在项目的根目录中创建一个名为 .env.local 的文件。这是我们保存秘密 FACEIO 应用 ID 的地方:
NEXT_PUBLIC_FACEIO_APP_ID=your-super-secret-faceio-app-id
请记住将“your-super-secret-faceio-app-id”替换为您的实际 FACEIO 应用程序 ID。确保安全!
您的项目结构应如下所示:
faceio-app/ ├── app/ │ ├── layout.tsx │ ├── page.tsx │ └── components/ │ ├── FaceAuth.tsx │ └── EmployeeDashboard.tsx ├── public/ ├── .env.local ├── next.config.js ├── package.json ├── tsconfig.json └── tailwind.config.js
是时候给 Tailwind 改头换面了。使用这个奇特的配置更新您的 tailwind.config.js 文件:
/** @type {import('tailwindcss').Config} */ module.exports = { darkMode: ["class"], content: [ './app/**/*.{ts,tsx}', ], theme: { container: { center: true, padding: "2rem", screens: { "2xl": "1400px", }, }, extend: { colors: { border: "hsl(var(--border))", input: "hsl(var(--input))", ring: "hsl(var(--ring))", background: "hsl(var(--background))", foreground: "hsl(var(--foreground))", primary: { DEFAULT: "hsl(var(--primary))", foreground: "hsl(var(--primary-foreground))", }, secondary: { DEFAULT: "hsl(var(--secondary))", foreground: "hsl(var(--secondary-foreground))", }, destructive: { DEFAULT: "hsl(var(--destructive))", foreground: "hsl(var(--destructive-foreground))", }, muted: { DEFAULT: "hsl(var(--muted))", foreground: "hsl(var(--muted-foreground))", }, accent: { DEFAULT: "hsl(var(--accent))", foreground: "hsl(var(--accent-foreground))", }, popover: { DEFAULT: "hsl(var(--popover))", foreground: "hsl(var(--popover-foreground))", }, card: { DEFAULT: "hsl(var(--card))", foreground: "hsl(var(--card-foreground))", }, }, borderRadius: { lg: "var(--radius)", md: "calc(var(--radius) - 2px)", sm: "calc(var(--radius) - 4px)", }, keyframes: { "accordion-down": { from: { height: 0 }, to: { height: "var(--radix-accordion-content-height)" }, }, "accordion-up": { from: { height: "var(--radix-accordion-content-height)" }, to: { height: 0 }, }, }, animation: { "accordion-down": "accordion-down 0.2s ease-out", "accordion-up": "accordion-up 0.2s ease-out", }, }, }, plugins: [require("tailwindcss-animate")], }
让我们创建我们节目的明星 - FaceAuth 组件。创建一个新文件 app/components/FaceAuth.tsx 并粘贴以下代码:
import { useEffect } from 'react'; import faceIO from '@faceio/fiojs'; import { Button, Card, CardHeader, CardTitle, CardContent } from '@shadcn/ui'; import { useToast } from '@shadcn/ui'; interface FaceAuthProps { onSuccessfulAuth: (data: any) => void; } const FaceAuth: React.FC<FaceAuthProps> = ({ onSuccessfulAuth }) => { const { toast } = useToast(); useEffect(() => { const faceio = new faceIO(process.env.NEXT_PUBLIC_FACEIO_APP_ID); const enrollNewUser = async () => { try { const userInfo = await faceio.enroll({ locale: 'auto', payload: { email: 'employee@example.com', pin: '12345', }, }); toast({ title: "Success!", description: "You're now enrolled in the facial recognition system!", }); console.log('User Enrolled!', userInfo); } catch (errCode) { toast({ title: "Oops!", description: "Enrollment failed. Please try again.", variant: "destructive", }); console.error('Enrollment Failed', errCode); } }; const authenticateUser = async () => { try { const userData = await faceio.authenticate(); toast({ title: "Welcome back!", description: "Authentication successful.", }); console.log('User Authenticated!', userData); onSuccessfulAuth({ name: 'John Doe', position: 'Software Developer', department: 'Engineering', photoUrl: 'https://example.com/john-doe.jpg', }); } catch (errCode) { toast({ title: "Authentication failed", description: "Please try again or enroll.", variant: "destructive", }); console.error('Authentication Failed', errCode); } }; const enrollBtn = document.getElementById('enroll-btn'); const authBtn = document.getElementById('auth-btn'); if (enrollBtn) enrollBtn.onclick = enrollNewUser; if (authBtn) authBtn.onclick = authenticateUser; return () => { if (enrollBtn) enrollBtn.onclick = null; if (authBtn) authBtn.onclick = null; }; }, [toast, onSuccessfulAuth]); return ( <Card className="w-full max-w-md mx-auto"> <CardHeader> <CardTitle>Facial Authentication</CardTitle> </CardHeader> <CardContent className="space-y-4"> <Button id="enroll-btn" variant="outline" className="w-full"> Enroll New Employee </Button> <Button id="auth-btn" variant="default" className="w-full"> Authenticate </Button> </CardContent> </Card> ); }; export default FaceAuth;
现在,让我们创建员工将看到的仪表板。创建 app/components/EmployeeDashboard.tsx:
import { useState } from 'react'; import { Card, CardHeader, CardTitle, CardContent } from '@shadcn/ui'; import { Button, Avatar, Badge, Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@shadcn/ui'; import FaceAuth from './FaceAuth'; interface EmployeeData { name: string; position: string; department: string; photoUrl: string; } const EmployeeDashboard: React.FC = () => { const [isAuthenticated, setIsAuthenticated] = useState(false); const [employeeData, setEmployeeData] = useState<EmployeeData | null>(null); const handleSuccessfulAuth = (data: EmployeeData) => { setIsAuthenticated(true); setEmployeeData(data); }; const mockAttendanceData = [ { date: '2024-07-14', timeIn: '09:00 AM', timeOut: '05:30 PM' }, { date: '2024-07-13', timeIn: '08:55 AM', timeOut: '05:25 PM' }, { date: '2024-07-12', timeIn: '09:05 AM', timeOut: '05:35 PM' }, ]; return ( <div className="space-y-6"> {!isAuthenticated ? ( <FaceAuth onSuccessfulAuth={handleSuccessfulAuth} /> ) : ( <> <Card> <CardHeader> <CardTitle>Employee Profile</CardTitle> </CardHeader> <CardContent className="flex items-center space-x-4"> <Avatar className="h-20 w-20" src={employeeData?.photoUrl} alt={employeeData?.name} /> <div> <h2 className="text-2xl font-bold">{employeeData?.name}</h2> <p className="text-gray-500">{employeeData?.position}</p> <Badge variant="outline">{employeeData?.department}</Badge> </div> </CardContent> </Card> <Card> <CardHeader> <CardTitle>Quick Actions</CardTitle> </CardHeader> <CardContent className="space-y-4"> <Button className="w-full">Check-in</Button> <Button className="w-full" variant="secondary">Request Leave</Button> </CardContent> </Card> <Card> <CardHeader> <CardTitle>Attendance Records</CardTitle> </CardHeader> <CardContent> <Table> <TableHeader> <TableRow> <TableHead>Date</TableHead> <TableHead>Time In</TableHead> <TableHead>Time Out</TableHead> </TableRow> </TableHeader> <TableBody> {mockAttendanceData.map((record, index) => ( <TableRow key={index}> <TableCell>{record.date}</TableCell> <TableCell>{record.timeIn}</TableCell> <TableCell>{record.timeOut}</TableCell> </TableRow> ))} </TableBody> </Table> </CardContent> </Card> </> )} </div> ); }; export default EmployeeDashboard;
最后,让我们更新一下我们的主页,以展示我们的辛劳。更新 app/page.tsx:
import EmployeeDashboard from './components/EmployeeDashboard'; export default function Home() { return ( <main className="flex min-h-screen flex-col items-center justify-center p-4"> <EmployeeDashboard /> </main> ); }
现在,让我们设置包裹整个应用程序的布局。添加此代码:app/layout.tsx
import './globals.css' import type { Metadata } from 'next' import { Inter } from 'next/font/google' const inter = Inter({ subsets: ['latin'] }) export const metadata: Metadata = { title: 'Employee Dashboard with Facial Authentication', description: 'A cutting-edge employee dashboard featuring facial recognition for secure authentication and efficient workplace management.', } export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <body className={inter.className}> <header className="bg-primary text-white p-4"> <h1 className="text-2xl font-bold">Faceio Solutions</h1> </header> <main className="container mx-auto p-4"> {children} </main> <footer className="bg-gray-100 text-center p-4 mt-8"> <p>© 2024 Faceio . All rights reserved.</p> </footer> </body> </html> ) }
这种布局就像房子的框架 - 它为您的整个应用程序提供结构。它包括带有您公司名称的标题、将显示仪表板的主要内容区域和页脚。另外,它还利用元数据设置了一些 SEO 魔法!
更多详情,请参阅FACEIO最佳实践。
拒绝弱 PIN
防止重复注册
防止深度赝品
禁止未成年人报名
需要 PIN 码进行身份验证
强制使用唯一的 PIN
忽略被遮挡的面孔
拒绝丢失的标头
限制实例化
启用 Webhooks
更多详细信息,请参阅 FACEIO 安全最佳实践。
现在我们已经构建了这个很棒的仪表板,您可能想知道,“我可以在现实世界中的哪里使用它?”好吧,让我告诉你,可能性是无限的!这里只是一些想法:
办公室管理:告别老式打孔卡!该系统可以彻底改变您跟踪出勤、控制对办公室不同区域的访问以及管理员工信息的方式。
安全系统:想象一个世界,您的办公室位于诺克斯堡,但没有任何麻烦。该面部识别系统可以成为强大安全协议的基石。
客户服务亭:想象一下 - 客户走到服务亭,它立即识别出他们,并提供个性化服务。这不再是科幻小说了!
恭喜你,技术奇才!您刚刚构建了一个具有面部身份验证功能的尖端员工仪表板。但为什么停在这里呢?该系统的优点在于其灵活性。以下是一些将其提升到新水平的想法:
请记住,在科技世界中,唯一的限制是你的想象力(也许还有你的咖啡因摄入量)。
那么,你觉得怎么样?您准备好将您的工作场所带入未来了吗?尝试一下这个项目,让我知道进展如何。我很想听听您的经历、您添加的任何很酷的功能,或者您在此过程中面临的任何挑战。
祝您编码愉快,愿您的面部识别永远不会将您误认为是办公室植物!
以上是使用面部身份验证构建安全的员工仪表板:综合 Next.js 教程的详细内容。更多信息请关注PHP中文网其他相关文章!