Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: add login page #93

Merged
merged 4 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"dyld",
"fullscreen",
"headlessui",
"Icdbb",
"icns",
"INFINI",
"inputbox",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@headlessui/react": "^2.1.10",
"@react-oauth/google": "^0.12.1",
"@tauri-apps/api": ">=2.0.0",
"@tauri-apps/plugin-autostart": "~2",
"@tauri-apps/plugin-global-shortcut": "~2.0.0",
Expand Down
14 changes: 14 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"core:window:allow-get-all-windows",
"core:window:allow-set-focus",
"core:app:allow-set-app-theme",
"shell:allow-open",
"shell:default",
"http:default",
"http:allow-fetch",
"http:allow-fetch-cancel",
Expand Down
Binary file added src/assets/images/apple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/bg-login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/coco-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/google.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/components/AppAI/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
CornerDownLeft,
} from "lucide-react";

import logoImg from "@/assets/32x32.png";

interface FooterProps {
isChat: boolean;
name?: string;
Expand All @@ -17,6 +19,13 @@ export default function Footer({ name }: FooterProps) {
className="px-4 z-999 mx-[1px] h-10 absolute bottom-0 left-0 right-0 border-t border-gray-200 dark:border-gray-700 flex items-center justify-between rounded-xl rounded-t-none overflow-hidden"
>
<div className="flex items-center">
<div className="flex items-center space-x-4">
<img src={logoImg} className="w-5 h-5" />
<span className="text-xs text-gray-500 dark:text-gray-400">
Version 1.0.0
</span>
</div>

{name ? (
<div className="flex gap-2 items-center text-[#666] text-xs">
<AppWindowMac className="w-5 h-5" /> {name}
Expand Down
96 changes: 57 additions & 39 deletions src/components/Auth/CocoCloud.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,70 @@
import { useState } from "react";
import { Cloud } from "lucide-react";

import { UserProfile } from "./UserProfile";
import { DataSourcesList } from "./DataSourcesList";
import { Sidebar } from "./Sidebar";
import { ConnectService } from "./ConnectService";

export default function CocoCloud() {
const [isLogin, setIsLogin] = useState(true);
const [isConnect, setIsConnect] = useState(true);

return (
<div className="min-h-screen bg-gray-50">
<div className="max-w-4xl mx-auto px-4 py-8">
<div className="flex items-center justify-between mb-8">
<div className="flex items-center space-x-3">
<div className="flex items-center space-x-2 px-4 py-2 bg-white rounded-md border border-gray-200">
<Cloud className="w-5 h-5 text-blue-500" />
<span className="font-medium">Coco Cloud</span>
<div className="flex min-h-screen bg-gray-50">
<Sidebar />

<main className="flex-1">
{isConnect ? <div className="max-w-4xl mx-auto px-4 py-8">
<div className="flex items-center justify-between mb-8">
<div className="flex items-center space-x-3">
<div className="flex items-center space-x-2 px-4 py-2 bg-white rounded-md border border-gray-200">
<Cloud className="w-5 h-5 text-blue-500" />
<span className="font-medium">Coco Cloud</span>
</div>
<span className="px-3 py-1 text-sm text-blue-600 bg-blue-50 rounded-md">
Available
</span>
</div>
<span className="px-3 py-1 text-sm text-blue-600 bg-blue-50 rounded-md">
Available
</span>
<button className="p-2 text-gray-500 hover:text-gray-700">
<Cloud className="w-5 h-5" />
</button>
</div>
<button className="p-2 text-gray-500 hover:text-gray-700">
<Cloud className="w-5 h-5" />
</button>
</div>
<div className="mb-8">
<div className="text-sm text-gray-500 mb-4">
<span>Service provision: INFINI Labs</span>
<span className="mx-4">|</span>
<span>Version Number: v2.3.0</span>
<span className="mx-4">|</span>
<span>Update time: 2023-05-12</span>

<div className="mb-8">
<div className="text-sm text-gray-500 mb-4">
<span>Service provision: INFINI Labs</span>
<span className="mx-4">|</span>
<span>Version Number: v2.3.0</span>
<span className="mx-4">|</span>
<span>Update time: 2023-05-12</span>
</div>
<p className="text-gray-600 leading-relaxed">
Coco Cloud provides users with a cloud storage and data
integration platform that supports account registration and data
source management. Users can integrate multiple data sources (such
as Google Drive, yuque, GitHub, etc.), easily access and search
for files, documents and codes across platforms, and achieve
efficient data collaboration and management.
</p>
</div>

<div className="mb-8">
<h2 className="text-lg font-medium text-gray-900 mb-4">
Account Information
</h2>
{isLogin ? (
<UserProfile name="Rain" email="an121245@gmail.com" />
) : (
<button className="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors">
Login
</button>
)}
</div>
<p className="text-gray-600 leading-relaxed">
Coco Cloud provides users with a cloud storage and data integration
platform that supports account registration and data source
management. Users can integrate multiple data sources (such as
Google Drive, yuque, GitHub, etc.), easily access and search for
files, documents and codes across platforms, and achieve efficient
data collaboration and management.
</p>
</div>
<div>
<h2 className="text-lg font-medium text-gray-900 mb-4">Account Information</h2>
<button className="px-6 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition-colors">
Login
</button>
</div>

<UserProfile name="Rain" email="an121245@gmail.com" />
<DataSourcesList />
</div>
{isLogin ? <DataSourcesList /> : null }
</div>: <ConnectService />}
</main>
</div>
);
}
53 changes: 53 additions & 0 deletions src/components/Auth/ConnectService.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useState } from 'react';
import { ArrowLeft } from 'lucide-react';

export function ConnectService() {
const [sourceName, setSourceName] = useState('');

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log('Connecting Google Drive with name:', sourceName);
};

return (
<div className="p-8 max-w-4xl">
<div className="mb-8">
<button className="flex items-center text-gray-600 hover:text-gray-900">
<ArrowLeft className="w-5 h-5 mr-2" />
<span>Connect Google Drive</span>
</button>
</div>

<div className="mb-8">
<p className="text-gray-600">
Coco needs to obtain authorization from your Google Drive account
</p>
</div>

<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label htmlFor="sourceName" className="block text-sm font-medium text-gray-700 mb-1">
Data Source Name
</label>
<input
type="text"
id="sourceName"
value={sourceName}
onChange={(e) => setSourceName(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
placeholder="Your Google Drive"
/>
</div>

<div className="flex justify-end">
<button
type="submit"
className="px-6 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
>
Save
</button>
</div>
</form>
</div>
);
}
20 changes: 9 additions & 11 deletions src/components/Auth/DataSourceItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link2, Trash2 } from 'lucide-react';
import { Link2, Trash2 } from "lucide-react";

interface Account {
email: string;
Expand All @@ -18,21 +18,19 @@ export function DataSourceItem({ name, type, accounts }: DataSourceItemProps) {
<div className="border border-gray-200 rounded-lg p-4">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center space-x-3">
<img
src={`/icons/${type}.svg`}
alt={name}
className="w-6 h-6"
/>
<img src={`/icons/${type}.svg`} alt={name} className="w-6 h-6" />
<span className="font-medium">{name}</span>
</div>
<button className="text-blue-500 hover:text-blue-600 flex items-center space-x-1">
<Link2 className="w-4 h-4" />
<span className="text-sm">{isConnected ? '管理' : '连接账户'}</span>
</button>
</div>
<div className="text-sm text-gray-500 mb-2">
{isConnected ? "Manage" : "Connect Accounts"}
</div>

{accounts.map((account, index) => (
<div
<div
key={account.email}
className="flex items-center justify-between py-2 border-t border-gray-100"
>
Expand All @@ -44,14 +42,14 @@ export function DataSourceItem({ name, type, accounts }: DataSourceItemProps) {
</div>
<div>
<div className="text-sm font-medium">
{index === 0 ? '我的网盘' : `网盘${index + 1}`}
{index === 0 ? "My network disk" : `Network disk ${index + 1}`}
</div>
<div className="text-xs text-gray-500">{account.email}</div>
</div>
</div>
<div className="flex items-center space-x-4">
<span className="text-xs text-gray-500">
最近同步: {account.lastSync}
Recently Synced: {account.lastSync}
</span>
<button className="text-gray-400 hover:text-gray-600">
<Trash2 className="w-4 h-4" />
Expand All @@ -61,4 +59,4 @@ export function DataSourceItem({ name, type, accounts }: DataSourceItemProps) {
))}
</div>
);
}
}
6 changes: 3 additions & 3 deletions src/components/Auth/DataSourcesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export function DataSourcesList() {
name: 'Google Drive',
type: 'google',
accounts: [
{ email: 'an121245@gmail.com', lastSync: '2025年1月2日 09:50 AM' },
{ email: '9paiii@gmail.com', lastSync: '2025年1月2日 09:50 AM' }
{ email: 'an121245@gmail.com', lastSync: '2025-01-02 09:50 AM' },
{ email: '9paiii@gmail.com', lastSync: '2025-01-02 09:50 AM' }
]
},
{
Expand All @@ -27,7 +27,7 @@ export function DataSourcesList() {

return (
<div className="space-y-4">
<h2 className="text-xl font-medium text-gray-900">数据源</h2>
<h2 className="text-xl font-medium text-gray-900">Data Source</h2>
<div className="space-y-4">
{dataSources.map(source => (
<DataSourceItem key={source.id} {...source} />
Expand Down
28 changes: 28 additions & 0 deletions src/components/Auth/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Cloud, Plus } from "lucide-react";

export function Sidebar() {
return (
<div className="w-64 border-r border-gray-200 bg-white">
<div className="p-4">
<div className="flex items-center space-x-2 px-3 py-2 bg-blue-50 text-blue-600 rounded-lg mb-6">
<Cloud className="w-5 h-5" />
<span className="font-medium">Coco Cloud</span>
<div className="flex-1" />
<button className="text-blue-600 hover:text-blue-700">
<Cloud className="w-4 h-4" />
</button>
</div>

<div className="space-y-2">
<div className="text-sm font-medium text-gray-500 px-3 mb-2">
Third-party services
</div>

<button className="w-full flex items-center justify-center p-2 border-2 border-dashed border-gray-200 rounded-lg text-gray-400 hover:text-gray-600 hover:border-gray-300">
<Plus className="w-5 h-5" />
</button>
</div>
</div>
</div>
);
}
1 change: 0 additions & 1 deletion src/components/Auth/UserProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ interface UserProfileProps {
export function UserProfile({ name, email }: UserProfileProps) {
return (
<div className="space-y-6">
<h2 className="text-xl font-medium text-gray-900">账户信息</h2>
<div className="flex items-center space-x-4">
<div className="w-12 h-12 bg-gray-100 rounded-full flex items-center justify-center">
<User className="w-6 h-6 text-gray-500" />
Expand Down
Loading