Files
GoMFT/components/config_form.templ
T
StarFleetCPTN 6c96cdbec1 chore: Remove OneDrive and Google Drive storage options from config form
- Comment out OneDrive and Google Drive options in source and destination storage type selects
- Remove corresponding form templates for OneDrive and Google Drive authentication
- Temporarily disable these cloud storage options from the configuration interface
2025-03-08 16:49:52 -08:00

1983 lines
95 KiB
Templ

package components
import (
"fmt"
"github.com/starfleetcptn/gomft/internal/db"
"context"
)
type ConfigFormData struct {
Config *db.TransferConfig
IsNew bool
}
func getConfigFormTitle(isNew bool) string {
if isNew {
return "New Configuration"
}
return "Edit Configuration"
}
func getInitialData(config *db.TransferConfig) string {
name := ""
sourceType := "local"
sourcePath := ""
sourceHost := ""
sourcePort := 22
sourceUser := ""
sourcePassword := ""
sourceKeyFile := ""
// S3 fields
sourceBucket := ""
sourceRegion := ""
sourceAccessKey := ""
sourceSecretKey := ""
sourceEndpoint := ""
// SMB fields
sourceShare := ""
sourceDomain := ""
// FTP fields
sourcePassiveMode := true
// OneDrive and Google Drive fields
sourceClientId := ""
sourceClientSecret := ""
sourceDriveId := ""
sourceTeamDrive := ""
filePattern := "*"
outputPattern := ""
destinationType := "local"
destinationPath := ""
destHost := ""
destPort := 22
destUser := ""
destPassword := ""
destKeyFile := ""
// S3 fields
destBucket := ""
destRegion := ""
destAccessKey := ""
destSecretKey := ""
destEndpoint := ""
// SMB fields
destShare := ""
destDomain := ""
// FTP fields
destPassiveMode := true
// OneDrive and Google Drive fields
destClientId := ""
destClientSecret := ""
destDriveId := ""
destTeamDrive := ""
archivePath := ""
archiveEnabled := false
deleteAfterTransfer := false
rcloneFlags := ""
if config != nil {
name = config.Name
sourceType = config.SourceType
sourcePath = config.SourcePath
sourceHost = config.SourceHost
sourcePort = config.SourcePort
sourceUser = config.SourceUser
sourcePassword = config.SourcePassword
sourceKeyFile = config.SourceKeyFile
// S3 fields
sourceBucket = config.SourceBucket
sourceRegion = config.SourceRegion
sourceAccessKey = config.SourceAccessKey
sourceSecretKey = config.SourceSecretKey
sourceEndpoint = config.SourceEndpoint
// SMB fields
sourceShare = config.SourceShare
sourceDomain = config.SourceDomain
// FTP fields
sourcePassiveMode = config.SourcePassiveMode
// OneDrive and Google Drive fields
sourceClientId = config.SourceClientID
sourceClientSecret = config.SourceClientSecret
sourceDriveId = config.SourceDriveID
sourceTeamDrive = config.SourceTeamDrive
filePattern = config.FilePattern
outputPattern = config.OutputPattern
destinationType = config.DestinationType
destinationPath = config.DestinationPath
destHost = config.DestHost
destPort = config.DestPort
destUser = config.DestUser
destPassword = config.DestPassword
destKeyFile = config.DestKeyFile
// S3 fields
destBucket = config.DestBucket
destRegion = config.DestRegion
destAccessKey = config.DestAccessKey
destSecretKey = config.DestSecretKey
destEndpoint = config.DestEndpoint
// SMB fields
destShare = config.DestShare
destDomain = config.DestDomain
// FTP fields
destPassiveMode = config.DestPassiveMode
// OneDrive and Google Drive fields
destClientId = config.DestClientID
destClientSecret = config.DestClientSecret
destDriveId = config.DestDriveID
destTeamDrive = config.DestTeamDrive
archivePath = config.ArchivePath
archiveEnabled = config.ArchiveEnabled
deleteAfterTransfer = config.DeleteAfterTransfer
rcloneFlags = config.RcloneFlags
}
return fmt.Sprintf(`{
name: '%s',
sourceType: '%s',
sourcePath: '%s',
sourceHost: '%s',
sourcePort: %d,
sourceUser: '%s',
sourcePassword: '%s',
sourceKeyFile: '%s',
sourceBucket: '%s',
sourceRegion: '%s',
sourceAccessKey: '%s',
sourceSecretKey: '%s',
sourceEndpoint: '%s',
sourceShare: '%s',
sourceDomain: '%s',
sourcePassiveMode: %v,
sourceClientId: '%s',
sourceClientSecret: '%s',
sourceDriveId: '%s',
sourceTeamDrive: '%s',
filePattern: '%s',
outputPattern: '%s',
destinationType: '%s',
destinationPath: '%s',
destHost: '%s',
destPort: %d,
destUser: '%s',
destPassword: '%s',
destKeyFile: '%s',
// S3 fields
destBucket: '%s',
destRegion: '%s',
destAccessKey: '%s',
destSecretKey: '%s',
destEndpoint: '%s',
// SMB fields
destShare: '%s',
destDomain: '%s',
// FTP fields
destPassiveMode: %v,
// OneDrive and Google Drive fields
destClientId: '%s',
destClientSecret: '%s',
destDriveId: '%s',
destTeamDrive: '%s',
// Existing fields
archivePath: '%s',
archiveEnabled: %v,
deleteAfterTransfer: %v,
rcloneFlags: '%s',
loading: false,
validate() {
if (this.sourceType === 'sftp') {
if (!this.sourceHost || !this.sourceUser || (!this.sourcePassword && !this.sourceKeyFile)) {
return false;
}
} else if (this.sourceType === 's3') {
if (!this.sourceBucket || !this.sourceRegion || !this.sourceAccessKey || !this.sourceSecretKey) {
return false;
}
} else if (this.sourceType === 'minio') {
if (!this.sourceBucket || !this.sourceEndpoint || !this.sourceAccessKey || !this.sourceSecretKey) {
return false;
}
} else if (this.sourceType === 'b2') {
if (!this.sourceBucket || !this.sourceAccessKey || !this.sourceSecretKey) {
return false;
}
} else if (this.sourceType === 'smb') {
if (!this.sourceHost || !this.sourceShare || !this.sourceUser || !this.sourcePassword) {
return false;
}
} else if (this.sourceType === 'ftp') {
if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) {
return false;
}
} else if (this.sourceType === 'webdav') {
if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) {
return false;
}
} else if (this.sourceType === 'nextcloud') {
if (!this.sourceHost || !this.sourceUser || !this.sourcePassword) {
return false;
}
} else if (this.sourceType === 'onedrive') {
if (!this.sourceClientId || !this.sourceClientSecret) {
return false;
}
} else if (this.sourceType === 'google_drive') {
if (!this.sourceClientId || !this.sourceClientSecret) {
return false;
}
}
if (this.destinationType === 'sftp') {
if (!this.destHost || !this.destUser || (!this.destPassword && !this.destKeyFile)) {
return false;
}
} else if (this.destinationType === 's3') {
if (!this.destBucket || !this.destRegion || !this.destAccessKey || !this.destSecretKey) {
return false;
}
} else if (this.destinationType === 'minio') {
if (!this.destBucket || !this.destEndpoint || !this.destAccessKey || !this.destSecretKey) {
return false;
}
} else if (this.destinationType === 'b2') {
if (!this.destBucket || !this.destAccessKey || !this.destSecretKey) {
return false;
}
} else if (this.destinationType === 'smb') {
if (!this.destHost || !this.destShare || !this.destUser || !this.destPassword) {
return false;
}
} else if (this.destinationType === 'ftp') {
if (!this.destHost || !this.destUser || !this.destPassword) {
return false;
}
} else if (this.destinationType === 'webdav') {
if (!this.destHost || !this.destUser || !this.destPassword) {
return false;
}
} else if (this.destinationType === 'nextcloud') {
if (!this.destHost || !this.destUser || !this.destPassword) {
return false;
}
} else if (this.destinationType === 'onedrive') {
if (!this.destClientId || !this.destClientSecret) {
return false;
}
} else if (this.destinationType === 'google_drive') {
if (!this.destClientId || !this.destClientSecret) {
return false;
}
}
return this.name && this.sourcePath && this.filePattern && this.destinationPath && (!this.archiveEnabled || this.archivePath);
}
}`, name, sourceType, sourcePath, sourceHost, sourcePort, sourceUser, sourcePassword, sourceKeyFile,
sourceBucket, sourceRegion, sourceAccessKey, sourceSecretKey, sourceEndpoint,
sourceShare, sourceDomain, sourcePassiveMode,
sourceClientId, sourceClientSecret, sourceDriveId, sourceTeamDrive,
filePattern, outputPattern, destinationType, destinationPath, destHost, destPort, destUser, destPassword, destKeyFile,
destBucket, destRegion, destAccessKey, destSecretKey, destEndpoint,
destShare, destDomain, destPassiveMode,
destClientId, destClientSecret, destDriveId, destTeamDrive,
archivePath, archiveEnabled, deleteAfterTransfer, rcloneFlags)
}
templ ConfigForm(ctx context.Context, data ConfigFormData) {
@LayoutWithContext(getConfigFormTitle(data.IsNew), ctx) {
<div class="min-h-[calc(100vh-4rem)] flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 bg-secondary-50 dark:bg-secondary-900">
<div class="max-w-4xl w-full">
<div class="card overflow-hidden shadow-lg">
<div class="p-8">
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-20 h-20 rounded-full bg-primary-100 dark:bg-primary-900 mb-4">
<i class="fas fa-cog text-primary-600 dark:text-primary-400 text-3xl"></i>
</div>
<h2 class="text-3xl font-bold text-secondary-900 dark:text-secondary-100">
if data.IsNew {
Create New Configuration
} else {
Edit Configuration: { data.Config.Name }
}
</h2>
<p class="mt-2 text-secondary-600 dark:text-secondary-400">Set up your file transfer configuration</p>
</div>
<form
class="space-y-8 divide-y divide-gray-200"
if data.IsNew {
hx-post="/configs"
} else {
hx-post={ fmt.Sprintf("/configs/%d", data.Config.ID) }
}
hx-target="body"
hx-boost="true"
x-data={ getInitialData(data.Config) }
@htmx:before-request="loading = true"
@htmx:after-request="loading = false">
<div class="space-y-8 divide-y divide-gray-200">
<div class="pt-4">
<div class="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
<div class="sm:col-span-4">
<label for="name" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Name</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-tag text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="name"
id="name"
x-model="name"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-3">
<label for="source_type" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Source Type</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-server text-secondary-400 dark:text-secondary-600"></i>
</div>
<select
id="source_type"
name="source_type"
x-model="sourceType"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500">
<option value="local">Local</option>
<option value="sftp">SFTP</option>
<option value="s3">S3</option>
<option value="minio">MinIO</option>
<option value="b2">Backblaze B2</option>
<option value="smb">SMB</option>
<option value="ftp">FTP</option>
<option value="webdav">WebDAV</option>
<option value="nextcloud">NextCloud</option>
//<option value="onedrive">OneDrive</option>
//<option value="google_drive">Google Drive</option>
</select>
</div>
</div>
<template x-if="sourceType === 'sftp'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_host"
id="source_host"
x-model="sourceHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="sftp.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="source_port" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Port</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-plug text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="number"
name="source_port"
id="source_port"
x-model="sourcePort"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="22"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_user"
id="source_user"
x-model="sourceUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="source_password"
id="source_password"
x-model="sourcePassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="source_password" :value="sourcePassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
<div class="sm:col-span-6">
<label for="source_key_file" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Key File Path</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-file-alt text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_key_file"
id="source_key_file"
x-model="sourceKeyFile"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="/path/to/id_rsa"/>
</div>
</div>
</div>
</template>
<template x-if="sourceType === 's3'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_bucket"
id="source_bucket"
x-model="sourceBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="source_region" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Region</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_region"
id="source_region"
x-model="sourceRegion"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="us-east-1"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_access_key"
id="source_access_key"
x-model="sourceAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_secret_key"
id="source_secret_key"
x-model="sourceSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-6">
<label for="source_endpoint" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Endpoint</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_endpoint"
id="source_endpoint"
x-model="sourceEndpoint"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://s3.amazonaws.com"/>
</div>
</div>
</div>
</template>
<template x-if="sourceType === 'minio'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_bucket"
id="source_bucket"
x-model="sourceBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="source_endpoint" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Endpoint</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_endpoint"
id="source_endpoint"
x-model="sourceEndpoint"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://s3.amazonaws.com"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_access_key"
id="source_access_key"
x-model="sourceAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_secret_key"
id="source_secret_key"
x-model="sourceSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
</div>
</template>
<template x-if="sourceType === 'b2'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_bucket"
id="source_bucket"
x-model="sourceBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_access_key"
id="source_access_key"
x-model="sourceAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_secret_key"
id="source_secret_key"
x-model="sourceSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
</div>
</template>
<template x-if="sourceType === 'smb'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_host"
id="source_host"
x-model="sourceHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="smb.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="source_share" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Share</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-folder text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_share"
id="source_share"
x-model="sourceShare"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="share"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_domain" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Domain</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_domain"
id="source_domain"
x-model="sourceDomain"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="domain"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_user"
id="source_user"
x-model="sourceUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="source_password"
id="source_password"
x-model="sourcePassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="source_password" :value="sourcePassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
</div>
</template>
<template x-if="sourceType === 'ftp'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_host"
id="source_host"
x-model="sourceHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="ftp.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="source_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_user"
id="source_user"
x-model="sourceUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="source_password"
id="source_password"
x-model="sourcePassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="source_password" :value="sourcePassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
</div>
</template>
<template x-if="sourceType === 'webdav'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">WebDAV URL</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_host"
id="source_host"
x-model="sourceHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://webdav.example.com/remote.php/webdav/"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_user"
id="source_user"
x-model="sourceUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="source_password"
id="source_password"
x-model="sourcePassword"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="source_password" :value="sourcePassword"/>
</div>
</div>
</template>
<template x-if="sourceType === 'nextcloud'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="source_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">NextCloud URL</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_host"
id="source_host"
x-model="sourceHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://nextcloud.example.com"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_user"
id="source_user"
x-model="sourceUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="source_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password or App Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="source_password"
id="source_password"
x-model="sourcePassword"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="source_password" :value="sourcePassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Using an app password is recommended for security</p>
</div>
</div>
</template>
// <template x-if="sourceType === 'onedrive'">
// <div class="sm:col-span-6 space-y-6">
// <div class="relative p-4 border border-yellow-300 bg-yellow-50 dark:bg-yellow-900/30 dark:border-yellow-700 rounded-lg mb-4">
// <div class="flex">
// <div class="flex-shrink-0">
// <i class="fas fa-info-circle text-yellow-400"></i>
// </div>
// <div class="ml-3">
// <h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-300">OneDrive Authentication</h3>
// <div class="mt-2 text-sm text-yellow-700 dark:text-yellow-400">
// <p>OneDrive requires OAuth authentication. You'll need to:</p>
// <ol class="list-decimal ml-4 mt-1 space-y-1">
// <li>Register an application in the Microsoft Azure portal</li>
// <li>Add redirect URI: http://localhost:53682/</li>
// <li>Save the application details below</li>
// </ol>
// </div>
// </div>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="source_client_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client ID</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-id-card text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="source_client_id"
// id="source_client_id"
// x-model="sourceClientId"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Azure application client ID"/>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="source_client_secret" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client Secret</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="password"
// name="source_client_secret"
// id="source_client_secret"
// x-model="sourceClientSecret"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Azure application client secret"/>
// </div>
// <input type="hidden" name="source_client_secret" :value="sourceClientSecret"/>
// </div>
// <div class="sm:col-span-4">
// <label for="source_drive_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Drive ID (Optional)</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-hdd text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="source_drive_id"
// id="source_drive_id"
// x-model="sourceDriveId"
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="OneDrive drive ID (leave empty for default)"/>
// </div>
// <p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">For shared or business drives</p>
// </div>
// </div>
// </template>
// <template x-if="sourceType === 'google_drive'">
// <div class="sm:col-span-6 space-y-6">
// <div class="relative p-4 border border-yellow-300 bg-yellow-50 dark:bg-yellow-900/30 dark:border-yellow-700 rounded-lg mb-4">
// <div class="flex">
// <div class="flex-shrink-0">
// <i class="fas fa-info-circle text-yellow-400"></i>
// </div>
// <div class="ml-3">
// <h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-300">Google Drive Authentication</h3>
// <div class="mt-2 text-sm text-yellow-700 dark:text-yellow-400">
// <p>Google Drive requires OAuth authentication. You'll need to:</p>
// <ol class="list-decimal ml-4 mt-1 space-y-1">
// <li>Create a project in Google Cloud Console</li>
// <li>Enable Google Drive API</li>
// <li>Create OAuth credentials</li>
// <li>Add redirect URI: http://localhost:53682/</li>
// <li>Save the client details below</li>
// </ol>
// </div>
// </div>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="source_client_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client ID</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-id-card text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="source_client_id"
// id="source_client_id"
// x-model="sourceClientId"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Google OAuth client ID"/>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="source_client_secret" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client Secret</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="password"
// name="source_client_secret"
// id="source_client_secret"
// x-model="sourceClientSecret"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Google OAuth client secret"/>
// </div>
// <input type="hidden" name="source_client_secret" :value="sourceClientSecret"/>
// </div>
// <div class="sm:col-span-4">
// <label for="source_team_drive" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Team Drive ID (Optional)</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-users text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="source_team_drive"
// id="source_team_drive"
// x-model="sourceTeamDrive"
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Team Drive ID (leave empty for personal drive)"/>
// </div>
// </div>
// </div>
// </template>
<div class="sm:col-span-6">
<label for="source_path" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Source Path</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-folder text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="source_path"
id="source_path"
x-model="sourcePath"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
:placeholder="sourceType === 'sftp' ? '/remote/path' : '/local/path'"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="file_pattern" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">File Pattern</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-file-code text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="file_pattern"
id="file_pattern"
x-model="filePattern"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="*.txt"/>
</div>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Pattern to match files for transfer (e.g., *.txt, *.csv)</p>
</div>
<div class="sm:col-span-4">
<label for="output_pattern" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Output Filename Pattern</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-file-export text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="output_pattern"
id="output_pattern"
x-model="outputPattern"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="filename_2006-01-02.ext"/>
</div>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">
Pattern for output filenames. Available variables:
<br/>
<code>{`${filename}`}</code> - Original filename without extension (e.g., "report")
<br/>
<code>{`${ext}`}</code> - Original file extension (e.g., ".csv")
<br/>
<code>{`${date:format}`}</code> - Current date using Go's time format:
<br/>
<span class="ml-4">2006-01-02 YYYY-MM-DD</span>
<br/>
<span class="ml-4">20060102 YYYYMMDD</span>
<br/>
<span class="ml-4">2006-01-02_15:04:05 YYYY-MM-DD_HH:MM:SS</span>
<br/>
<span class="ml-4">Example: <code>{`${filename}_[date:2006-01-02]_${ext}`}</code> "report_2025-03-01.csv"</span>
</p>
</div>
<div class="sm:col-span-3">
<label for="destination_type" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Destination Type</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-server text-secondary-400 dark:text-secondary-600"></i>
</div>
<select
id="destination_type"
name="destination_type"
x-model="destinationType"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500">
<option value="local">Local</option>
<option value="sftp">SFTP</option>
<option value="s3">S3</option>
<option value="minio">MinIO</option>
<option value="b2">Backblaze B2</option>
<option value="smb">SMB</option>
<option value="ftp">FTP</option>
<option value="webdav">WebDAV</option>
<option value="nextcloud">NextCloud</option>
// <option value="onedrive">OneDrive</option>
// <option value="google_drive">Google Drive</option>
</select>
</div>
</div>
<template x-if="destinationType === 'sftp'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_host"
id="dest_host"
x-model="destHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="sftp.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="dest_port" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Port</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-plug text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="number"
name="dest_port"
id="dest_port"
x-model="destPort"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="22"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_user"
id="dest_user"
x-model="destUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="dest_password"
id="dest_password"
x-model="destPassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="dest_password" :value="destPassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
<div class="sm:col-span-6">
<label for="dest_key_file" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Key File Path</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-file-alt text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_key_file"
id="dest_key_file"
x-model="destKeyFile"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="/path/to/id_rsa"/>
</div>
</div>
</div>
</template>
<template x-if="destinationType === 's3'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_bucket"
id="dest_bucket"
x-model="destBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="dest_region" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Region</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_region"
id="dest_region"
x-model="destRegion"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="us-east-1"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_access_key"
id="dest_access_key"
x-model="destAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_secret_key"
id="dest_secret_key"
x-model="destSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-6">
<label for="dest_endpoint" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Endpoint</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_endpoint"
id="dest_endpoint"
x-model="destEndpoint"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://s3.amazonaws.com"/>
</div>
</div>
</div>
</template>
<template x-if="destinationType === 'minio'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_bucket"
id="dest_bucket"
x-model="destBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="dest_endpoint" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Endpoint</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_endpoint"
id="dest_endpoint"
x-model="destEndpoint"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://s3.amazonaws.com"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_access_key"
id="dest_access_key"
x-model="destAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_secret_key"
id="dest_secret_key"
x-model="destSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
</div>
</template>
<template x-if="destinationType === 'b2'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_bucket" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Bucket</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_bucket"
id="dest_bucket"
x-model="destBucket"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="my-bucket"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_access_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Access Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_access_key"
id="dest_access_key"
x-model="destAccessKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_secret_key" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Secret Key</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_secret_key"
id="dest_secret_key"
x-model="destSecretKey"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
</div>
</template>
<template x-if="destinationType === 'smb'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_host"
id="dest_host"
x-model="destHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="smb.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="dest_share" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Share</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-folder text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_share"
id="dest_share"
x-model="destShare"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="share"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_domain" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Domain</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_domain"
id="dest_domain"
x-model="destDomain"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="domain"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_user"
id="dest_user"
x-model="destUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="dest_password"
id="dest_password"
x-model="destPassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="dest_password" :value="destPassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
</div>
</template>
<template x-if="destinationType === 'ftp'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Host</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_host"
id="dest_host"
x-model="destHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="ftp.example.com"/>
</div>
</div>
<div class="sm:col-span-2">
<label for="dest_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_user"
id="dest_user"
x-model="destUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="dest_password"
id="dest_password"
x-model="destPassword"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="dest_password" :value="destPassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Either password or key file is required</p>
</div>
</div>
</template>
<template x-if="destinationType === 'webdav'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">WebDAV URL</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-globe text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_host"
id="dest_host"
x-model="destHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://webdav.example.com/remote.php/webdav/"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_user"
id="dest_user"
x-model="destUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="dest_password"
id="dest_password"
x-model="destPassword"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="dest_password" :value="destPassword"/>
</div>
</div>
</template>
<template x-if="destinationType === 'nextcloud'">
<div class="sm:col-span-6 space-y-6">
<div class="sm:col-span-4">
<label for="dest_host" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">NextCloud URL</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-cloud text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_host"
id="dest_host"
x-model="destHost"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="https://nextcloud.example.com"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_user" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Username</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-user text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="dest_user"
id="dest_user"
x-model="destUser"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"/>
</div>
</div>
<div class="sm:col-span-4">
<label for="dest_password" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Password or App Password</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="password"
name="dest_password"
id="dest_password"
x-model="destPassword"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="Password"/>
</div>
<input type="hidden" name="dest_password" :value="destPassword"/>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">Using an app password is recommended for security</p>
</div>
</div>
</template>
// <template x-if="destinationType === 'onedrive'">
// <div class="sm:col-span-6 space-y-6">
// <div class="relative p-4 border border-yellow-300 bg-yellow-50 dark:bg-yellow-900/30 dark:border-yellow-700 rounded-lg mb-4">
// <div class="flex">
// <div class="flex-shrink-0">
// <i class="fas fa-info-circle text-yellow-400"></i>
// </div>
// <div class="ml-3">
// <h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-300">OneDrive Authentication</h3>
// <div class="mt-2 text-sm text-yellow-700 dark:text-yellow-400">
// <p>OneDrive requires OAuth authentication. You'll need to:</p>
// <ol class="list-decimal ml-4 mt-1 space-y-1">
// <li>Register an application in the Microsoft Azure portal</li>
// <li>Add redirect URI: http://localhost:53682/</li>
// <li>Save the application details below</li>
// </ol>
// </div>
// </div>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_client_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client ID</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-id-card text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="dest_client_id"
// id="dest_client_id"
// x-model="destClientId"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Azure application client ID"/>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_client_secret" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client Secret</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="password"
// name="dest_client_secret"
// id="dest_client_secret"
// x-model="destClientSecret"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Azure application client secret"/>
// </div>
// <input type="hidden" name="dest_client_secret" :value="destClientSecret"/>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_drive_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Drive ID (Optional)</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-hdd text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="dest_drive_id"
// id="dest_drive_id"
// x-model="destDriveId"
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="OneDrive drive ID (leave empty for default)"/>
// </div>
// <p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">For shared or business drives</p>
// </div>
// </div>
// </template>
// <template x-if="destinationType === 'google_drive'">
// <div class="sm:col-span-6 space-y-6">
// <div class="relative p-4 border border-yellow-300 bg-yellow-50 dark:bg-yellow-900/30 dark:border-yellow-700 rounded-lg mb-4">
// <div class="flex">
// <div class="flex-shrink-0">
// <i class="fas fa-info-circle text-yellow-400"></i>
// </div>
// <div class="ml-3">
// <h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-300">Google Drive Authentication</h3>
// <div class="mt-2 text-sm text-yellow-700 dark:text-yellow-400">
// <p>Google Drive requires OAuth authentication. You'll need to:</p>
// <ol class="list-decimal ml-4 mt-1 space-y-1">
// <li>Create a project in Google Cloud Console</li>
// <li>Enable Google Drive API</li>
// <li>Create OAuth credentials</li>
// <li>Add redirect URI: http://localhost:53682/</li>
// <li>Save the client details below</li>
// </ol>
// </div>
// </div>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_client_id" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client ID</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-id-card text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="dest_client_id"
// id="dest_client_id"
// x-model="destClientId"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Google OAuth client ID"/>
// </div>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_client_secret" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Client Secret</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-key text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="password"
// name="dest_client_secret"
// id="dest_client_secret"
// x-model="destClientSecret"
// required
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Google OAuth client secret"/>
// </div>
// <input type="hidden" name="dest_client_secret" :value="destClientSecret"/>
// </div>
// <div class="sm:col-span-4">
// <label for="dest_team_drive" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Team Drive ID (Optional)</label>
// <div class="relative">
// <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
// <i class="fas fa-users text-secondary-400 dark:text-secondary-600"></i>
// </div>
// <input
// type="text"
// name="dest_team_drive"
// id="dest_team_drive"
// x-model="destTeamDrive"
// class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
// placeholder="Team Drive ID (leave empty for personal drive)"/>
// </div>
// </div>
// </div>
// </template>
<div class="sm:col-span-6">
<label for="destination_path" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Destination Path</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-folder-open text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="destination_path"
id="destination_path"
x-model="destinationPath"
required
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
:placeholder="destinationType === 'sftp' ? '/remote/path' : '/local/path'"/>
</div>
</div>
<div class="sm:col-span-6">
<div class="flex items-center">
<input
type="checkbox"
id="archive_enabled"
x-model="archiveEnabled"
class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-secondary-300 dark:border-secondary-700 rounded"/>
<input type="hidden" name="archive_enabled" :value="archiveEnabled.toString()"/>
<label for="archive_enabled" class="ml-2 block text-sm text-secondary-700 dark:text-secondary-300">
Archive files after transfer
</label>
</div>
<div class="mt-4" x-show="archiveEnabled">
<label for="archive_path" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Archive Path</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-archive text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="archive_path"
id="archive_path"
x-model="archivePath"
:required="archiveEnabled"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="/path/to/archive"/>
</div>
</div>
</div>
<div class="sm:col-span-6 mt-4">
<div class="flex items-center">
<input
type="checkbox"
id="delete_after_transfer"
x-model="deleteAfterTransfer"
class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-secondary-300 dark:border-secondary-700 rounded"/>
<input type="hidden" name="delete_after_transfer" :value="deleteAfterTransfer.toString()"/>
<label for="delete_after_transfer" class="ml-2 block text-sm text-secondary-700 dark:text-secondary-300">
Delete files from source after transfer
</label>
</div>
<p class="mt-2 text-sm text-secondary-500 dark:text-secondary-400">
<i class="fas fa-exclamation-triangle text-yellow-500 mr-1"></i>
Original files will be permanently deleted from source after successful transfer
<span x-show="archiveEnabled">and archiving</span>
</p>
</div>
<div class="sm:col-span-6">
<label for="rclone_flags" class="block text-sm font-medium text-secondary-700 dark:text-secondary-300 mb-1">Rclone Flags</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-flag text-secondary-400 dark:text-secondary-600"></i>
</div>
<input
type="text"
name="rclone_flags"
id="rclone_flags"
x-model="rcloneFlags"
class="form-input pl-10 w-full rounded-lg border-secondary-300 dark:border-secondary-700 dark:bg-secondary-800 dark:text-secondary-100 focus:ring-primary-500 focus:border-primary-500"
placeholder="--transfers 4 --checkers 8"/>
</div>
</div>
</div>
</div>
</div>
<div class="pt-6">
<div class="flex justify-end">
<a href="/configs" class="btn-secondary mr-4 px-6 py-3 rounded-lg flex items-center">
<i class="fas fa-times mr-2"></i>
Cancel
</a>
<button
type="submit"
class="btn-primary px-6 py-3 rounded-lg flex items-center"
x-bind:disabled="!validate() || loading">
<span x-show="!loading" class="flex items-center">
<i class="fas fa-save mr-2"></i>
if data.IsNew {
Create Configuration
} else {
Save Changes
}
</span>
<span x-show="loading" class="flex items-center">
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Processing...
</span>
</button>
</div>
</div>
</form>
</div>
<div class="px-8 py-4 bg-secondary-50 dark:bg-secondary-800 border-t border-secondary-200 dark:border-secondary-700 text-center">
<p class="text-sm text-secondary-600 dark:text-secondary-400">
<i class="fas fa-info-circle mr-1"></i>
Configure your file transfer settings carefully for optimal performance
</p>
</div>
</div>
</div>
</div>
}
}