Skip to content
Open
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
.externalNativeBuild
.cxx
local.properties
/.idea/misc.xml
1 change: 1 addition & 0 deletions .idea/gradle.xml

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

17 changes: 17 additions & 0 deletions .idea/misc.xml

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

6 changes: 6 additions & 0 deletions .idea/vcs.xml

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

14 changes: 14 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ plugins {
android {
compileSdk 32

buildFeatures{
viewBinding = true
}

defaultConfig {
applicationId "com.sudo.androidd20"
minSdk 23
Expand All @@ -29,6 +33,9 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}

dependencies {
Expand All @@ -37,7 +44,14 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.annotation:annotation:1.2.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

def fragment_version = "1.5.0"
implementation "androidx.fragment:fragment:$fragment_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K nhất thiết phải dùng thư viện này

}
7 changes: 7 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".ContentActivity"
android:exported="true">
</activity>

</application>


</manifest>
27 changes: 27 additions & 0 deletions app/src/main/java/com/sudo/androidd20/ContentActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.sudo.androidd20

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class ContentActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.content_activity)
val tv_user = findViewById(R.id.tv_lineUser) as TextView
val tv_pass = findViewById(R.id.tv_linepassword) as TextView
val btn_logout = findViewById(R.id.btn_logout) as Button

tv_user.text = intent?.getStringExtra("user").toString()
tv_pass.text = intent?.getStringExtra("password").toString()
btn_logout.setOnClickListener{
val intent = Intent(this,MainActivity::class.java)
startActivity(intent)
}
}


}
76 changes: 76 additions & 0 deletions app/src/main/java/com/sudo/androidd20/LogInFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.sudo.androidd20

import android.content.Intent
import android.graphics.Paint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.sudo.androidd20.databinding.FragmentLoginBinding

class LogInFragment : Fragment() {

private var _binding: FragmentLoginBinding? = null
private val binding get() = _binding!!
var accounts:ArrayList<User> = arrayListOf()

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nên dùng mutable list của kotlin nhé

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
) : View? {
_binding = FragmentLoginBinding.inflate(inflater,container,false)
binding.tvSignup.paintFlags = Paint.UNDERLINE_TEXT_FLAG

//getting data
arguments?.let {
accounts = it.getSerializable("acc") as ArrayList<User>
}
binding.btnLogin.setOnClickListener{
val email = binding.etUsername.text.toString()
val password = binding.etPassword.text.toString()
if(!isEmailValid(email)) Toast.makeText(
context,
"You didn't enter email in the right way!",
Toast.LENGTH_LONG
).show()
else if(email.isEmpty()) Toast.makeText(
context,
"Email must not be empty!! Try again",
Toast.LENGTH_LONG
).show()
else if(password.isEmpty()) Toast.makeText(
context,
"Password must not be empty!! Try again",
Toast.LENGTH_LONG
).show()

val login_user = User(email,password)
if(accounts.contains(login_user)){
val intent = Intent(context,ContentActivity::class.java)

intent.putExtra("user",login_user.email.toString())
intent.putExtra("password",login_user.password.toString())
startActivity(intent)
} else{
Toast.makeText(context,"Wrong password or email", Toast.LENGTH_LONG).show()
}
}

binding.tvSignup.setOnClickListener {
val FragmentSignUP = SignUpFragment()
val transaction = requireActivity().supportFragmentManager.beginTransaction()
transaction.apply {
replace(R.id.fragment_menu,FragmentSignUP)
commit()
}
}

return binding.root
}

private fun isEmailValid(email: String):Boolean{
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
7 changes: 7 additions & 0 deletions app/src/main/java/com/sudo/androidd20/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

val logInFragment = LogInFragment()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction().apply {
replace(R.id.fragment_menu,logInFragment)
commit()
}
}
}
82 changes: 82 additions & 0 deletions app/src/main/java/com/sudo/androidd20/SignUpFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.sudo.androidd20

import android.graphics.Paint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.sudo.androidd20.databinding.FragmentLoginBinding
import com.sudo.androidd20.databinding.FragmentSignUpBinding

class SignUpFragment : Fragment(R.layout.fragment_sign_up) {

private var _binding: FragmentSignUpBinding? = null
private val binding get() = _binding!!
var accounts:ArrayList<User> = arrayListOf()

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
) : View? {
_binding = FragmentSignUpBinding.inflate(inflater, container, false)
binding.tvLogIn.paintFlags = Paint.UNDERLINE_TEXT_FLAG

binding.btnSignUp.setOnClickListener{
val email = binding.etUsername.text.toString()
val password = binding.etPassword.text.toString()
val confirm_password = binding.etConfirmPassword.text.toString()
if(!isEmailValid(email)) Toast.makeText(
context,
"You didn't enter email in the right way!",
Toast.LENGTH_LONG
).show()
else if(email.isEmpty()) Toast.makeText(
context,
"Email must not be empty!! Try again",
Toast.LENGTH_LONG
).show()
else if(password.isEmpty()) Toast.makeText(
context,
"Password must not be empty!! Try again",
Toast.LENGTH_LONG
).show()
else if(confirm_password.isEmpty()) Toast.makeText(
context,
"Confirm password must not be empty!! Try again",
Toast.LENGTH_LONG
)
else if(confirm_password != password) Toast.makeText(
context,
"Confirm password is not correct!",
Toast.LENGTH_LONG
).show()
else{
accounts.add(User(email,password))
Toast.makeText(context,"Successfull",Toast.LENGTH_SHORT).show()
}
}

binding.tvLogIn.setOnClickListener {
val FragmentLogin = LogInFragment()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xem lại cách đặt tên biến


val bundle = Bundle()
FragmentLogin.arguments = bundle
bundle.putSerializable("acc",accounts)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

em tạo hẳn 1 mảng để push 1 phần tử rồi chuyển nguyên nó sang màn login à?


val transaction = requireActivity().supportFragmentManager.beginTransaction()
transaction.apply {
replace(R.id.fragment_menu,FragmentLogin)
commit()
}
}


return binding.root
}

fun isEmailValid(email:String) : Boolean{
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
}
}
5 changes: 5 additions & 0 deletions app/src/main/java/com/sudo/androidd20/User.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sudo.androidd20

import java.io.Serializable

data class User(val email:String?,val password:String?) : Serializable
24 changes: 24 additions & 0 deletions app/src/main/java/com/sudo/androidd20/data/LoginDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.sudo.androidd20.data
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


import com.sudo.androidd20.data.model.LoggedInUser
import java.io.IOException

/**
* Class that handles authentication w/ login credentials and retrieves user information.
*/
class LoginDataSource {

fun login(username: String, password: String): Result<LoggedInUser> {
try {
// TODO: handle loggedInUser authentication
val fakeUser = LoggedInUser(java.util.UUID.randomUUID().toString(), "Jane Doe")
return Result.Success(fakeUser)
} catch (e: Throwable) {
return Result.Error(IOException("Error logging in", e))
}
}

fun logout() {
// TODO: revoke authentication
}
}
46 changes: 46 additions & 0 deletions app/src/main/java/com/sudo/androidd20/data/LoginRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.sudo.androidd20.data

import com.sudo.androidd20.data.model.LoggedInUser

/**
* Class that requests authentication and user information from the remote data source and
* maintains an in-memory cache of login status and user credentials information.
*/

class LoginRepository(val dataSource: LoginDataSource) {

// in-memory cache of the loggedInUser object
var user: LoggedInUser? = null
private set

val isLoggedIn: Boolean
get() = user != null

init {
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
user = null
}

fun logout() {
user = null
dataSource.logout()
}

fun login(username: String, password: String): Result<LoggedInUser> {
// handle login
val result = dataSource.login(username, password)

if (result is Result.Success) {
setLoggedInUser(result.data)
}

return result
}

private fun setLoggedInUser(loggedInUser: LoggedInUser) {
this.user = loggedInUser
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Loading